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:
parent
6bb22caea2
commit
c509744b0f
3 changed files with 78 additions and 37 deletions
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue