1
0
Fork 0

Nasal library load order

Previously, the Nasal files in fgdata/Nasal/*.nas were loaded in
file-name order.  This created a particular problem file files
beginning with "a" which might want to use props.nas.

This adds support for an ordered list of files to be defined
in the property tree that will be loaded before the rest of the
Nasal files.
This commit is contained in:
Stuart Buchanan 2020-05-25 19:45:40 +01:00
parent 0423524b82
commit d852308dc6
2 changed files with 38 additions and 22 deletions

View file

@ -1079,7 +1079,7 @@ void FGNasalSys::init()
// Now load the various source files in the Nasal directory
simgear::Dir nasalDir(SGPath(globals->get_fg_root(), "Nasal"));
loadScriptDirectory(nasalDir);
loadScriptDirectory(nasalDir, globals->get_props()->getNode("/sim/nasal-load-priority"));
// Add modules in Nasal subdirectories to property tree
simgear::PathList directories = nasalDir.children(simgear::Dir::TYPE_DIR+
@ -1223,17 +1223,33 @@ bool pathSortPredicate(const SGPath& p1, const SGPath& p2)
return p1.file() < p2.file();
}
// Loads all scripts in given directory
void FGNasalSys::loadScriptDirectory(simgear::Dir nasalDir)
// Loads all scripts in given directory, with an optional partial ordering of
// files defined in loadorder.
void FGNasalSys::loadScriptDirectory(simgear::Dir nasalDir, SGPropertyNode* loadorder)
{
simgear::PathList scripts = nasalDir.children(simgear::Dir::TYPE_FILE, ".nas");
if (loadorder != nullptr && loadorder->hasChild("file")) {
// Load any scripts defined in the loadorder in order, removing them from
// the list so they don't get loaded twice.
simgear::PropertyList files = loadorder->getChildren("file");
auto loadAndErase = [ &scripts, &nasalDir, this ] (SGPropertyNode_ptr n) {
SGPath p = SGPath(nasalDir.path(), n->getStringValue());
auto script = std::find(scripts.begin(), scripts.end(), p);
if (script != scripts.end()) {
this->loadModule(p, p.file_base().c_str());
scripts.erase(script);
}
};
std::for_each(files.begin(), files.end(), loadAndErase);
}
// Load any remaining scripts.
// Note: simgear::Dir already reports file entries in a deterministic order,
// so a fixed loading sequence is guaranteed (same for every user)
for (unsigned int i=0; i<scripts.size(); ++i) {
SGPath fullpath(scripts[i]);
SGPath file = fullpath.file();
loadModule(fullpath, file.base().c_str());
}
std::for_each(scripts.begin(), scripts.end(), [this](SGPath p) { this->loadModule(p, p.file_base().c_str()); });
}
// Create module with list of scripts

View file

@ -158,7 +158,7 @@ private:
void loadPropertyScripts();
void loadPropertyScripts(SGPropertyNode* n);
void loadScriptDirectory(simgear::Dir nasalDir);
void loadScriptDirectory(simgear::Dir nasalDir, SGPropertyNode* loadorder);
void addModule(std::string moduleName, simgear::PathList scripts);
static void logError(naContext);
naRef parse(naContext ctx, const char* filename, const char* buf, int len,