StackDir

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.

Constructors

this
this(string name)

Construct a StackDir.

Members

Functions

composePath
string composePath(VFSDir child)
Undocumented in source. Be warned that the author may not have intended to support it.
copyWithoutParent
VFSDir copyWithoutParent()
Undocumented in source. Be warned that the author may not have intended to support it.
create_
void create_()
Undocumented in source. Be warned that the author may not have intended to support it.
dir
VFSDir dir(string path)
Undocumented in source. Be warned that the author may not have intended to support it.
dirs
VFSDirs dirs(Flag!"deep" deep, string glob)
Undocumented in source. Be warned that the author may not have intended to support it.
file
VFSFile file(string path)
Undocumented in source. Be warned that the author may not have intended to support it.
files
VFSFiles files(Flag!"deep" deep, string glob)
Undocumented in source. Be warned that the author may not have intended to support it.
mount
void mount(VFSDir dir)

Mount a directory.

remove
void remove()
Undocumented in source. Be warned that the author may not have intended to support it.

Properties

exists
bool exists [@property getter]
Undocumented in source. Be warned that the author may not have intended to support it.
writable
bool writable [@property getter]
Undocumented in source. Be warned that the author may not have intended to support it.

Inherited Members

From VFSDir

name
string name [@property getter]

Get the name of this directory.

path
string path [@property getter]

Get full path of this directory in the VFS.

writable
bool writable [@property getter]

Is it possible to write to the directory?

exists
bool exists [@property getter]

Does the directory exist?

file
VFSFile file(string path)

Get file with specified _path in the directory.

dir
VFSDir dir(string path)

Get a subdirectory with specified _path in the directory.

files
VFSFiles files(Flag!"deep" deep, string glob)

Get a range of files in the directory.

dirs
VFSDirs dirs(Flag!"deep" deep, string glob)

Get a range of subdirectories.

create
void create()

Create the directory if it does not exist (otherwise do nothing).

remove
void remove()

Remove the directory if it exists (otherwise do nothing).

dirsRange
VFSDirs dirsRange(VFSDirs.Items dirs)

Construct a range from a set of directories.

filesRange
VFSFiles filesRange(VFSFiles.Items files)

Construct a range from a set of _files.

composePath
string composePath(VFSDir child)

Compose path for a _child directory. Used e.g. to allow StackDir to set children's paths.

create_
void create_()

Implementation of create(). Caller contract guarantees that the directory is writable.

copyWithoutParent
VFSDir copyWithoutParent()

Return a copy of this VFSDir without a parent. Used for mounting.

getCopyWithoutParent
VFSDir getCopyWithoutParent(VFSDir dir)

Access for derived classes to call copyWithoutParent() of other instances.

parent
VFSDir parent [@property getter]
Undocumented in source. Be warned that the author may not have intended to support it.
parent
VFSDir parent [@property setter]
Undocumented in source. Be warned that the author may not have intended to support it.

Examples

We have a directory called data with the following contents:

shaders:
    font.frag 
    font.vert 
logs:
    (empty)
main.cfg

and a directory called user_data with the following contents:

shaders: 
     font.frag
logs:
     (empty)
custom.cfg

the following code will work as specified in the comments:

VFSDir data, user_data; //initialized somewhere before

auto stack = new StackDir("stack");
stack.mount(data);
stack.mount(user_data);

//This will access user_data/shaders/font.frag
auto frag = stack.file("shaders/font.frag");
//This will access data/shaders/font.vert
auto vert = stack.file("shaders/font.vert");
//This will return a StackDir (as VFSDir) with "data/logs" and "user_data/logs"
//mounted, in that order:
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.

When we have a StackDir that does not exist and we create() it, the newest directory that is writable will be created. (This can happen when getting a nonexistent subdirectory of a StackDir.)

Meta