From 0fbc448af0dbd6f01050776e3824b07888c7c8b3 Mon Sep 17 00:00:00 2001 From: James Turner Date: Fri, 22 Nov 2013 22:40:50 +0000 Subject: [PATCH] Nasal changes for reset - reduce use of global context (will die soon) - replace static wrappedNode ref which breaks reset --- src/GUI/FileDialog.cxx | 3 ++- src/Scripting/NasalClipboard.cxx | 8 ++++-- src/Scripting/NasalPositioned.cxx | 27 ++++++++++++-------- src/Scripting/NasalSys.cxx | 41 +++++++++++++++++++++---------- src/Scripting/NasalSys.hxx | 5 ++-- 5 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/GUI/FileDialog.cxx b/src/GUI/FileDialog.cxx index 2312960cb..3c6b48d83 100644 --- a/src/GUI/FileDialog.cxx +++ b/src/GUI/FileDialog.cxx @@ -101,12 +101,13 @@ public: virtual void onFileDialogDone(FGFileDialog* instance, const SGPath& aPath) { FGNasalSys* sys = static_cast(globals->get_subsystem("nasal")); - naContext ctx = sys->context(); + naContext ctx = naNewContext(); naRef args[1]; args[0] = nasal::to_nasal(ctx, aPath); sys->callMethod(func, object, 1, args, naNil() /* locals */); + naFreeContext(ctx); } ~NasalCallback() diff --git a/src/Scripting/NasalClipboard.cxx b/src/Scripting/NasalClipboard.cxx index 6ac146263..d2b26f6f7 100644 --- a/src/Scripting/NasalClipboard.cxx +++ b/src/Scripting/NasalClipboard.cxx @@ -113,8 +113,10 @@ NasalClipboard::~NasalClipboard() //------------------------------------------------------------------------------ void NasalClipboard::init(FGNasalSys *nasal) { + naContext ctx = naNewContext(); + _clipboard = create(); - _clipboard_hash = naNewHash(nasal->context()); + _clipboard_hash = naNewHash(ctx); nasal->globalsSet("clipboard", _clipboard_hash); @@ -124,7 +126,7 @@ void NasalClipboard::init(FGNasalSys *nasal) ( _clipboard_hash, funcs[i].name, - naNewFunc(nasal->context(), naNewCCode(nasal->context(), funcs[i].func)) + naNewFunc(ctx, naNewCCode(ctx, funcs[i].func)) ); SG_LOG(SG_NASAL, SG_DEBUG, "Adding clipboard function: " << funcs[i].name); @@ -136,6 +138,8 @@ void NasalClipboard::init(FGNasalSys *nasal) SG_LOG(SG_NASAL, SG_DEBUG, "Adding clipboard symbol: " << symbols[i].name); } + + naFreeContext(ctx); } //------------------------------------------------------------------------------ diff --git a/src/Scripting/NasalPositioned.cxx b/src/Scripting/NasalPositioned.cxx index 6e64bdb4b..3e494e352 100644 --- a/src/Scripting/NasalPositioned.cxx +++ b/src/Scripting/NasalPositioned.cxx @@ -1798,13 +1798,15 @@ private: void callDelegateMethod(const char* method) { naRef f; - if (naMember_cget(_nasal->context(), _instance, method, &f) == 0) { - return; // no method on the delegate + naContext ctx = naNewContext(); + + if (naMember_cget(ctx, _instance, method, &f) != 0) { + naRef arg[1]; + arg[0] = ghostForFlightPlan(ctx, _plan); + _nasal->callMethod(f, _instance, 1, arg, naNil()); } - naRef arg[1]; - arg[0] = ghostForFlightPlan(_nasal->context(), _plan); - _nasal->callMethod(f, _instance, 1, arg, naNil()); + naFreeContext(ctx); } FGNasalSys* _nasal; @@ -1832,13 +1834,18 @@ public: virtual FlightPlan::Delegate* createFlightPlanDelegate(FlightPlan* fp) { naRef args[1]; - args[0] = ghostForFlightPlan(_nasal->context(), fp); + naContext ctx = naNewContext(); + args[0] = ghostForFlightPlan(ctx, fp); naRef instance = _nasal->call(_func, 1, args, naNil()); - if (naIsNil(instance)) { - return NULL; - } - return new NasalFPDelegate(fp, _nasal, instance); + FlightPlan::Delegate* result = NULL; + if (!naIsNil(instance)) { + // will GC-save instance + result = new NasalFPDelegate(fp, _nasal, instance); + } + + naFreeContext(ctx); + return result; } private: FGNasalSys* _nasal; diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index caaf6a582..f0df1aacf 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -206,6 +206,7 @@ FGNasalSys::FGNasalSys() _context = 0; _globals = naNil(); _string = naNil(); + _wrappedNodeFunc = naNil(); _log = new simgear::BufferedLogCallback(SG_NASAL, SG_INFO); _log->truncateAt(255); @@ -844,15 +845,17 @@ void FGNasalSys::shutdown() naRef FGNasalSys::wrappedPropsNode(SGPropertyNode* aProps) { - static naRef wrapNodeFunc = naNil(); - if (naIsNil(wrapNodeFunc)) { + if (naIsNil(_wrappedNodeFunc)) { nasal::Hash props = getGlobals().get("props"); - wrapNodeFunc = props.get("wrapNode"); + _wrappedNodeFunc = props.get("wrapNode"); } naRef args[1]; args[0] = propNodeGhost(aProps); - return naCall(_context, wrapNodeFunc, 1, args, naNil(), naNil()); + naContext ctx = naNewContext(); + naRef wrapped = naCall(ctx, _wrappedNodeFunc, 1, args, naNil(), naNil()); + naFreeContext(ctx); + return wrapped; } void FGNasalSys::update(double) @@ -1062,44 +1065,54 @@ bool FGNasalSys::createModule(const char* moduleName, const char* fileName, if(naIsNil(code)) return false; + naContext ctx = naNewContext(); + // See if we already have a module hash to use. This allows the // user to, for example, add functions to the built-in math // module. Make a new one if necessary. naRef locals; - naRef modname = naNewString(_context); + naRef modname = naNewString(ctx); naStr_fromdata(modname, (char*)moduleName, strlen(moduleName)); if(!naHash_get(_globals, modname, &locals)) - locals = naNewHash(_context); + locals = naNewHash(ctx); _cmdArg = (SGPropertyNode*)cmdarg; call(code, argc, args, locals); hashset(_globals, moduleName, locals); + + naFreeContext(ctx); return true; } void FGNasalSys::deleteModule(const char* moduleName) { - naRef modname = naNewString(_context); + naContext ctx = naNewContext(); + naRef modname = naNewString(ctx); naStr_fromdata(modname, (char*)moduleName, strlen(moduleName)); naHash_delete(_globals, modname); + naFreeContext(ctx); } naRef FGNasalSys::parse(const char* filename, const char* buf, int len) { int errLine = -1; - naRef srcfile = naNewString(_context); + naContext ctx = naNewContext(); + naRef srcfile = naNewString(ctx); naStr_fromdata(srcfile, (char*)filename, strlen(filename)); - naRef code = naParseCode(_context, srcfile, 1, (char*)buf, len, &errLine); + naRef code = naParseCode(ctx, srcfile, 1, (char*)buf, len, &errLine); if(naIsNil(code)) { SG_LOG(SG_NASAL, SG_ALERT, - "Nasal parse error: " << naGetError(_context) << + "Nasal parse error: " << naGetError(ctx) << " in "<< filename <<", line " << errLine); + naFreeContext(ctx); return naNil(); } // Bind to the global namespace before returning - return naBindFunction(_context, code, _globals); + naRef bound = naBindFunction(ctx, code, _globals); + naFreeContext(ctx); + return bound; } bool FGNasalSys::handleCommand( const char* moduleName, @@ -1115,12 +1128,14 @@ bool FGNasalSys::handleCommand( const char* moduleName, // command. naRef locals = naNil(); if(moduleName[0]) { - naRef modname = naNewString(_context); + naContext ctx = naNewContext(); + naRef modname = naNewString(ctx); naStr_fromdata(modname, (char*)moduleName, strlen(moduleName)); if(!naHash_get(_globals, modname, &locals)) { - locals = naNewHash(_context); + locals = naNewHash(ctx); naHash_set(_globals, modname, locals); } + naFreeContext(ctx); } // Cache this command's argument for inspection via cmdarg(). For diff --git a/src/Scripting/NasalSys.hxx b/src/Scripting/NasalSys.hxx index 1ce862c78..f8be35db1 100644 --- a/src/Scripting/NasalSys.hxx +++ b/src/Scripting/NasalSys.hxx @@ -112,9 +112,6 @@ public: // can't call this 'globals' due to naming clash naRef nasalGlobals() const { return _globals; } - - naContext context() const - { return _context; } nasal::Hash getGlobals() const { return nasal::Hash(_globals, _context); } @@ -182,6 +179,8 @@ private: typedef std::map NasalCommandDict; NasalCommandDict _commands; + + naRef _wrappedNodeFunc; public: void handleTimer(NasalTimer* t); }; -- 2.39.5