From 79e48829da50e0103e81684896b8287bfe23cc96 Mon Sep 17 00:00:00 2001 From: ehofman Date: Mon, 1 Dec 2003 14:35:49 +0000 Subject: [PATCH] Add Nasal Vs. 1.5 --- src/Scripting/Makefile.am | 2 +- src/Scripting/NasalSys.cxx | 142 ++++++++++++++++----- src/Scripting/NasalSys.hxx | 16 +++ src/Scripting/nasal-props.cxx | 230 ++++++++++++++++++++++++++++++++++ 4 files changed, 357 insertions(+), 33 deletions(-) create mode 100644 src/Scripting/nasal-props.cxx diff --git a/src/Scripting/Makefile.am b/src/Scripting/Makefile.am index 4eb53621f..468e969d7 100644 --- a/src/Scripting/Makefile.am +++ b/src/Scripting/Makefile.am @@ -1,6 +1,6 @@ noinst_LIBRARIES = libScripting.a -libScripting_a_SOURCES = NasalSys.cxx NasalSys.hxx +libScripting_a_SOURCES = NasalSys.cxx NasalSys.hxx nasal-props.cxx # libScripting_a_SOURCES = scriptmgr.cxx scriptmgr.hxx NasalSys.cxx NasalSys.hxx INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index e481ac510..80adc19ea 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -34,7 +34,8 @@ static char* readfile(const char* file, int* lenOut) // etc...) SG_LOG(SG_NASAL, SG_ALERT, "ERROR in Nasal initialization: " << - "short count returned from fread(). Check your C library!"); + "short count returned from fread() of " << file << + ". Check your C library!"); delete[] buf; return 0; } @@ -60,6 +61,20 @@ FGNasalSys::~FGNasalSys() _globals = naNil(); } +bool FGNasalSys::parseAndRun(const char* sourceCode) +{ + naRef code = parse("FGNasalSys::parseAndRun()", sourceCode, + strlen(sourceCode)); + if(naIsNil(code)) + return false; + + naCall(_context, code, naNil(), naNil(), naNil()); + + if(!naGetError(_context)) return true; + logError(); + return false; +} + // Utility. Sets a named key in a hash by C string, rather than nasal // string object. void FGNasalSys::hashset(naRef hash, const char* key, naRef val) @@ -176,13 +191,11 @@ static naRef f_fgcommand(naContext c, naRef args) { naRef cmd = naVec_get(args, 0); naRef props = naVec_get(args, 1); - if(!naIsString(cmd) || !naIsString(props)) return naNil(); - - SGPropertyNode* pnode = - globals->get_props()->getNode(naStr_data(props)); - if(pnode) - globals->get_commands()->execute(naStr_data(cmd), pnode); + if(!naIsString(cmd) || !naIsGhost(props)) return naNil(); + SGPropertyNode_ptr* node = (SGPropertyNode_ptr*)naGhost_ptr(props); + globals->get_commands()->execute(naStr_data(cmd), *node); return naNil(); + } // settimer(func, dt, simtime) extension function. Falls through to @@ -194,18 +207,34 @@ static naRef f_settimer(naContext c, naRef args) return naNil(); } +// Returns a ghost handle to the argument to the currently executing +// command +static naRef f_cmdarg(naContext c, naRef args) +{ + FGNasalSys* nasal = (FGNasalSys*)globals->get_subsystem("nasal"); + return nasal->cmdArgGhost(); +} + // Table of extension functions. Terminate with zeros. static struct { char* name; naCFunction func; } funcs[] = { { "getprop", f_getprop }, { "setprop", f_setprop }, { "print", f_print }, - { "fgcommand", f_fgcommand }, + { "_fgcommand", f_fgcommand }, { "settimer", f_settimer }, + { "_cmdarg", f_cmdarg }, { 0, 0 } }; +naRef FGNasalSys::cmdArgGhost() +{ + return propNodeGhost(_cmdArg); +} + void FGNasalSys::init() { + int i; + _context = naNewContext(); // Start with globals. Add it to itself as a recursive @@ -220,10 +249,13 @@ void FGNasalSys::init() hashset(_globals, "math", naMathLib(_context)); // Add our custom extension functions: - for(int i=0; funcs[i].name; i++) + for(i=0; funcs[i].name; i++) hashset(_globals, funcs[i].name, naNewFunc(_context, naNewCCode(_context, funcs[i].func))); + // And our SGPropertyNode wrapper + hashset(_globals, "props", genPropsModule()); + // Make a "__timers" hash to hold the settimer() handlers (to // protect them from begin garbage-collected). _timerHash = naNewHash(_context); @@ -241,6 +273,42 @@ void FGNasalSys::init() if(file.extension() != "nas") continue; readScriptFile(fullpath, file.base().c_str()); } + + // Pull scripts out of the property tree, too + loadPropertyScripts(); +} + +// Loads the scripts found under /nasal in the global tree +void FGNasalSys::loadPropertyScripts() +{ + SGPropertyNode* nasal = globals->get_props()->getNode("nasal"); + if(!nasal) return; + + for(int i=0; inChildren(); i++) { + SGPropertyNode* n = nasal->getChild(i); + + const char* module = n->getName(); + if(n->hasChild("module")) + module = n->getStringValue("module"); + + const char* file = n->getStringValue("file"); + if(!n->hasChild("file")) file = 0; // Hrm... + if(file) { + SGPath p(globals->get_fg_root()); + p.append(file); + readScriptFile(p, module); + } + + const char* src = n->getStringValue("script"); + if(!n->hasChild("script")) src = 0; // Hrm... + if(src) + initModule(module, n->getPath(), src, strlen(src)); + + if(!file && !src) + SG_LOG(SG_NASAL, SG_ALERT, "Nasal error: " << + "no or