From e71d6b24d721545be085394788597512dfe6ae9e Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Mon, 21 Jul 2014 00:19:31 +0200 Subject: [PATCH] cppbind: helper to call Nasal methods on NasalWidget. --- simgear/canvas/layout/NasalWidget.cxx | 12 +------ simgear/nasal/cppbind/CMakeLists.txt | 1 + simgear/nasal/cppbind/Ghost.hxx | 2 +- simgear/nasal/cppbind/NasalCallContext.hxx | 4 ++- simgear/nasal/cppbind/NasalObject.hxx | 13 +++++++ simgear/nasal/cppbind/cppbind_test.cxx | 2 +- .../NasalObject_callMethod_templates.hxx | 35 +++++++++++++++++++ .../nasal/cppbind/detail/to_nasal_helper.cxx | 2 +- simgear/nasal/cppbind/nasal_num_test.cxx | 2 +- 9 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 simgear/nasal/cppbind/detail/NasalObject_callMethod_templates.hxx diff --git a/simgear/canvas/layout/NasalWidget.cxx b/simgear/canvas/layout/NasalWidget.cxx index 9d31a455..01d3f55a 100644 --- a/simgear/canvas/layout/NasalWidget.cxx +++ b/simgear/canvas/layout/NasalWidget.cxx @@ -84,18 +84,9 @@ namespace canvas //---------------------------------------------------------------------------- void NasalWidget::onRemove() { - if( !_nasal_impl.valid() ) - return; - - typedef boost::function Deleter; - - naContext c = naNewContext(); try { - Deleter del = - nasal::get_member(c, _nasal_impl.get_naRef(), "onRemove"); - if( del ) - del(nasal::to_nasal(c, this)); + callMethod("onRemove"); } catch( std::exception const& ex ) { @@ -105,7 +96,6 @@ namespace canvas "NasalWidget::onRemove: callback error: '" << ex.what() << "'" ); } - naFreeContext(c); } //---------------------------------------------------------------------------- diff --git a/simgear/nasal/cppbind/CMakeLists.txt b/simgear/nasal/cppbind/CMakeLists.txt index de6eece6..e9e9e581 100644 --- a/simgear/nasal/cppbind/CMakeLists.txt +++ b/simgear/nasal/cppbind/CMakeLists.txt @@ -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 ) diff --git a/simgear/nasal/cppbind/Ghost.hxx b/simgear/nasal/cppbind/Ghost.hxx index 1a02e367..84a655cc 100644 --- a/simgear/nasal/cppbind/Ghost.hxx +++ b/simgear/nasal/cppbind/Ghost.hxx @@ -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) diff --git a/simgear/nasal/cppbind/NasalCallContext.hxx b/simgear/nasal/cppbind/NasalCallContext.hxx index 574fe59e..ea4e1967 100644 --- a/simgear/nasal/cppbind/NasalCallContext.hxx +++ b/simgear/nasal/cppbind/NasalCallContext.hxx @@ -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; }; diff --git a/simgear/nasal/cppbind/NasalObject.hxx b/simgear/nasal/cppbind/NasalObject.hxx index d1ed920d..4ee85029 100644 --- a/simgear/nasal/cppbind/NasalObject.hxx +++ b/simgear/nasal/cppbind/NasalObject.hxx @@ -19,9 +19,13 @@ #ifndef SG_NASAL_OBJECT_HXX_ #define SG_NASAL_OBJECT_HXX_ +#include "NasalContext.hxx" #include "NasalObjectHolder.hxx" #include "Ghost.hxx" +#include +#include + 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 +#undef SG_DONT_DO_ANYTHING + +#define BOOST_PP_ITERATION_LIMITS (0, 9) +#define BOOST_PP_FILENAME_1 +#include BOOST_PP_ITERATE() + bool _set(naContext c, const std::string& key, naRef val); bool _get(naContext c, const std::string& key, naRef& out); diff --git a/simgear/nasal/cppbind/cppbind_test.cxx b/simgear/nasal/cppbind/cppbind_test.cxx index c3b794c8..86de6d4d 100644 --- a/simgear/nasal/cppbind/cppbind_test.cxx +++ b/simgear/nasal/cppbind/cppbind_test.cxx @@ -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(0) == "test-arg" ); VERIFY( cc.getArg(0) == "test-arg" ); VERIFY( cc.getArg(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 index 00000000..41dd9fd4 --- /dev/null +++ b/simgear/nasal/cppbind/detail/NasalObject_callMethod_templates.hxx @@ -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::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 + MemFunc; + + Context ctx; + MemFunc f = get_member(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 diff --git a/simgear/nasal/cppbind/detail/to_nasal_helper.cxx b/simgear/nasal/cppbind/detail/to_nasal_helper.cxx index 5c877e47..13de1913 100644 --- a/simgear/nasal/cppbind/detail/to_nasal_helper.cxx +++ b/simgear/nasal/cppbind/detail/to_nasal_helper.cxx @@ -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) { diff --git a/simgear/nasal/cppbind/nasal_num_test.cxx b/simgear/nasal/cppbind/nasal_num_test.cxx index 0f06a872..e1e7dd0f 100644 --- a/simgear/nasal/cppbind/nasal_num_test.cxx +++ b/simgear/nasal/cppbind/nasal_num_test.cxx @@ -8,7 +8,7 @@ class TestContext: { public: TestContext(): - CallContext(naNewContext(), 0, 0) + CallContext(naNewContext(), naNil(), 0, 0) {} ~TestContext()