1
0
Fork 0

Nasal: support for module reload via command

This won’t work for all modules, depending on what inter-dependencies
exist.
This commit is contained in:
James Turner 2022-11-06 11:44:09 +00:00
parent 6bb22caea2
commit c509744b0f
3 changed files with 78 additions and 37 deletions

View file

@ -1036,6 +1036,17 @@ do_profiler_stop(const SGPropertyNode *arg, SGPropertyNode *root)
#endif #endif
} }
static bool do_reload_nasal_module(const SGPropertyNode* arg, SGPropertyNode*)
{
auto nasalSys = globals->get_subsystem<FGNasalSys>();
if (!nasalSys) {
SG_LOG(SG_GUI, SG_ALERT, "reloadModuleFromFile command: Nasal subsystem not found");
return false;
}
return nasalSys->reloadModuleFromFile(arg->getStringValue("module"));
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Command setup. // Command setup.
@ -1051,53 +1062,54 @@ do_profiler_stop(const SGPropertyNode *arg, SGPropertyNode *root)
static struct { static struct {
const char * name; const char * name;
SGCommandMgr::command_t command; SGCommandMgr::command_t command;
} built_ins [] = { } built_ins[] = {
{ "null", do_null }, {"null", do_null},
{ "nasal", do_nasal }, {"nasal", do_nasal},
{ "pause", do_pause }, {"nasal-module-reload", do_reload_nasal_module},
{ "load", do_load }, {"pause", do_pause},
{ "save", do_save }, {"load", do_load},
{ "save-tape", do_save_tape }, {"save", do_save},
{ "load-tape", do_load_tape }, {"save-tape", do_save_tape},
{ "view-cycle", do_view_cycle }, {"load-tape", do_load_tape},
{ "view-push", do_view_push }, {"view-cycle", do_view_cycle},
{ "view-clone", do_view_clone }, {"view-push", do_view_push},
{ "view-last-pair", do_view_last_pair }, {"view-clone", do_view_clone},
{ "view-last-pair-double", do_view_last_pair_double }, {"view-last-pair", do_view_last_pair},
{ "view-new", do_view_new }, {"view-last-pair-double", do_view_last_pair_double},
{"view-new", do_view_new},
/* /*
{ "set-sea-level-air-temp-degc", do_set_sea_level_degc }, { "set-sea-level-air-temp-degc", do_set_sea_level_degc },
{ "set-outside-air-temp-degc", do_set_oat_degc }, { "set-outside-air-temp-degc", do_set_oat_degc },
{ "set-dewpoint-sea-level-air-temp-degc", do_set_dewpoint_sea_level_degc }, { "set-dewpoint-sea-level-air-temp-degc", do_set_dewpoint_sea_level_degc },
{ "set-dewpoint-temp-degc", do_set_dewpoint_degc }, { "set-dewpoint-temp-degc", do_set_dewpoint_degc },
*/ */
{ "property-toggle", do_property_toggle }, {"property-toggle", do_property_toggle},
{ "property-assign", do_property_assign }, {"property-assign", do_property_assign},
{ "property-adjust", do_property_adjust }, {"property-adjust", do_property_adjust},
{ "property-multiply", do_property_multiply }, {"property-multiply", do_property_multiply},
{ "property-swap", do_property_swap }, {"property-swap", do_property_swap},
{ "property-scale", do_property_scale }, {"property-scale", do_property_scale},
{ "property-cycle", do_property_cycle }, {"property-cycle", do_property_cycle},
{ "property-randomize", do_property_randomize }, {"property-randomize", do_property_randomize},
{ "property-interpolate", do_property_interpolate }, {"property-interpolate", do_property_interpolate},
{ "data-logging-commit", do_data_logging_commit }, {"data-logging-commit", do_data_logging_commit},
{ "log-level", do_log_level }, {"log-level", do_log_level},
{ "replay", do_replay }, {"replay", do_replay},
/* /*
{ "decrease-visibility", do_decrease_visibility }, { "decrease-visibility", do_decrease_visibility },
{ "increase-visibility", do_increase_visibility }, { "increase-visibility", do_increase_visibility },
*/ */
{ "loadxml", do_load_xml_to_proptree}, {"loadxml", do_load_xml_to_proptree},
{ "savexml", do_save_xml_from_proptree }, {"savexml", do_save_xml_from_proptree},
{ "xmlhttprequest", do_load_xml_from_url }, {"xmlhttprequest", do_load_xml_from_url},
{ "profiler-start", do_profiler_start }, {"profiler-start", do_profiler_start},
{ "profiler-stop", do_profiler_stop }, {"profiler-stop", do_profiler_stop},
{ "video-start", do_video_start },
{ "video-stop", do_video_stop },
{ 0, 0 } // zero-terminated {"video-start", do_video_start},
{"video-stop", do_video_stop},
{0, 0} // zero-terminated
}; };

View file

@ -800,7 +800,7 @@ public:
_sys->gcRelease(_gcRoot); _sys->gcRelease(_gcRoot);
} }
virtual bool operator()(const SGPropertyNode* aNode, SGPropertyNode * root) bool operator()(const SGPropertyNode* aNode, SGPropertyNode* root) override
{ {
_sys->setCmdArg(const_cast<SGPropertyNode*>(aNode)); _sys->setCmdArg(const_cast<SGPropertyNode*>(aNode));
naRef args[1]; naRef args[1];
@ -1541,8 +1541,12 @@ bool FGNasalSys::createModule(const char* moduleName, const char* fileName,
if (!naHash_get(_globals, modname, &locals)) if (!naHash_get(_globals, modname, &locals))
locals = naNewHash(ctx); locals = naNewHash(ctx);
_cmdArg = (SGPropertyNode*)cmdarg; // store the filename in the module hash, so we could reload it
naRef modFilePath = naNewString(ctx);
naStr_fromdata(modFilePath, (char*)fileName, strlen(fileName));
hashset(locals, "__moduleFilePath", modFilePath);
_cmdArg = (SGPropertyNode*)cmdarg;
callWithContext(ctx, code, argc, args, locals); callWithContext(ctx, code, argc, args, locals);
hashset(_globals, moduleName, locals); hashset(_globals, moduleName, locals);
@ -1565,6 +1569,28 @@ void FGNasalSys::deleteModule(const char* moduleName)
naFreeContext(ctx); naFreeContext(ctx);
} }
bool FGNasalSys::reloadModuleFromFile(const std::string& moduleName)
{
if (!_inited || naIsNil(_globals)) {
return false;
}
naRef locals = naHash_cget(_globals, (char*)moduleName.c_str());
if (naIsNil(locals)) {
// no such module
return false;
}
naRef filePath = naHash_cget(locals, (char*)"__moduleFilePath");
if (naIsNil(filePath)) {
return false;
}
SGPath path = SGPath::fromUtf8(naStr_data(filePath));
deleteModule(moduleName.c_str());
return loadModule(path, moduleName.c_str());
}
naRef FGNasalSys::getModule(const std::string& moduleName) const naRef FGNasalSys::getModule(const std::string& moduleName) const
{ {
naRef mod = naHash_cget(_globals, (char*)moduleName.c_str()); naRef mod = naHash_cget(_globals, (char*)moduleName.c_str());

View file

@ -163,6 +163,8 @@ public:
*/ */
static naRef getPropertyValue(naContext c, SGPropertyNode* node); static naRef getPropertyValue(naContext c, SGPropertyNode* node);
bool reloadModuleFromFile(const std::string& moduleName);
private: private:
void initLogLevelConstants(); void initLogLevelConstants();
@ -176,6 +178,7 @@ private:
std::string& errors); std::string& errors);
naRef genPropsModule(); naRef genPropsModule();
private: private:
//friend class FGNasalScript; //friend class FGNasalScript;
friend class FGNasalListener; friend class FGNasalListener;