4 #include <simgear/misc/sg_path.hxx>
5 #include <simgear/structure/subsystem_mgr.hxx>
6 #include <simgear/nasal/nasal.h>
13 class FGNasalListener;
15 class FGNasalSys : public SGSubsystem
19 virtual ~FGNasalSys();
21 virtual void update(double dt) { /* noop */ }
23 // Loads a nasal script from an external file and inserts it as a
24 // global module of the specified name.
25 void loadModule(SGPath file, const char* moduleName);
27 // Simple hook to run arbitrary source code. Returns a bool to
28 // indicate successful execution. Does *not* return any Nasal
29 // values, because handling garbage-collected objects from C space
30 // is deep voodoo and violates the "simple hook" idea.
31 bool parseAndRun(const char* sourceCode);
33 // Slightly more complicated hook to get a handle to a precompiled
34 // Nasal script that can be invoked via a call() method. The
35 // caller is expected to delete the FGNasalScript returned from
36 // this function. The "name" argument specifies the "file name"
37 // for the source code that will be printed in Nasal stack traces
39 FGNasalScript* parseScript(const char* src, const char* name=0);
41 // Implementation of the settimer extension function
42 void setTimer(int argc, naRef* args);
44 // Implementation of the setlistener extension function
45 naRef setListener(int argc, naRef* args);
46 naRef removeListener(int argc, naRef* args);
48 // Returns a ghost wrapper for the current _cmdArg
51 // Callbacks for command and timer bindings
52 virtual bool handleCommand(const SGPropertyNode* arg);
54 void createModule(const char* moduleName, const char* fileName,
55 const char* src, int len);
57 void deleteModule(const char* moduleName);
60 friend class FGNasalScript;
61 friend class FGNasalListener;
64 // FGTimer subclass for handling Nasal timer callbacks.
65 // See the implementation of the settimer() extension function for
69 virtual void timerExpired();
76 map<int, FGNasalListener *> _listener;
77 static int _listenerId;
79 void loadPropertyScripts();
80 void hashset(naRef hash, const char* key, naRef val);
81 void logError(naContext);
82 naRef parse(const char* filename, const char* buf, int len);
83 naRef genPropsModule();
84 naRef propNodeGhost(SGPropertyNode* handle);
86 // This mechanism is here to allow naRefs to be passed to
87 // locations "outside" the interpreter. Normally, such a
88 // reference would be garbage collected unexpectedly. By passing
89 // it to gcSave and getting a key/handle, it can be cached in a
90 // globals.__gcsave hash. Be sure to release it with gcRelease
93 void gcRelease(int key);
98 SGPropertyNode* _cmdArg;
103 public: void handleTimer(NasalTimer* t);
107 class FGNasalScript {
109 ~FGNasalScript() { _nas->gcRelease(_gcKey); }
113 naCall(_nas->_context, _code, 0, &n, naNil(), naNil());
114 return naGetError(_nas->_context) == 0;
118 friend class FGNasalSys;
125 class FGNasalListener : public SGPropertyChangeListener {
127 FGNasalListener(SGPropertyNode_ptr node, naRef handler,
128 FGNasalSys* nasal, int key)
129 : _node(node), _handler(handler), _gcKey(key), _nas(nasal) {}
132 _nas->gcRelease(_gcKey);
135 void valueChanged(SGPropertyNode* node) {
136 _nas->_cmdArg = node;
137 naContext c = naNewContext();
139 naCall(c, _handler, 0, 0, naNil(), naNil());
147 friend class FGNasalSys;
148 SGPropertyNode_ptr _node;
154 #endif // __NASALSYS_HXX