Reset: Nasal can be shutdown.
Also guard against duplicate init of cppbind wrapped classes.
This commit is contained in:
parent
95679e6d76
commit
881df711ba
8 changed files with 124 additions and 39 deletions
|
@ -152,17 +152,19 @@ static naRef f_createFileDialog(naContext c, naRef me, int argc, naRef* args)
|
|||
|
||||
void postinitNasalGUI(naRef globals, naContext c)
|
||||
{
|
||||
NasalFileDialog::init("gui._FileDialog")
|
||||
.member("title", &FGFileDialog::getTitle, &FGFileDialog::setTitle)
|
||||
.member("button", &FGFileDialog::getButton, &FGFileDialog::setButton)
|
||||
.member("directory", &FGFileDialog::getDirectory, &FGFileDialog::setDirectory)
|
||||
.member("show_hidden", &FGFileDialog::showHidden, &FGFileDialog::setShowHidden)
|
||||
.member("placeholder", &FGFileDialog::getPlaceholder, &FGFileDialog::setPlaceholderName)
|
||||
.member("pattern", &FGFileDialog::filterPatterns, &FGFileDialog::setFilterPatterns)
|
||||
.method("open", &FGFileDialog::exec)
|
||||
.method("close", &FGFileDialog::close)
|
||||
.method("setCallback", &FGFileDialog::setCallbackFromNasal);
|
||||
|
||||
if (!NasalFileDialog::isInit()) {
|
||||
NasalFileDialog::init("gui._FileDialog")
|
||||
.member("title", &FGFileDialog::getTitle, &FGFileDialog::setTitle)
|
||||
.member("button", &FGFileDialog::getButton, &FGFileDialog::setButton)
|
||||
.member("directory", &FGFileDialog::getDirectory, &FGFileDialog::setDirectory)
|
||||
.member("show_hidden", &FGFileDialog::showHidden, &FGFileDialog::setShowHidden)
|
||||
.member("placeholder", &FGFileDialog::getPlaceholder, &FGFileDialog::setPlaceholderName)
|
||||
.member("pattern", &FGFileDialog::filterPatterns, &FGFileDialog::setFilterPatterns)
|
||||
.method("open", &FGFileDialog::exec)
|
||||
.method("close", &FGFileDialog::close)
|
||||
.method("setCallback", &FGFileDialog::setCallbackFromNasal);
|
||||
}
|
||||
|
||||
nasal::Hash guiModule = nasal::Hash(globals, c).get<nasal::Hash>("gui");
|
||||
|
||||
guiModule.set("FILE_DIALOG_OPEN_FILE", (int) FGFileDialog::USE_OPEN_FILE);
|
||||
|
|
|
@ -204,7 +204,9 @@ naRef to_nasal_helper(naContext c, const sc::ElementWeakPtr& el)
|
|||
|
||||
naRef initNasalCanvas(naRef globals, naContext c)
|
||||
{
|
||||
NasalEvent::init("canvas.Event")
|
||||
if (!NasalEvent::isInit()) {
|
||||
|
||||
NasalEvent::init("canvas.Event")
|
||||
.member("type", &sc::Event::getTypeString)
|
||||
.member("target", &sc::Event::getTarget)
|
||||
.member("currentTarget", &sc::Event::getCurrentTarget)
|
||||
|
@ -245,7 +247,8 @@ naRef initNasalCanvas(naRef globals, naContext c)
|
|||
.bases<NasalElement>()
|
||||
.member("_node_ghost", &elementGetNode<canvas::Window>)
|
||||
.method("_getCanvasDecoration", &canvas::Window::getCanvasDecoration);
|
||||
|
||||
}
|
||||
|
||||
nasal::Hash globals_module(globals, c),
|
||||
canvas_module = globals_module.createHash("canvas");
|
||||
|
||||
|
|
|
@ -81,6 +81,8 @@ static naRef f_http_load(const nasal::CallContext& ctx)
|
|||
//------------------------------------------------------------------------------
|
||||
naRef initNasalHTTP(naRef globals, naContext c)
|
||||
{
|
||||
if (!NasalRequest::isInit()) {
|
||||
|
||||
using simgear::HTTP::Request;
|
||||
NasalRequest::init("http.Request")
|
||||
.member("url", &Request::url)
|
||||
|
@ -107,6 +109,8 @@ naRef initNasalHTTP(naRef globals, naContext c)
|
|||
.bases<NasalRequest>()
|
||||
.member("response", &MemoryRequest::responseBody);
|
||||
|
||||
}
|
||||
|
||||
nasal::Hash globals_module(globals, c),
|
||||
http = globals_module.createHash("http");
|
||||
|
||||
|
|
|
@ -1813,6 +1813,7 @@ private:
|
|||
int _gcSaveKey;
|
||||
};
|
||||
|
||||
|
||||
class NasalFPDelegateFactory : public FlightPlan::DelegateFactory
|
||||
{
|
||||
public:
|
||||
|
@ -1823,7 +1824,7 @@ public:
|
|||
_gcSaveKey = _nasal->gcSave(_func);
|
||||
}
|
||||
|
||||
~NasalFPDelegateFactory()
|
||||
virtual ~NasalFPDelegateFactory()
|
||||
{
|
||||
_nasal->gcRelease(_gcSaveKey);
|
||||
}
|
||||
|
@ -1845,6 +1846,20 @@ private:
|
|||
int _gcSaveKey;
|
||||
};
|
||||
|
||||
static std::vector<NasalFPDelegateFactory*> static_nasalDelegateFactories;
|
||||
|
||||
void shutdownNasalPositioned()
|
||||
{
|
||||
std::vector<NasalFPDelegateFactory*>::iterator it;
|
||||
for (it = static_nasalDelegateFactories.begin();
|
||||
it != static_nasalDelegateFactories.end(); ++it)
|
||||
{
|
||||
FlightPlan::unregisterDelegateFactory(*it);
|
||||
delete (*it);
|
||||
}
|
||||
static_nasalDelegateFactories.clear();
|
||||
}
|
||||
|
||||
static naRef f_registerFPDelegate(naContext c, naRef me, int argc, naRef* args)
|
||||
{
|
||||
if ((argc < 1) || !naIsFunc(args[0])) {
|
||||
|
@ -1853,7 +1868,7 @@ static naRef f_registerFPDelegate(naContext c, naRef me, int argc, naRef* args)
|
|||
|
||||
NasalFPDelegateFactory* factory = new NasalFPDelegateFactory(args[0]);
|
||||
FlightPlan::registerDelegateFactory(factory);
|
||||
|
||||
static_nasalDelegateFactories.push_back(factory);
|
||||
return naNil();
|
||||
}
|
||||
|
||||
|
|
|
@ -31,5 +31,6 @@ bool geodFromHash(naRef ref, SGGeod& result);
|
|||
naRef initNasalPositioned(naRef globals, naContext c);
|
||||
naRef initNasalPositioned_cppbind(naRef globals, naContext c);
|
||||
void postinitNasalPositioned(naRef globals, naContext c);
|
||||
void shutdownNasalPositioned();
|
||||
|
||||
#endif // of SCRIPTING_NASAL_POSITIONED_HXX
|
||||
|
|
|
@ -459,6 +459,8 @@ static naRef f_sortByRange(nasal::CallContext ctx)
|
|||
//------------------------------------------------------------------------------
|
||||
naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c)
|
||||
{
|
||||
if (!NasalPositioned::isInit()) {
|
||||
|
||||
NasalPositioned::init("Positioned")
|
||||
.member("id", &FGPositioned::ident)
|
||||
.member("ident", &FGPositioned::ident) // TODO to we really need id and ident?
|
||||
|
@ -502,6 +504,7 @@ naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c)
|
|||
.method("getStar", &FGAirport::findSTARWithIdent)
|
||||
.method("getIAP", &FGAirport::findApproachWithIdent)
|
||||
.method("tostring", &FGAirport::toString);
|
||||
}
|
||||
|
||||
nasal::Hash globals(globalsRef, c),
|
||||
positioned( globals.createHash("positioned") );
|
||||
|
|
|
@ -246,13 +246,6 @@ naRef FGNasalSys::callMethod(naRef code, naRef self, int argc, naRef* args, naRe
|
|||
FGNasalSys::~FGNasalSys()
|
||||
{
|
||||
nasalSys = 0;
|
||||
map<int, FGNasalListener *>::iterator it, end = _listener.end();
|
||||
for(it = _listener.begin(); it != end; ++it)
|
||||
delete it->second;
|
||||
|
||||
naFreeContext(_context);
|
||||
_globals = naNil();
|
||||
_string = naNil();
|
||||
}
|
||||
|
||||
bool FGNasalSys::parseAndRun(const char* sourceCode)
|
||||
|
@ -601,10 +594,12 @@ static naRef f_findDataDir(naContext c, naRef me, int argc, naRef* args)
|
|||
class NasalCommand : public SGCommandMgr::Command
|
||||
{
|
||||
public:
|
||||
NasalCommand(FGNasalSys* sys, naRef f) :
|
||||
NasalCommand(FGNasalSys* sys, naRef f, const std::string& name) :
|
||||
_sys(sys),
|
||||
_func(f)
|
||||
_func(f),
|
||||
_name(name)
|
||||
{
|
||||
globals->get_commands()->addCommandObject(_name, this);
|
||||
_gcRoot = sys->gcSave(f);
|
||||
}
|
||||
|
||||
|
@ -628,6 +623,7 @@ private:
|
|||
FGNasalSys* _sys;
|
||||
naRef _func;
|
||||
int _gcRoot;
|
||||
std::string _name;
|
||||
};
|
||||
|
||||
static naRef f_addCommand(naContext c, naRef me, int argc, naRef* args)
|
||||
|
@ -635,20 +631,16 @@ static naRef f_addCommand(naContext c, naRef me, int argc, naRef* args)
|
|||
if(argc != 2 || !naIsString(args[0]) || !naIsFunc(args[1]))
|
||||
naRuntimeError(c, "bad arguments to addcommand()");
|
||||
|
||||
naRef func = args[1];
|
||||
NasalCommand* cmd = new NasalCommand(nasalSys, func);
|
||||
globals->get_commands()->addCommandObject(naStr_data(args[0]), cmd);
|
||||
nasalSys->addCommand(args[1], naStr_data(args[0]));
|
||||
return naNil();
|
||||
}
|
||||
|
||||
static naRef f_removeCommand(naContext c, naRef me, int argc, naRef* args)
|
||||
{
|
||||
SGCommandMgr::Command* cmd = globals->get_commands()->getCommand(naStr_data(args[0]));
|
||||
|
||||
// SGCommandMgr::Command* cmd = globals->get_commands()->removeCommand(naStr_data(args[0]))
|
||||
|
||||
delete cmd;
|
||||
if ((argc < 1) || !naIsString(args[0]))
|
||||
naRuntimeError(c, "bad argument to removecommand()");
|
||||
|
||||
globals->get_commands()->removeCommand(naStr_data(args[0]));
|
||||
return naNil();
|
||||
}
|
||||
|
||||
|
@ -782,13 +774,15 @@ void FGNasalSys::init()
|
|||
initNasalCondition(_globals, _context);
|
||||
initNasalHTTP(_globals, _context);
|
||||
|
||||
NasalTimerObj::init("Timer")
|
||||
.method("start", &TimerObj::start)
|
||||
.method("stop", &TimerObj::stop)
|
||||
.method("restart", &TimerObj::restart)
|
||||
.member("singleShot", &TimerObj::isSingleShot, &TimerObj::setSingleShot)
|
||||
.member("isRunning", &TimerObj::isRunning);
|
||||
|
||||
if (!NasalTimerObj::isInit()) {
|
||||
NasalTimerObj::init("Timer")
|
||||
.method("start", &TimerObj::start)
|
||||
.method("stop", &TimerObj::stop)
|
||||
.method("restart", &TimerObj::restart)
|
||||
.member("singleShot", &TimerObj::isSingleShot, &TimerObj::setSingleShot)
|
||||
.member("isRunning", &TimerObj::isRunning);
|
||||
}
|
||||
|
||||
// Now load the various source files in the Nasal directory
|
||||
simgear::Dir nasalDir(SGPath(globals->get_fg_root(), "Nasal"));
|
||||
loadScriptDirectory(nasalDir);
|
||||
|
@ -816,6 +810,36 @@ void FGNasalSys::init()
|
|||
postinitNasalGUI(_globals, _context);
|
||||
}
|
||||
|
||||
void FGNasalSys::shutdown()
|
||||
{
|
||||
shutdownNasalPositioned();
|
||||
|
||||
map<int, FGNasalListener *>::iterator it, end = _listener.end();
|
||||
for(it = _listener.begin(); it != end; ++it)
|
||||
delete it->second;
|
||||
_listener.clear();
|
||||
|
||||
NasalCommandDict::iterator j = _commands.begin();
|
||||
for (; j != _commands.end(); ++j) {
|
||||
globals->get_commands()->removeCommand(j->first);
|
||||
}
|
||||
_commands.clear();
|
||||
|
||||
naClearSaved();
|
||||
|
||||
_string = naNil(); // will be freed by _context
|
||||
naFreeContext(_context);
|
||||
|
||||
//setWatchedRef(_globals);
|
||||
|
||||
// remove the recursive reference in globals
|
||||
hashset(_globals, "globals", naNil());
|
||||
_globals = naNil();
|
||||
|
||||
naGC();
|
||||
|
||||
}
|
||||
|
||||
naRef FGNasalSys::wrappedPropsNode(SGPropertyNode* aProps)
|
||||
{
|
||||
static naRef wrapNodeFunc = naNil();
|
||||
|
@ -1251,6 +1275,30 @@ void FGNasalSys::registerToUnload(FGNasalModelData *data)
|
|||
_unloadList.push(data);
|
||||
}
|
||||
|
||||
void FGNasalSys::addCommand(naRef func, const std::string& name)
|
||||
{
|
||||
if (_commands.find(name) != _commands.end()) {
|
||||
SG_LOG(SG_NASAL, SG_WARN, "duplicate add of command:" << name);
|
||||
return;
|
||||
}
|
||||
|
||||
NasalCommand* cmd = new NasalCommand(this, func, name);
|
||||
_commands[name] = cmd;
|
||||
}
|
||||
|
||||
void FGNasalSys::removeCommand(const std::string& name)
|
||||
{
|
||||
NasalCommandDict::iterator it = _commands.find(name);
|
||||
if (it == _commands.end()) {
|
||||
SG_LOG(SG_NASAL, SG_WARN, "remove of unknwon command:" << name);
|
||||
return;
|
||||
}
|
||||
|
||||
// will delete the NasalCommand instance
|
||||
globals->get_commands()->removeCommand(name);
|
||||
_commands.erase(it);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// FGNasalListener class.
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ class FGNasalScript;
|
|||
class FGNasalListener;
|
||||
class SGCondition;
|
||||
class FGNasalModelData;
|
||||
class NasalCommand;
|
||||
|
||||
namespace simgear { class BufferedLogCallback; }
|
||||
|
||||
|
@ -33,6 +34,8 @@ public:
|
|||
FGNasalSys();
|
||||
virtual ~FGNasalSys();
|
||||
virtual void init();
|
||||
virtual void shutdown();
|
||||
|
||||
virtual void update(double dt);
|
||||
|
||||
// Loads a nasal script from an external file and inserts it as a
|
||||
|
@ -84,6 +87,9 @@ public:
|
|||
|
||||
void deleteModule(const char* moduleName);
|
||||
|
||||
void addCommand(naRef func, const std::string& name);
|
||||
void removeCommand(const std::string& name);
|
||||
|
||||
/**
|
||||
* Set member of specified hash to given value
|
||||
*/
|
||||
|
@ -173,6 +179,9 @@ private:
|
|||
SGPropertyNode_ptr _cmdArg;
|
||||
|
||||
simgear::BufferedLogCallback* _log;
|
||||
|
||||
typedef std::map<std::string, NasalCommand*> NasalCommandDict;
|
||||
NasalCommandDict _commands;
|
||||
public:
|
||||
void handleTimer(NasalTimer* t);
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue