cppbind: helper to call Nasal methods on NasalWidget.

This commit is contained in:
Thomas Geymayer 2014-07-21 00:19:31 +02:00
parent 726a4c6d10
commit e71d6b24d7
9 changed files with 57 additions and 16 deletions

View 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);
}
//----------------------------------------------------------------------------

View 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
)

View 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)

View 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;
};

View File

@ -19,9 +19,13 @@
#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);

View 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) == "" );

View File

@ -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

View 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)
{

View File

@ -8,7 +8,7 @@ class TestContext:
{
public:
TestContext():
CallContext(naNewContext(), 0, 0)
CallContext(naNewContext(), naNil(), 0, 0)
{}
~TestContext()