Refactors the Virtual file System creation process to improve memory efficiency at scale. This is laying the ground work for a copy-on-write system. Previously, each new VFS instance was a full copy, which won't scale to a large number of NPC's. Especially now that we are loading in entire Lua scripts. - Added VFSManager class which now manages the lifecycle of all VFS instances. - VFSManager creates a single "template" VFS on initilisation. The template holds the shared, read-only directories like '/bin' and their command scripts. - When a new VFS is created (for a client or NPC), it links it's 'bin' directory to the shared template's '/bin' by pointer rather than creating a copy of it. this makes sure the content for *all* common command scripts exists in memory only once, regardless of the number of NPC's we will later generate.
70 lines
2.3 KiB
C++
70 lines
2.3 KiB
C++
#include "vfs_manager.h"
|
|
#include "vfs.h"
|
|
|
|
/* Create a new node. */
|
|
vfs_node* new_node(std::string name, vfs_node_type type, vfs_node* parent) {
|
|
vfs_node* node = new vfs_node();
|
|
node->name = name;
|
|
node->type = type;
|
|
node->parent = parent;
|
|
return node;
|
|
}
|
|
|
|
VFSManager::VFSManager(void) {
|
|
/* Create template VFS that holds shared, read-only directories. */
|
|
_vfs_root = new_node("/", DIR_NODE, nullptr);
|
|
vfs_node* bin = new_node("bin", DIR_NODE, _vfs_root);
|
|
_vfs_root->children["bin"] = bin;
|
|
|
|
/* TODO:
|
|
* Load all scripts from assets/scripts/bin into the bind node.
|
|
* We'll create ls.lua manually for now.
|
|
*/
|
|
vfs_node* ls_script = new_node("ls.lua", FILE_NODE, bin);
|
|
ls_script->content = R"lua(-- /bin/ls.lua - Lists files in a directory.
|
|
local dir = current_dir -- Get directory object from C++.
|
|
local output = ""
|
|
|
|
-- Iterate over the 'children' map exposed from c++.
|
|
for name, node in pairs(dir.children) do
|
|
output = output .. name
|
|
if node.type == 1 then
|
|
output = output .. "/"
|
|
end
|
|
output = output .. " "
|
|
end
|
|
return output
|
|
)lua";
|
|
|
|
bin->children["ls.lua"] = ls_script;
|
|
}
|
|
|
|
VFSManager::~VFSManager(void) {
|
|
/* TODO: Implement recursive deletion of all created VFS nodes.*/
|
|
//delete _vfs_root;
|
|
}
|
|
|
|
vfs_node* VFSManager::create_vfs(const std::string& system_type) {
|
|
vfs_node* root = new_node("/", DIR_NODE, nullptr);
|
|
|
|
/* Create directories for this specific VFS. */
|
|
vfs_node* home = new_node("home", DIR_NODE, root);
|
|
vfs_node* user = new_node("user", DIR_NODE, home);
|
|
home->children["user"] = user;
|
|
vfs_node* readme = new_node("readme.txt", FILE_NODE, user);
|
|
readme->content = "Welcome to your new virtual machine.";
|
|
user->children["readme.txt"] = readme;
|
|
|
|
/* Link to the shared directories from the template. */
|
|
root->children["bin"] = _vfs_root->children["bin"];
|
|
|
|
if(system_type == "npc") {
|
|
vfs_node* npc_file = new_node("npc_system.txt", FILE_NODE, root);
|
|
npc_file->content = "This guy sucks nuts!";
|
|
root->children["npc_system.txt"] = npc_file;
|
|
|
|
}
|
|
|
|
return root;
|
|
}
|