]> git.mxchange.org Git - flightgear.git/commitdiff
Expose SGCondition as a ghost to Nasal directly.
authorJames Turner <zakalawe@mac.com>
Sun, 19 Aug 2012 20:13:31 +0000 (21:13 +0100)
committerJames Turner <zakalawe@mac.com>
Sun, 19 Aug 2012 20:13:31 +0000 (21:13 +0100)
src/Scripting/CMakeLists.txt
src/Scripting/NasalCondition.cxx [new file with mode: 0644]
src/Scripting/NasalCondition.hxx [new file with mode: 0644]
src/Scripting/NasalSys.cxx
src/Scripting/NasalSys.hxx
src/Scripting/nasal-props.cxx

index 42692b55a95578e095d5159f52e3237229d11e88..57ef20827a9d4c9f46d10fe7f32fac7717ca5ac5 100644 (file)
@@ -6,6 +6,7 @@ set(SOURCES
     NasalPositioned.cxx
     NasalCanvas.cxx
     NasalClipboard.cxx
+    NasalCondition.cxx
        )
 
 set(HEADERS
@@ -13,6 +14,7 @@ set(HEADERS
     NasalPositioned.hxx
     NasalCanvas.hxx
     NasalClipboard.hxx
+    NasalCondition.hxx
        )
 
 if(WIN32)
diff --git a/src/Scripting/NasalCondition.cxx b/src/Scripting/NasalCondition.cxx
new file mode 100644 (file)
index 0000000..da796c5
--- /dev/null
@@ -0,0 +1,115 @@
+// NasalCondition -- expose SGCondition to Nasal
+//
+// Written by James Turner, started 2012.
+//
+// Copyright (C) 2012 James Turner
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <string.h>
+
+#include "NasalCondition.hxx"
+#include "NasalSys.hxx"
+#include <Main/globals.hxx>
+
+#include <simgear/sg_inlines.h>
+#include <simgear/props/condition.hxx>
+
+static void conditionGhostDestroy(void* g);
+
+naGhostType ConditionGhostType = { conditionGhostDestroy, "condition" };
+
+static void hashset(naContext c, naRef hash, const char* key, naRef val)
+{
+  naRef s = naNewString(c);
+  naStr_fromdata(s, (char*)key, strlen(key));
+  naHash_set(hash, s, val);
+}
+
+SGCondition* conditionGhost(naRef r)
+{
+  if ((naGhost_type(r) == &ConditionGhostType))
+  {
+    return (SGCondition*) naGhost_ptr(r);
+  }
+  
+  return 0;
+}
+
+static void conditionGhostDestroy(void* g)
+{
+  SGCondition* cond = (SGCondition*)g;
+  if (!SGCondition::put(cond)) // unref
+    delete cond;
+}
+
+static naRef conditionPrototype;
+
+naRef ghostForCondition(naContext c, const SGCondition* cond)
+{
+  if (!cond) {
+    return naNil();
+  }
+  
+  SGCondition::get(cond); // take a ref
+  return naNewGhost(c, &ConditionGhostType, (void*) cond);
+}
+
+static naRef f_condition_test(naContext c, naRef me, int argc, naRef* args)
+{
+  SGCondition* cond = conditionGhost(me);
+  if (!cond) {
+    naRuntimeError(c, "condition.test called on non-condition object");
+  }
+  
+  return naNum(cond->test());
+}
+
+static naRef f_createCondition(naContext c, naRef me, int argc, naRef* args)
+{
+  SGPropertyNode* node = ghostToPropNode(args[0]);
+  SGPropertyNode* root = globals->get_props();
+  if (argc > 1) {
+    root = ghostToPropNode(args[1]);
+  }
+  
+  SGCondition* cond = sgReadCondition(root, node);
+  return ghostForCondition(c, cond);
+}
+
+// Table of extension functions.  Terminate with zeros.
+static struct { const char* name; naCFunction func; } funcs[] = {
+  { "_createCondition", f_createCondition },
+  { 0, 0 }
+};
+
+
+naRef initNasalCondition(naRef globals, naContext c, naRef gcSave)
+{
+  conditionPrototype = naNewHash(c);
+  hashset(c, gcSave, "conditionProto", conditionPrototype);
+  
+  hashset(c, conditionPrototype, "test", naNewFunc(c, naNewCCode(c, f_condition_test)));  
+  for(int i=0; funcs[i].name; i++) {
+    hashset(c, globals, funcs[i].name,
+            naNewFunc(c, naNewCCode(c, funcs[i].func)));
+  }
+  
+  return naNil();
+}
diff --git a/src/Scripting/NasalCondition.hxx b/src/Scripting/NasalCondition.hxx
new file mode 100644 (file)
index 0000000..51b2661
--- /dev/null
@@ -0,0 +1,34 @@
+// NasalCondition.hxx -- expose SGCondition to Nasal
+//
+// Written by James Turner, started 2012.
+//
+// Copyright (C) 2012 James Turner
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+#ifndef SCRIPTING_NASAL_CONDITION_HXX
+#define SCRIPTING_NASAL_CONDITION_HXX
+
+#include <simgear/nasal/nasal.h>
+
+// forward decls
+class SGCondition;
+
+naRef ghostForCondition(naContext c, const SGCondition* cond);
+
+naRef initNasalCondition(naRef globals, naContext c, naRef gcSave);
+
+#endif // of SCRIPTING_NASAL_CONDITION_HXX
+
index a3983015d753942ace0f7f2fe012a18c69fa76f4..b38e0fbcd35137e43dd8d7cc8d78281380068995 100644 (file)
@@ -29,6 +29,7 @@
 #include "NasalPositioned.hxx"
 #include "NasalCanvas.hxx"
 #include "NasalClipboard.hxx"
+#include "NasalCondition.hxx"
 
 #include <Main/globals.hxx>
 #include <Main/util.hxx>
@@ -559,7 +560,8 @@ void FGNasalSys::init()
     initNasalPositioned(_globals, _context, _gcHash);
     initNasalCanvas(_globals, _context, _gcHash);
     NasalClipboard::init(this);
-
+    initNasalCondition(_globals, _context, _gcHash);
+  
     // Now load the various source files in the Nasal directory
     simgear::Dir nasalDir(SGPath(globals->get_fg_root(), "Nasal"));
     loadScriptDirectory(nasalDir);
index 18ef05314c115682d63b68d3daefbe437c10809a..5434844998fb077d1a5df1cab0e771a960703406 100644 (file)
@@ -14,7 +14,7 @@
 
 class FGNasalScript;
 class FGNasalListener;
-
+class SGCondition;
 
 /** Nasal model data container.
  * load and unload methods must be run in main thread (not thread-safe). */
@@ -65,6 +65,9 @@ protected:
     SGSharedPtr<FGNasalModelData> _data;
 };
 
+SGPropertyNode* ghostToPropNode(naRef ref);
+SGCondition* conditionGhost(naRef r);
+
 class FGNasalSys : public SGSubsystem
 {
 public:
@@ -129,7 +132,7 @@ public:
     naRef callMethod(naRef code, naRef self, int argc, naRef* args, naRef locals);
   
     naRef propNodeGhost(SGPropertyNode* handle);
-
+  
     void registerToLoad(FGNasalModelData* data)   { _loadList.push(data);}
     void registerToUnload(FGNasalModelData* data) { _unloadList.push(data);}
 
index 78a2428778aa67fff42d18cda3c621e5b0e784a9..1df4b0d42b93741296eb0229dafb18166b102d1a 100644 (file)
@@ -45,6 +45,15 @@ naRef FGNasalSys::propNodeGhost(SGPropertyNode* handle)
     return propNodeGhostCreate(_context, handle);
 }
 
+SGPropertyNode* ghostToPropNode(naRef ref)
+{
+  if (!naIsGhost(ref) || (naGhost_type(ref) != &PropNodeGhostType))
+    return NULL;
+  
+  SGPropertyNode_ptr* pp = (SGPropertyNode_ptr*) naGhost_ptr(ref);
+  return pp->ptr();
+}
+
 #define NASTR(s) s ? naStr_fromdata(naNewString(c),(char*)(s),strlen(s)) : naNil()
 
 //