]> git.mxchange.org Git - flightgear.git/commitdiff
Skeleton Nasal-Canvas integration.
authorJames Turner <zakalawe@mac.com>
Thu, 2 Aug 2012 11:18:38 +0000 (12:18 +0100)
committerJames Turner <zakalawe@mac.com>
Thu, 2 Aug 2012 11:18:38 +0000 (12:18 +0100)
This code is non-functional, but contains most of the stubs to show what's required to add property get/set access, convert to from ghost & C++ types, and manage ownership. Element derived classes & inheritance (e.g., methods on image/path/map elements) will follow, along with some actual functionality!

src/Canvas/canvas.hxx
src/Scripting/CMakeLists.txt
src/Scripting/NasalCanvas.cxx [new file with mode: 0644]
src/Scripting/NasalCanvas.hxx [new file with mode: 0644]
src/Scripting/NasalSys.cxx

index fa75f95d0251bfdfe41b0a263dfe4d74dfdfc3ce..29d9ee93e04d368bfb9af56fde5d71b3f2d8b2e5 100644 (file)
@@ -89,6 +89,12 @@ class Canvas:
 
     void update(double delta_time_sec);
 
+    int getSizeX() const
+    { return _size_x; }
+  
+    int getSizeY() const
+    { return _size_y; }
+  
     void setSizeX(int sx);
     void setSizeY(int sy);
 
index d3eab7a70561053a915a8618049e2b59d048c3a9..44c9563b243a68b566b40caa4debc00d425210f0 100644 (file)
@@ -4,11 +4,13 @@ set(SOURCES
        NasalSys.cxx
        nasal-props.cxx
     NasalPositioned.cxx
+    NasalCanvas.cxx
        )
 
 set(HEADERS
        NasalSys.hxx
     NasalPositioned.hxx
+    NasalCanvas.hxx
        )
 
        
diff --git a/src/Scripting/NasalCanvas.cxx b/src/Scripting/NasalCanvas.cxx
new file mode 100644 (file)
index 0000000..bbafebd
--- /dev/null
@@ -0,0 +1,264 @@
+// NasalCanvas.cxx -- expose Canvas classes 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 "NasalCanvas.hxx"
+
+#include <boost/foreach.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
+
+#include <osgGA/GUIEventAdapter>
+
+#include <simgear/sg_inlines.h>
+
+#include <Canvas/canvas.hxx>
+#include <Canvas/elements/element.hxx>
+
+static naRef canvasPrototype;
+static naRef elementPrototype;
+static naRef eventPrototype;
+
+static void canvasGhostDestroy(void* g);
+static void elementGhostDestroy(void* g);
+static void eventGhostDestroy(void* g);
+
+static const char* canvasGhostGetMember(naContext c, void* g, naRef field, naRef* out);
+naGhostType CanvasGhostType = { canvasGhostDestroy, "canvas", canvasGhostGetMember, 0 };
+
+static const char* elementGhostGetMember(naContext c, void* g, naRef field, naRef* out);
+static void elementGhostSetMember(naContext c, void* g, naRef field, naRef value);
+naGhostType ElementGhostType = { elementGhostDestroy, "canvas.element", 
+    elementGhostGetMember, elementGhostSetMember };
+
+static const char* eventGhostGetMember(naContext c, void* g, naRef field, naRef* out);
+naGhostType EventGhostType = { eventGhostDestroy, "ga-event", eventGhostGetMember, 0 };
+
+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);
+}
+
+static naRef stringToNasal(naContext c, const std::string& s)
+{
+    return naStr_fromdata(naNewString(c),
+                   const_cast<char *>(s.c_str()), 
+                   s.length());
+}
+
+static naRef eventTypeToNasal(naContext c, osgGA::GUIEventAdapter::EventType ty)
+{
+  switch (ty) {
+  case osgGA::GUIEventAdapter::PUSH: return stringToNasal(c, "push");
+  case osgGA::GUIEventAdapter::RELEASE: return stringToNasal(c, "release");
+  case osgGA::GUIEventAdapter::DOUBLECLICK: return stringToNasal(c, "double-click");
+  case osgGA::GUIEventAdapter::DRAG: return stringToNasal(c, "drag");
+  case osgGA::GUIEventAdapter::MOVE: return stringToNasal(c, "move");
+  case osgGA::GUIEventAdapter::SCROLL: return stringToNasal(c, "scroll");
+  case osgGA::GUIEventAdapter::KEYUP: return stringToNasal(c, "key-up");
+  case osgGA::GUIEventAdapter::KEYDOWN: return stringToNasal(c, "key-down");
+
+  default:
+      ; // fall through
+  }
+  
+  return naNil();
+}
+
+static canvas::Element* elementGhost(naRef r)
+{
+  if (naGhost_type(r) == &ElementGhostType)
+    return (canvas::Element*) naGhost_ptr(r);
+  return 0;
+}
+
+static Canvas* canvasGhost(naRef r)
+{
+  if (naGhost_type(r) == &CanvasGhostType)
+    return (Canvas*) naGhost_ptr(r);
+  return 0;
+}
+
+static void elementGhostDestroy(void* g)
+{
+}
+
+static void canvasGhostDestroy(void* g)
+{
+}
+
+static void eventGhostDestroy(void* g)
+{
+    osgGA::GUIEventAdapter* gea = static_cast<osgGA::GUIEventAdapter*>(g);
+    gea->unref();
+}
+
+static const char* eventGhostGetMember(naContext c, void* g, naRef field, naRef* out)
+{
+  const char* fieldName = naStr_data(field);
+  osgGA::GUIEventAdapter* gea = (osgGA::GUIEventAdapter*) g;
+  
+  if (!strcmp(fieldName, "parents")) {
+    *out = naNewVector(c);
+    naVec_append(*out, eventPrototype);
+  } else if (!strcmp(fieldName, "type")) *out = eventTypeToNasal(c, gea->getEventType());
+  else if (!strcmp(fieldName, "windowX")) *out = naNum(gea->getWindowX());
+  else if (!strcmp(fieldName, "windowY")) *out = naNum(gea->getWindowY());
+  else if (!strcmp(fieldName, "time")) *out = naNum(gea->getTime());
+  else if (!strcmp(fieldName, "button")) *out = naNum(gea->getButton());
+  else {
+    return 0;
+  }
+  
+  return "";
+}
+
+static const char* canvasGhostGetMember(naContext c, void* g, naRef field, naRef* out)
+{
+  const char* fieldName = naStr_data(field);
+  Canvas* cvs = (Canvas*) g;
+  
+  if (!strcmp(fieldName, "parents")) {
+    *out = naNewVector(c);
+    naVec_append(*out, canvasPrototype);
+  } else if (!strcmp(fieldName, "sizeX")) *out = naNum(cvs->getSizeX());
+  else if (!strcmp(fieldName, "sizeY")) *out = naNum(cvs->getSizeY());
+  else {
+    return 0;
+  }
+  
+  return "";
+}
+
+static const char* elementGhostGetMember(naContext c, void* g, naRef field, naRef* out)
+{
+  const char* fieldName = naStr_data(field);
+  canvas::Element* e = (canvas::Element*) g;
+  
+  if (!strcmp(fieldName, "parents")) {
+    *out = naNewVector(c);
+    naVec_append(*out, elementPrototype);
+  } else {
+    return 0;
+  }
+  
+  return "";
+}
+
+static void elementGhostSetMember(naContext c, void* g, naRef field, naRef value)
+{
+  const char* fieldName = naStr_data(field);
+  canvas::Element* e = (canvas::Element*) g;
+}
+
+
+static naRef f_canvas_getElement(naContext c, naRef me, int argc, naRef* args)
+{
+  Canvas* cvs = canvasGhost(me);
+  if (!cvs) {
+    naRuntimeError(c, "canvas.getElement called on non-canvas object");
+  }
+  
+  return naNil();
+}
+
+static naRef f_element_addButtonCallback(naContext c, naRef me, int argc, naRef* args)
+{
+  canvas::Element* e = elementGhost(me);
+  if (!e) {
+    naRuntimeError(c, "element.addButtonCallback called on non-canvas-element object");
+  }
+  
+  return naNil();
+}
+
+static naRef f_element_addDragCallback(naContext c, naRef me, int argc, naRef* args)
+{
+  canvas::Element* e = elementGhost(me);
+  if (!e) {
+    naRuntimeError(c, "element.addDragCallback called on non-canvas-element object");
+  }
+  
+  return naNil();
+}
+
+static naRef f_element_addMoveCallback(naContext c, naRef me, int argc, naRef* args)
+{
+  canvas::Element* e = elementGhost(me);
+  if (!e) {
+    naRuntimeError(c, "element.addMoveCallback called on non-canvas-element object");
+  }
+  
+  return naNil();
+}
+
+static naRef f_element_addScrollCallback(naContext c, naRef me, int argc, naRef* args)
+{
+  canvas::Element* e = elementGhost(me);
+  if (!e) {
+    naRuntimeError(c, "element.addScrollCallback called on non-canvas-element object");
+  }
+  
+  return naNil();
+}
+
+static naRef f_canvas(naContext c, naRef me, int argc, naRef* args)
+{
+  return naNil();
+}
+
+// Table of extension functions.  Terminate with zeros.
+static struct { const char* name; naCFunction func; } funcs[] = {
+  { "canvas", f_canvas },
+  { 0, 0 }
+};
+
+naRef initNasalCanvas(naRef globals, naContext c, naRef gcSave)
+{
+    canvasPrototype = naNewHash(c);
+    hashset(c, gcSave, "canvasProto", canvasPrototype);
+  
+    hashset(c, canvasPrototype, "getElement", naNewFunc(c, naNewCCode(c, f_canvas_getElement)));
+    
+    eventPrototype = naNewHash(c);
+    hashset(c, gcSave, "eventProto", eventPrototype);
+    // set any event methods
+  
+    elementPrototype = naNewHash(c);
+    hashset(c, gcSave, "elementProto", elementPrototype);
+    
+    hashset(c, elementPrototype, "addButtonCallback", naNewFunc(c, naNewCCode(c, f_element_addButtonCallback)));
+    hashset(c, elementPrototype, "addDragCallback", naNewFunc(c, naNewCCode(c, f_element_addDragCallback)));
+    hashset(c, elementPrototype, "addMoveCallback", naNewFunc(c, naNewCCode(c, f_element_addMoveCallback)));
+    hashset(c, elementPrototype, "addScrollCallback", naNewFunc(c, naNewCCode(c, f_element_addScrollCallback)));
+      
+    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/NasalCanvas.hxx b/src/Scripting/NasalCanvas.hxx
new file mode 100644 (file)
index 0000000..c68fc04
--- /dev/null
@@ -0,0 +1,35 @@
+// NasalCanvas.hxx -- expose Canvas classes 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_CANVAS_HXX
+#define SCRIPTING_NASAL_CANVAS_HXX
+
+#include <simgear/nasal/nasal.h>
+
+// forward decls
+namespace canvas
+{
+    class Element;
+}
+
+naRef initNasalCanvas(naRef globals, naContext c, naRef gcSave);
+
+#endif // of SCRIPTING_NASAL_CANVAS_HXX
+
index b65264a8be78a87da896542044c9fa6c4f1c770d..a1de1e79452588230bf1838f29cd1f0e68533055 100644 (file)
@@ -27,6 +27,8 @@
 
 #include "NasalSys.hxx"
 #include "NasalPositioned.hxx"
+#include "NasalCanvas.hxx"
+
 #include <Main/globals.hxx>
 #include <Main/util.hxx>
 #include <Main/fg_props.hxx>
@@ -548,6 +550,7 @@ void FGNasalSys::init()
     hashset(_globals, "__gcsave", _gcHash);
 
     initNasalPositioned(_globals, _context, _gcHash);
+    initNasalCanvas(_globals, _context, _gcHash);
   
     // Now load the various source files in the Nasal directory
     simgear::Dir nasalDir(SGPath(globals->get_fg_root(), "Nasal"));