]> git.mxchange.org Git - simgear.git/commitdiff
cppbind: helper to call Nasal methods on NasalWidget.
authorThomas Geymayer <tomgey@gmail.com>
Sun, 20 Jul 2014 22:19:31 +0000 (00:19 +0200)
committerThomas Geymayer <tomgey@gmail.com>
Sun, 20 Jul 2014 22:22:15 +0000 (00:22 +0200)
simgear/canvas/layout/NasalWidget.cxx
simgear/nasal/cppbind/CMakeLists.txt
simgear/nasal/cppbind/Ghost.hxx
simgear/nasal/cppbind/NasalCallContext.hxx
simgear/nasal/cppbind/NasalObject.hxx
simgear/nasal/cppbind/cppbind_test.cxx
simgear/nasal/cppbind/detail/NasalObject_callMethod_templates.hxx [new file with mode: 0644]
simgear/nasal/cppbind/detail/to_nasal_helper.cxx
simgear/nasal/cppbind/nasal_num_test.cxx

index 9d31a4559e30a79b66560b85f699e4bcac846d1b..01d3f55af2e30f179cbf2e8ebd242afdc42ffb10 100644 (file)
@@ -84,18 +84,9 @@ namespace canvas
   //----------------------------------------------------------------------------
   void NasalWidget::onRemove()
   {
-    if( !_nasal_impl.valid() )
-      return;
-
-    typedef boost::function<void(nasal::Me)> Deleter;
-
-    naContext c = naNewContext();
     try
     {
-      Deleter del =
-        nasal::get_member<Deleter>(c, _nasal_impl.get_naRef(), "onRemove");
-      if( del )
-        del(nasal::to_nasal(c, this));
+      callMethod<void>("onRemove");
     }
     catch( std::exception const& ex )
     {
@@ -105,7 +96,6 @@ namespace canvas
         "NasalWidget::onRemove: callback error: '" << ex.what() << "'"
       );
     }
-    naFreeContext(c);
   }
 
   //----------------------------------------------------------------------------
index de6eece6f0b7420ea4e73e3c054099203263ad8b..e9e9e581e9c5b8d1b8942674b8a0b486bed2ad3b 100644 (file)
@@ -17,6 +17,7 @@ set(DETAIL_HEADERS
   detail/from_nasal_helper.hxx
   detail/functor_templates.hxx
   detail/nasal_traits.hxx
+  detail/NasalObject_callMethod_templates.hxx
   detail/to_nasal_helper.hxx
 )
 
index 1a02e3676f45f8a9930b2756d917556e096407bc..84a655ccc4cc112d5c1aba24abc3bb9fe10a69fa 100644 (file)
@@ -322,7 +322,7 @@ namespace nasal
               return holder->_method
               (
                 *get_pointer(ref),
-                CallContext(c, argc, args)
+                CallContext(c, me, argc, args)
               );
             }
             catch(const std::exception& ex)
index 574fe59edc4a23e7e5e51a94ab9b70bbe5d5a40f..ea4e1967ef144e5f62050c53178c05577bc1d186 100644 (file)
@@ -32,8 +32,9 @@ namespace nasal
   class CallContext
   {
     public:
-      CallContext(naContext c, size_t argc, naRef* args):
+      CallContext(naContext c, naRef me, size_t argc, naRef* args):
         c(c),
+        me(me),
         argc(argc),
         args(args)
       {}
@@ -120,6 +121,7 @@ namespace nasal
       }
 
       naContext   c;
+      naRef       me;
       size_t      argc;
       naRef      *args;
   };
index d1ed920da25d2996c69642a9ca014eab096591f5..4ee850293f3d00874e27ea394ed250917afb53e1 100644 (file)
 #ifndef SG_NASAL_OBJECT_HXX_
 #define SG_NASAL_OBJECT_HXX_
 
+#include "NasalContext.hxx"
 #include "NasalObjectHolder.hxx"
 #include "Ghost.hxx"
 
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+
 namespace nasal
 {
   class Object:
@@ -41,6 +45,15 @@ namespace nasal
 
       bool valid() const;
 
+      // Build dependency for CMake, gcc, etc.
+#define SG_DONT_DO_ANYTHING
+# include <simgear/nasal/cppbind/detail/NasalObject_callMethod_templates.hxx>
+#undef SG_DONT_DO_ANYTHING
+
+#define BOOST_PP_ITERATION_LIMITS (0, 9)
+#define BOOST_PP_FILENAME_1 <simgear/nasal/cppbind/detail/NasalObject_callMethod_templates.hxx>
+#include BOOST_PP_ITERATE()
+
       bool _set(naContext c, const std::string& key, naRef val);
       bool _get(naContext c, const std::string& key, naRef& out);
 
index c3b794c8e2d8bfc0d561cdd70a4ded00d401f804..86de6d4de39eed27e4dc552f6c4daedcf6efc60a 100644 (file)
@@ -417,7 +417,7 @@ int main(int argc, char* argv[])
     to_nasal(c, int_vec),
     to_nasal(c, map)
   };
-  CallContext cc(c, sizeof(args)/sizeof(args[0]), args);
+  CallContext cc(c, naNil(), sizeof(args)/sizeof(args[0]), args);
   VERIFY( cc.requireArg<std::string>(0) == "test-arg" );
   VERIFY( cc.getArg<std::string>(0) == "test-arg" );
   VERIFY( cc.getArg<std::string>(10) == "" );
diff --git a/simgear/nasal/cppbind/detail/NasalObject_callMethod_templates.hxx b/simgear/nasal/cppbind/detail/NasalObject_callMethod_templates.hxx
new file mode 100644 (file)
index 0000000..41dd9fd
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef SG_NASAL_OBJECT_HXX_
+# error Nasal cppbind - do not include this file!
+#endif
+
+#ifndef SG_DONT_DO_ANYTHING
+#define n BOOST_PP_ITERATION()
+
+#define SG_CALL_ARG(z, n, dummy)\
+      to_nasal<typename boost::call_traits<A##n>::param_type>(ctx, a##n)
+
+  template<
+    class Ret
+    BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)
+  >
+  Ret callMethod( const std::string& name
+                  BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(n, A, a) )
+  {
+    if( !_nasal_impl.valid() )
+      return Ret();
+
+    typedef boost::function<Ret (nasal::Me BOOST_PP_ENUM_TRAILING_PARAMS(n, A))>
+            MemFunc;
+
+    Context ctx;
+    MemFunc f = get_member<MemFunc>(ctx, _nasal_impl.get_naRef(), name.c_str());
+    if( f )
+      return f(nasal::to_nasal(ctx, this) BOOST_PP_ENUM_TRAILING_PARAMS(n, a));
+
+    return Ret();
+  }
+
+#undef SG_CALL_ARG
+
+#undef n
+#endif // SG_DONT_DO_ANYTHING
index 5c877e47dd36f4f5ca988ccd7ce55dcfe02f74c6..13de1913eab5806d6299d8c79373540e5ade577c 100644 (file)
@@ -87,7 +87,7 @@ namespace nasal
 
     try
     {
-      return (*func)(nasal::CallContext(c, argc, args));
+      return (*func)(nasal::CallContext(c, me, argc, args));
     }
     catch(const std::exception& ex)
     {
index 0f06a872034f29c39c2d5c01b4238811433775e2..e1e7dd0fcdcc204b34154083ed184573529899d6 100644 (file)
@@ -8,7 +8,7 @@ class TestContext:
 {
   public:
     TestContext():
-      CallContext(naNewContext(), 0, 0)
+      CallContext(naNewContext(), naNil(), 0, 0)
     {}
 
     ~TestContext()