SFML community forums

General => General discussions => Topic started by: keharriso on August 03, 2015, 06:07:31 am

Title: locus - loading data from paths, files, and directories
Post by: keharriso on August 03, 2015, 06:07:31 am
Hey, all.

I just put together a lightweight and cross-platform library (https://github.com/keharriso/locus) to help with a mod/plugin system I'm making. It might be useful to you if you're also making a cross-platform game that needs to load data from a data directory.

It  has three jobs:
1) Find the data directory (XDG_DATA_HOME/APPDATA/Application Support)
2) Manipulate file paths for easy file finding
3) Walk through directory contents

Let me know if you find it useful or would like to see other features.
Title: Re: locus - loading data from paths, files, and directories
Post by: Hapax on August 03, 2015, 09:13:20 pm
It's very....c
 :-\
Title: Re: locus - loading data from paths, files, and directories
Post by: Jesper Juhl on August 04, 2015, 12:03:24 am
I agree. It's very C.
Personally I prefer C++ libraries with type safety and nice abstractions and without manual memory management, so I don't think I'll be using this one...

Also, what advantage does this have over something like PhysFS (http://icculus.org/physfs/)?
Title: Re: locus - loading data from paths, files, and directories
Post by: Mario on August 04, 2015, 10:01:50 am
While I understand the idea behind your library's name, I'd really think about picking something else, considering there are related words, like the German "Lokus", which is an old word for... well... loo. :) No offense, just immediately saw that in my head again reading the name.
Title: Re: locus - loading data from paths, files, and directories
Post by: Tank on August 04, 2015, 10:07:20 am
Same for me, lol.
Title: Re: locus - loading data from paths, files, and directories
Post by: dabbertorres on August 04, 2015, 06:15:04 pm
Yeah, I'm with everyone else, it looks good and useful, but especially something like filesystem access, C++ is quite nice.

Unfortunately (imo), most filesystem libraries are very C. I mean, I understand why, but, eh. Haha.
Kinda left me to just write my own and stop complaining to myself. :P
Title: Re: locus - loading data from paths, files, and directories
Post by: Nexus on August 04, 2015, 09:02:46 pm
Five answers, of which two complain about the name and three about the programming language? ::)

I assume there's a reason why C was chosen; if that code were written in C++, I'd totally agree. And the spread of that word seems to vary even in German language and its variants, as my first association was also location (in a mathematical sense, e.g. points on a curve) -- but I'm not from Germany.

keharriso, could you show a few use cases of your library? I always like to get a quick impression of the tools in action :)

dabbertorres, do you know Boost.Filesystem? Version 3 is very clean C++, and easy to use. One of the few Boost libraries I'm still using.
Title: Re: locus - loading data from paths, files, and directories
Post by: dabbertorres on August 05, 2015, 12:04:09 am
Yeah, I can understand why C was chosen. There are definitely benefits to using C, I won't argue that. I just feel like if you're going to use C, why not just use POSIX dirent (he wraps it anyway)? It has a Windows port (or used to, at least).

It definitely looks to be good and quite useful, if I'm doing a project in C. :)

@Nexus,
Yeah, I've used it in the past. Definitely handy, and done very well. I've found it to be a bit overengineered in some cases though.
Plus, I wanted a few things it didn't have.
And the fact they needed to override std::fstream and such is a minor annoyance.

Mostly nitpicking, but, as I use my own library in my free time and out of enjoyment, it's okay to be picky. Hehe.

I did end up taking a lot of inspiration from Boost.Filesystem though.

It has a leg up on me in locale support though, so I use it when I need it. That's a thing I need more practice with.
Title: Re: locus - loading data from paths, files, and directories
Post by: keharriso on August 05, 2015, 02:42:30 am
Quote
It's very....c

A valid criticism, well taken. I won't debate this choice here, but I understand it's a deal breaker for many. C++ bindings would be trivial, if you're interested in me adding those to the repository.

Quote
What advantage does this have over something like PhysFS?

For one thing, PhysFS doesn't implement the XDG Base Directory Specification, which locus does (with sensible values for Windows and OS X). For another, PhysFS doesn't have recursive directory enumeration. In locus, it is simple to, for instance, recurse over all files (excluding folders) in a directory.

locus_walk("my/dir", fn, NULL, LOCUS_RECURSE | LOCUS_FILE);

Quote
could you show a few use cases of your library?

Let's say you have a game that is cross-platform with distributions for Windows, Linux, and OS X. Where do you keep your global game data? Traditionally, this is kept in Program Files on Windows, which means it's often a simple matter of looking in the current working directory. Unfortunately, on Linux and OS X, program data is kept separate from program executables, so you might want /usr/share, for instance on Linux.

This is where locus_data_dirs() comes in. It'll be a list of traditional places to check for data files depending on what platform the game was compiled for. There is similarly locus_config_dirs() for configuration, although this is perhaps less important. For user-specific data we have locus_data_home() and locus_config_home().

Now let's say you want to run all the Lua scripts inside each active plugin. For this you'd use locus_walk() to walk through the plugin folders (which are inside some subdirectory of locus_data_home()). Putting it all together, we have:

int load_script(const char *path, void *data) {
        return !luaL_dofile((lua_State*) data, path);
}

void load_plugin(const char *plugin_dir, const char *plugin, lua_State *L) {
        char *plugin_path = locus_join(plugin_dir, plugin);
        locus_walk(plugin_path, load_script, L, LOCUS_RECURSE | LOCUS_FILE);
        free(plugin_path);
}

int main() {
        lua_State *L = luaL_newstate();
        const char **plugins = {"vanilla", "cool-mod1", "awesomer-mod2", NULL};
        char *data_home = locus_data_home();
        char *plugin_dir = locus_join(data_home, "MyGame/Plugins");
        const char **plugin;

        for (plugin = plugins; *plugin; ++plugin) {
                load_plugin(plugin_dir, *plugin, L);
        }

        free(data_home);
        free(plugin_dir);
        lua_close(L);

        return 0;
}
 
Title: Re: locus - loading data from paths, files, and directories
Post by: Mario on August 05, 2015, 09:25:43 am
Five answers, of which two complain about the name and three about the programming language? ::)

If you haven't tried the code, don't comment the code. :D