]> git.mxchange.org Git - simgear.git/blobdiff - simgear/nasal/cppbind/Ghost.hxx
First working version of DOM like Canvas event handling
[simgear.git] / simgear / nasal / cppbind / Ghost.hxx
index 6fce4cbc74b1171172893f259f57887ded536a2c..d2a5d22c9906b80610750537961cb6f4720706ad 100644 (file)
@@ -26,6 +26,7 @@
 #include <simgear/debug/logstream.hxx>
 
 #include <boost/bind.hpp>
+#include <boost/call_traits.hpp>
 #include <boost/function.hpp>
 #include <boost/lambda/lambda.hpp>
 #include <boost/utility/enable_if.hpp>
@@ -223,14 +224,44 @@ namespace nasal
    */
   struct CallContext
   {
-    CallContext(naContext c, int argc, naRef* args):
+    CallContext(naContext c, size_t argc, naRef* args):
       c(c),
       argc(argc),
       args(args)
     {}
 
+    /**
+     * Get the argument with given index if it exists. Otherwise returns the
+     * passed default value.
+     *
+     * @tparam T    Type of argument (converted using ::from_nasal)
+     * @param index Index of requested argument
+     * @param def   Default value returned if too few arguments available
+     */
+    template<class T>
+    T getArg(size_t index, const T& def = T()) const
+    {
+      if( index >= argc )
+        return def;
+
+      return from_nasal<T>(c, args[index]);
+    }
+
+    /**
+     * Get the argument with given index. Raises a Nasal runtime error if there
+     * are to few arguments available.
+     */
+    template<class T>
+    T requireArg(size_t index) const
+    {
+      if( index >= argc )
+        naRuntimeError(c, "Missing required arg #%d", index);
+
+      return from_nasal<T>(c, args[index]);
+    }
+
     naContext   c;
-    int         argc;
+    size_t      argc;
     naRef      *args;
   };
 
@@ -427,12 +458,13 @@ namespace nasal
       template<class Var>
       Ghost& member( const std::string& field,
                      Var (raw_type::*getter)() const,
-                     void (raw_type::*setter)(Var) = 0 )
+                     void (raw_type::*setter)(typename boost::call_traits<Var>::param_type) = 0 )
       {
         member_t m;
         if( getter )
         {
-          naRef (*to_nasal_)(naContext, Var) = &nasal::to_nasal;
+          typedef typename boost::call_traits<Var>::param_type param_type;
+          naRef (*to_nasal_)(naContext, param_type) = &nasal::to_nasal;
 
           // Getter signature: naRef(naContext, raw_type&)
           m.getter = boost::bind(to_nasal_, _1, boost::bind(getter, _2));
@@ -598,7 +630,6 @@ namespace nasal
           return Ghost::getPtr( naGhost_ptr(me) );
 
         // Now if it is derived from a ghost (hash with ghost in parent vector)
-        // TODO handle recursive parents
         else if( naIsHash(me) )
         {
           naRef na_parents = naHash_cget(me, const_cast<char*>("parents"));
@@ -614,8 +645,9 @@ namespace nasal
                                       parent != parents.end();
                                     ++parent )
           {
-            if( isBaseOf(naGhost_type(*parent)) )
-              return Ghost::getPtr( naGhost_ptr(*parent) );
+            pointer ptr = fromNasal(c, *parent);
+            if( ptr )
+              return ptr;
           }
         }