A directory seamlessly working on a stack of multiple directories.
Directories can be mounted using the mount() method.
When looking for a file or directory in a StackDir, the last directory is searched first, then the second last, and so on. This means that directories mounted later override those mounted before.
Mount a directory.
Get the name of this directory.
Get full path of this directory in the VFS.
Is it possible to write to the directory?
Does the directory exist?
Get file with specified _path in the directory.
Get a subdirectory with specified _path in the directory.
Get a range of files in the directory.
Get a range of subdirectories.
Create the directory if it does not exist (otherwise do nothing).
Remove the directory if it exists (otherwise do nothing).
Construct a range from a set of directories.
Construct a range from a set of _files.
Compose path for a _child directory. Used e.g. to allow StackDir to set children's paths.
Implementation of create(). Caller contract guarantees that the directory is writable.
Return a copy of this VFSDir without a parent. Used for mounting.
Access for derived classes to call copyWithoutParent() of other instances.
We have a directory called data with the following contents:
1 shaders: 2 font.frag 3 font.vert 4 logs: 5 (empty) 6 main.cfg
and a directory called user_data with the following contents:
1 shaders: 2 font.frag 3 logs: 4 (empty) 5 custom.cfg
the following code will work as specified in the comments:
1 VFSDir data, user_data; //initialized somewhere before 2 3 auto stack = new StackDir("stack"); 4 stack.mount(data); 5 stack.mount(user_data); 6 7 //This will access user_data/shaders/font.frag 8 auto frag = stack.file("shaders/font.frag"); 9 //This will access data/shaders/font.vert 10 auto vert = stack.file("shaders/font.vert"); 11 //This will return a StackDir (as VFSDir) with "data/logs" and "user_data/logs" 12 //mounted, in that order: 13 auto logs = stack.dir("logs");
Accessing a file in a StackDir will actually return a StackFile, which decides which file to access on read, write and other operations. The StackFile is a stack of all files that map to the same path in the StackDir in the same order as StackDir's mounted directories.
For example, when reading or determining file size, the directories in the stack will be searched from newest to oldest and the first file found will be used.
When writing, the file in the newest writable directory will be written to.
In some cases, it might be required to access a particular directory in the stack. E.g. a game might have multiple packages stacked on top of each other, but sometimes default, non-overridden version of a file could be needed. This can be done using the :: separator.
In the context of the previous example:
//This will access data/shaders/font.frag even though user_data/shaders/font.frag exists auto default_frag = stack.file("data::shaders/font.frag");
StackDir is considered writable when any directory in the stack is writable. Similarly, it exists when any directory in the stack exists.