cppbind: More refactoring and finally getting rid of boost.preprocessor
This commit is contained in:
parent
5a72a7d9f4
commit
5f8f5a1c33
@ -189,10 +189,10 @@ namespace canvas
|
||||
if( hfw.empty() )
|
||||
return -1;
|
||||
|
||||
naContext c = naNewContext();
|
||||
try
|
||||
{
|
||||
return hfw(nasal::to_nasal(c, const_cast<NasalWidget*>(this)), w);
|
||||
nasal::Context ctx;
|
||||
return hfw(ctx.to_me(const_cast<NasalWidget*>(this)), w);
|
||||
}
|
||||
catch( std::exception const& ex )
|
||||
{
|
||||
@ -202,7 +202,6 @@ namespace canvas
|
||||
"NasalWidget.heightForWidth: callback error: '" << ex.what() << "'"
|
||||
);
|
||||
}
|
||||
naFreeContext(c);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -262,8 +261,8 @@ namespace canvas
|
||||
|
||||
try
|
||||
{
|
||||
nasal::Context c;
|
||||
_set_geometry(nasal::to_nasal(c, this), rect);
|
||||
nasal::Context ctx;
|
||||
_set_geometry(ctx.to_me(this), rect);
|
||||
_flags &= ~LAYOUT_DIRTY;
|
||||
}
|
||||
catch( std::exception const& ex )
|
||||
|
@ -1,10 +1,13 @@
|
||||
include (SimGearComponent)
|
||||
|
||||
set(HEADERS
|
||||
cppbind_fwd.hxx
|
||||
Ghost.hxx
|
||||
NasalCallContext.hxx
|
||||
NasalContext.hxx
|
||||
NasalHash.hxx
|
||||
NasalMe.hxx
|
||||
NasalMethodHolder.hxx
|
||||
NasalObject.hxx
|
||||
NasalObjectHolder.hxx
|
||||
NasalString.hxx
|
||||
@ -13,7 +16,6 @@ set(HEADERS
|
||||
)
|
||||
|
||||
set(DETAIL_HEADERS
|
||||
detail/from_nasal_function_templates.hxx
|
||||
detail/from_nasal_helper.hxx
|
||||
detail/nasal_traits.hxx
|
||||
detail/to_nasal_helper.hxx
|
||||
|
@ -56,6 +56,26 @@ namespace nasal
|
||||
return String(_ctx, str);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
naRef ContextWrapper::callMethod( Me me,
|
||||
naRef code,
|
||||
std::initializer_list<naRef> args )
|
||||
{
|
||||
naRef ret = naCallMethodCtx(
|
||||
_ctx,
|
||||
code,
|
||||
me,
|
||||
args.size(),
|
||||
const_cast<naRef*>(args.begin()),
|
||||
naNil() // locals
|
||||
);
|
||||
|
||||
if( const char* error = naGetError(_ctx) )
|
||||
throw std::runtime_error(error);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
naRef ContextWrapper::newVector(std::initializer_list<naRef> vals)
|
||||
{
|
||||
|
@ -19,13 +19,14 @@
|
||||
#ifndef SG_NASAL_CONTEXT_HXX_
|
||||
#define SG_NASAL_CONTEXT_HXX_
|
||||
|
||||
#include "from_nasal.hxx"
|
||||
#include "to_nasal.hxx"
|
||||
#include "cppbind_fwd.hxx"
|
||||
#include "NasalMe.hxx"
|
||||
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace nasal
|
||||
{
|
||||
class Hash;
|
||||
class String;
|
||||
|
||||
/**
|
||||
* Wraps a nasal ::naContext without taking ownership/managing its lifetime
|
||||
@ -63,12 +64,18 @@ namespace nasal
|
||||
return nasal::to_nasal(_ctx, arg);
|
||||
}
|
||||
|
||||
template<class T, size_t N>
|
||||
template<class T, std::size_t N>
|
||||
naRef to_nasal(const T(&array)[N]) const
|
||||
{
|
||||
return nasal::to_nasal(_ctx, array);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Me to_me(T arg) const
|
||||
{
|
||||
return Me{ to_nasal(arg) };
|
||||
}
|
||||
|
||||
template<class T>
|
||||
typename from_nasal_ptr<T>::return_type
|
||||
from_nasal(naRef ref) const
|
||||
@ -76,6 +83,21 @@ namespace nasal
|
||||
return (*from_nasal_ptr<T>::get())(_ctx, ref);
|
||||
}
|
||||
|
||||
naRef callMethod(Me me, naRef code, std::initializer_list<naRef> args);
|
||||
|
||||
template<class Ret, class... Args>
|
||||
Ret callMethod( Me me,
|
||||
naRef code,
|
||||
typename boost::call_traits<Args>::param_type ... args )
|
||||
{
|
||||
// TODO warn if with Ret == void something different to nil is returned?
|
||||
return from_nasal<Ret>(callMethod(
|
||||
me,
|
||||
code,
|
||||
{ to_nasal<typename boost::call_traits<Args>::param_type>(args)... }
|
||||
));
|
||||
}
|
||||
|
||||
protected:
|
||||
naContext _ctx;
|
||||
|
||||
@ -100,4 +122,7 @@ namespace nasal
|
||||
|
||||
} // namespace nasal
|
||||
|
||||
#include "from_nasal.hxx"
|
||||
#include "to_nasal.hxx"
|
||||
|
||||
#endif /* SG_NASAL_CONTEXT_HXX_ */
|
||||
|
44
simgear/nasal/cppbind/NasalMe.hxx
Normal file
44
simgear/nasal/cppbind/NasalMe.hxx
Normal file
@ -0,0 +1,44 @@
|
||||
///@file
|
||||
//
|
||||
// Copyright (C) 2018 Thomas Geymayer <tomgey@gmail.com>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
#ifndef SG_NASAL_ME_HXX_
|
||||
#define SG_NASAL_ME_HXX_
|
||||
|
||||
#include <simgear/nasal/nasal.h>
|
||||
|
||||
namespace nasal
|
||||
{
|
||||
|
||||
/**
|
||||
* Wrap a naRef to indicate it references the self/me object in Nasal method
|
||||
* calls.
|
||||
*/
|
||||
struct Me
|
||||
{
|
||||
naRef _ref;
|
||||
|
||||
explicit Me(naRef ref = naNil()):
|
||||
_ref(ref)
|
||||
{}
|
||||
|
||||
operator naRef() { return _ref; }
|
||||
};
|
||||
|
||||
} // namespace nasal
|
||||
|
||||
#endif /* SG_NASAL_ME_HXX_ */
|
75
simgear/nasal/cppbind/NasalMethodHolder.hxx
Normal file
75
simgear/nasal/cppbind/NasalMethodHolder.hxx
Normal file
@ -0,0 +1,75 @@
|
||||
///@file
|
||||
//
|
||||
// Copyright (C) 2018 Thomas Geymayer <tomgey@gmail.com>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
#ifndef SG_NASAL_METHOD_HOLDER_HXX_
|
||||
#define SG_NASAL_METHOD_HOLDER_HXX_
|
||||
|
||||
#include "NasalContext.hxx"
|
||||
#include "NasalObjectHolder.hxx"
|
||||
|
||||
namespace nasal
|
||||
{
|
||||
|
||||
/**
|
||||
* Hold any callable function in Nasal and call it from C++
|
||||
*/
|
||||
template<class Ret, class... Args>
|
||||
class NasalMethodHolder
|
||||
{
|
||||
using Holder = ObjectHolder<SGReferenced>;
|
||||
|
||||
public:
|
||||
NasalMethodHolder(naRef code):
|
||||
_code(Holder::makeShared(code))
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief Call the function with the given arguments
|
||||
*
|
||||
* If the first argument is nasal::Me it will be passed as 'me' object and
|
||||
* not as argument.
|
||||
*/
|
||||
Ret operator()(Args ... args)
|
||||
{
|
||||
return call(args...);
|
||||
}
|
||||
|
||||
private:
|
||||
Holder::Ref _code;
|
||||
|
||||
template<class... CArgs>
|
||||
Ret call(Me self, CArgs ... args)
|
||||
{
|
||||
nasal::Context ctx;
|
||||
return ctx.callMethod<Ret, CArgs...>(
|
||||
self,
|
||||
_code->get_naRef(),
|
||||
args...
|
||||
);
|
||||
}
|
||||
|
||||
template<class... CArgs>
|
||||
Ret call(CArgs ... args)
|
||||
{
|
||||
return call(Me{}, args...);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace nasal
|
||||
|
||||
#endif /* SG_NASAL_METHOD_HOLDER_HXX_ */
|
@ -52,11 +52,11 @@ namespace nasal
|
||||
return Ret();
|
||||
|
||||
Context ctx;
|
||||
auto func = get_member<boost::function<Ret (nasal::Me, Args...)>>(
|
||||
auto func = get_member<boost::function<Ret (Me, Args...)>>(
|
||||
ctx, _nasal_impl.get_naRef(), name
|
||||
);
|
||||
if( func )
|
||||
return func(nasal::to_nasal(ctx, this), args...);
|
||||
return func(Me(ctx.to_nasal(this)), args...);
|
||||
|
||||
return Ret();
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ namespace nasal
|
||||
{
|
||||
public:
|
||||
|
||||
using Ref = SGSharedPtr<ObjectHolder<Base>>;
|
||||
|
||||
/**
|
||||
* @param obj Object to save
|
||||
*/
|
||||
@ -84,7 +86,7 @@ namespace nasal
|
||||
*
|
||||
* @param obj Object to save
|
||||
*/
|
||||
static SGSharedPtr<ObjectHolder<Base> > makeShared(naRef obj);
|
||||
static Ref makeShared(naRef obj);
|
||||
|
||||
protected:
|
||||
naRef _ref;
|
||||
@ -155,10 +157,10 @@ namespace nasal
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<class Base>
|
||||
SGSharedPtr<ObjectHolder<Base> >
|
||||
typename ObjectHolder<Base>::Ref
|
||||
ObjectHolder<Base>::makeShared(naRef obj)
|
||||
{
|
||||
return SGSharedPtr<ObjectHolder<Base> >( new ObjectHolder<Base>(obj) );
|
||||
return Ref( new ObjectHolder<Base>(obj) );
|
||||
}
|
||||
|
||||
} // namespace nasal
|
||||
|
54
simgear/nasal/cppbind/cppbind_fwd.hxx
Normal file
54
simgear/nasal/cppbind/cppbind_fwd.hxx
Normal file
@ -0,0 +1,54 @@
|
||||
///@file
|
||||
/// Nasal C++ Bindings forward declarations
|
||||
///
|
||||
// Copyright (C) 2018 Thomas Geymayer <tomgey@gmail.com>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
#ifndef SG_NASAL_CPPBIND_FWD_HXX_
|
||||
#define SG_NASAL_CPPBIND_FWD_HXX_
|
||||
|
||||
#include <simgear/nasal/nasal.h>
|
||||
#include <cstddef>
|
||||
|
||||
namespace nasal
|
||||
{
|
||||
|
||||
class CallContext;
|
||||
class Context;
|
||||
class ContextWrapper;
|
||||
class Hash;
|
||||
class Me;
|
||||
class Object;
|
||||
class String;
|
||||
|
||||
template<class, class>
|
||||
class Ghost;
|
||||
|
||||
template<class T>
|
||||
naRef to_nasal(naContext c, T arg);
|
||||
|
||||
template<class T, std::size_t N>
|
||||
naRef to_nasal(naContext c, const T(&array)[N]);
|
||||
|
||||
template<class T>
|
||||
T from_nasal(naContext c, naRef ref);
|
||||
|
||||
template<class Var>
|
||||
struct from_nasal_ptr;
|
||||
|
||||
} // namespace nasal
|
||||
|
||||
#endif /* SG_NASAL_CPPBIND_FWD_HXX_ */
|
@ -1,131 +0,0 @@
|
||||
#ifndef SG_FROM_NASAL_HELPER_HXX_
|
||||
# error Nasal cppbind - do not include this file!
|
||||
#endif
|
||||
|
||||
#ifndef SG_DONT_DO_ANYTHING
|
||||
#define n BOOST_PP_ITERATION()
|
||||
|
||||
#ifndef SG_BOOST_FUNCTION_FROM_NASAL_FWD
|
||||
# define SG_CALL_TRAITS_PARAM(z, n, dummy)\
|
||||
typename boost::call_traits<A##n>::param_type a##n
|
||||
# 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)
|
||||
>
|
||||
typename boost::disable_if<boost::is_void<Ret>, Ret>::type
|
||||
callNasalMethod( const ObjectHolder<SGReferenced>* holder,
|
||||
Me self
|
||||
BOOST_PP_ENUM_TRAILING(n, SG_CALL_TRAITS_PARAM, 0) )
|
||||
{
|
||||
naContext ctx = naNewContext();
|
||||
#if n
|
||||
naRef args[n] = {
|
||||
BOOST_PP_ENUM(n, SG_CALL_ARG, 0)
|
||||
};
|
||||
#else
|
||||
naRef* args = NULL;
|
||||
#endif
|
||||
|
||||
naRef result =
|
||||
naCallMethodCtx(ctx, holder->get_naRef(), self, n, args, naNil());
|
||||
|
||||
const char* error = naGetError(ctx);
|
||||
std::string error_str(error ? error : "");
|
||||
|
||||
Ret r = Ret();
|
||||
if( !error )
|
||||
r = from_nasal_helper(ctx, result, static_cast<Ret*>(0));
|
||||
|
||||
naFreeContext(ctx);
|
||||
|
||||
if( error )
|
||||
throw std::runtime_error(error_str);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
template<
|
||||
class Ret
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)
|
||||
>
|
||||
typename boost::enable_if<boost::is_void<Ret>, Ret>::type
|
||||
callNasalMethod( const ObjectHolder<SGReferenced>* holder,
|
||||
Me self
|
||||
BOOST_PP_ENUM_TRAILING(n, SG_CALL_TRAITS_PARAM, 0) )
|
||||
{
|
||||
callNasalMethod<
|
||||
naRef // do not do any conversion and just ignore the return value
|
||||
// TODO warn if something different to nil is returned?
|
||||
BOOST_PP_COMMA_IF(n)
|
||||
BOOST_PP_ENUM_PARAMS(n, A)
|
||||
>
|
||||
(
|
||||
holder,
|
||||
self
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS(n, a)
|
||||
);
|
||||
}
|
||||
|
||||
# undef SG_CALL_TRAITS_PARAM
|
||||
# undef SG_CALL_ARG
|
||||
#endif
|
||||
|
||||
template<
|
||||
class Ret
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)
|
||||
>
|
||||
typename boost::disable_if<
|
||||
// free function if first argument is not nasal::Me or no argument at all
|
||||
boost::is_same<BOOST_PP_IF(n, A0, void), Me>,
|
||||
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, A))>
|
||||
>::type
|
||||
boostFunctionFromNasal(naRef code, Ret (*)(BOOST_PP_ENUM_PARAMS(n, A)))
|
||||
#ifdef SG_BOOST_FUNCTION_FROM_NASAL_FWD
|
||||
;
|
||||
#else
|
||||
{
|
||||
return boost::bind
|
||||
(
|
||||
&callNasalMethod<Ret BOOST_PP_ENUM_TRAILING_PARAMS(n, A)>,
|
||||
ObjectHolder<SGReferenced>::makeShared(code),
|
||||
boost::bind(naNil)
|
||||
BOOST_PP_COMMA_IF(n)
|
||||
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(n), _)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if n > 0
|
||||
template<
|
||||
class Ret
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)
|
||||
>
|
||||
typename boost::enable_if<
|
||||
// method if type of first argument is nasal::Me
|
||||
boost::is_same<A0, Me>,
|
||||
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, A))>
|
||||
>::type
|
||||
boostFunctionFromNasal(naRef code, Ret (*)(BOOST_PP_ENUM_PARAMS(n, A)))
|
||||
#ifdef SG_BOOST_FUNCTION_FROM_NASAL_FWD
|
||||
;
|
||||
#else
|
||||
{
|
||||
return boost::bind
|
||||
(
|
||||
&callNasalMethod<
|
||||
Ret
|
||||
BOOST_PP_COMMA_IF(BOOST_PP_DEC(n))
|
||||
BOOST_PP_ENUM_SHIFTED_PARAMS(n, A)
|
||||
>,
|
||||
ObjectHolder<SGReferenced>::makeShared(code),
|
||||
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(n), _)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef n
|
||||
#endif // SG_DONT_DO_ANYTHING
|
@ -24,20 +24,15 @@
|
||||
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
#include <simgear/math/SGRect.hxx>
|
||||
#include <simgear/nasal/nasal.h>
|
||||
#include <simgear/nasal/cppbind/NasalContext.hxx>
|
||||
#include <simgear/nasal/cppbind/NasalMe.hxx>
|
||||
#include <simgear/nasal/cppbind/NasalMethodHolder.hxx>
|
||||
#include <simgear/nasal/cppbind/NasalObjectHolder.hxx>
|
||||
#include <simgear/nasal/cppbind/to_nasal.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
#include <simgear/structure/SGSharedPtr.hxx>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/preprocessor/control/if.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
@ -76,27 +71,19 @@ namespace nasal
|
||||
std::string _msg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wrap a naRef to indicate it references the self/me object in Nasal method
|
||||
* calls.
|
||||
*/
|
||||
struct Me
|
||||
{
|
||||
naRef _ref;
|
||||
|
||||
Me(naRef ref = naNil()):
|
||||
_ref(ref)
|
||||
{}
|
||||
|
||||
operator naRef() { return _ref; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple pass through for unified handling also of naRef.
|
||||
*/
|
||||
inline naRef from_nasal_helper(naContext, naRef ref, const naRef*)
|
||||
{ return ref; }
|
||||
|
||||
/**
|
||||
* Ignore return value
|
||||
*/
|
||||
// TODO show some warning when something is returned but ignored?
|
||||
inline void from_nasal_helper(naContext, naRef, const void*)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Convert Nasal string to std::string
|
||||
*/
|
||||
@ -125,43 +112,33 @@ namespace nasal
|
||||
*/
|
||||
bool from_nasal_helper(naContext c, naRef ref, const bool*);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
#define SG_BOOST_FUNCTION_FROM_NASAL_FWD
|
||||
#define BOOST_PP_ITERATION_LIMITS (0, 9)
|
||||
#define BOOST_PP_FILENAME_1 <simgear/nasal/cppbind/detail/from_nasal_function_templates.hxx>
|
||||
#include BOOST_PP_ITERATE()
|
||||
#undef SG_BOOST_FUNCTION_FROM_NASAL_FWD
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a Nasal function to a boost::function with the given signature.
|
||||
*
|
||||
* @tparam Sig Signature of returned function (arguments and return value
|
||||
* are automatically converted using from_nasal/to_nasal)
|
||||
*/
|
||||
template<class Sig>
|
||||
boost::function<Sig>
|
||||
from_nasal_helper(naContext c, naRef ref, boost::function<Sig>*)
|
||||
template<class Ret, class... Args>
|
||||
boost::function<Ret (Args...)>
|
||||
from_nasal_helper(naContext c, naRef ref, const boost::function<Ret (Args...)>*)
|
||||
{
|
||||
if( naIsNil(ref) )
|
||||
return boost::function<Sig>();
|
||||
return {};
|
||||
|
||||
if( !naIsCode(ref)
|
||||
&& !naIsCCode(ref)
|
||||
&& !naIsFunc(ref) )
|
||||
throw bad_nasal_cast("not a function");
|
||||
|
||||
return detail::boostFunctionFromNasal(ref, static_cast<Sig*>(0));
|
||||
return NasalMethodHolder<Ret, Args...>(ref);
|
||||
}
|
||||
|
||||
template<class Sig>
|
||||
typename boost::enable_if< boost::is_function<Sig>,
|
||||
boost::function<Sig>
|
||||
>::type
|
||||
from_nasal_helper(naContext c, naRef ref, Sig*)
|
||||
template<class Ret, class... Args>
|
||||
boost::function<Ret (Args...)>
|
||||
from_nasal_helper(naContext c, naRef ref, Ret (*const)(Args...))
|
||||
{
|
||||
return from_nasal_helper(c, ref, static_cast<boost::function<Sig>*>(0));
|
||||
return
|
||||
from_nasal_helper(c, ref, static_cast<boost::function<Ret (Args...)>*>(0));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -227,21 +204,6 @@ namespace nasal
|
||||
return SGRect<T>(vec[0], vec[1], vec[2], vec[3]);
|
||||
}
|
||||
|
||||
// Helpers for wrapping calls to Nasal functions into boost::function
|
||||
namespace detail
|
||||
{
|
||||
// Dummy include to add a build dependency on this file for gcc/CMake/etc.
|
||||
#define SG_DONT_DO_ANYTHING
|
||||
# include <simgear/nasal/cppbind/detail/from_nasal_function_templates.hxx>
|
||||
#undef SG_DONT_DO_ANYTHING
|
||||
|
||||
// Now the actual include (we are limited to 8 arguments (+me) here because
|
||||
// boost::bind has an upper limit of 9)
|
||||
#define BOOST_PP_ITERATION_LIMITS (0, 8)
|
||||
#define BOOST_PP_FILENAME_1 <simgear/nasal/cppbind/detail/from_nasal_function_templates.hxx>
|
||||
#include BOOST_PP_ITERATE()
|
||||
}
|
||||
|
||||
} // namespace nasal
|
||||
|
||||
#endif /* SG_FROM_NASAL_HELPER_HXX_ */
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define SG_FROM_NASAL_HXX_
|
||||
|
||||
#include <simgear/nasal/cppbind/detail/from_nasal_helper.hxx>
|
||||
#include <type_traits>
|
||||
|
||||
namespace nasal
|
||||
{
|
||||
@ -52,8 +53,8 @@ namespace nasal
|
||||
template<class Var>
|
||||
struct from_nasal_ptr
|
||||
{
|
||||
typedef typename boost::remove_const
|
||||
< typename boost::remove_reference<Var>::type
|
||||
typedef typename std::remove_const
|
||||
< typename std::remove_reference<Var>::type
|
||||
>::type return_type;
|
||||
typedef return_type(*type)(naContext, naRef);
|
||||
|
||||
|
@ -42,7 +42,7 @@ class TestContext:
|
||||
template<class T = naRef>
|
||||
T exec(const std::string& code)
|
||||
{
|
||||
return from_nasal<T>(execImpl(code, {}));
|
||||
return from_nasal<T>(execImpl(code, nasal::Me{}));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
@ -218,7 +218,7 @@ BOOST_AUTO_TEST_CASE( cppbind_misc_testing )
|
||||
// passed on to function
|
||||
typedef boost::function<int (Me, int)> MeIntFunc;
|
||||
MeIntFunc fmeint = hash.get<MeIntFunc>("func");
|
||||
BOOST_CHECK_EQUAL(fmeint(naNil(), 5), 5);
|
||||
BOOST_CHECK_EQUAL(fmeint(Me{}, 5), 5);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Test exposing classes to Nasal
|
||||
@ -292,7 +292,7 @@ BOOST_AUTO_TEST_CASE( cppbind_misc_testing )
|
||||
typedef boost::function<unsigned long (Me)> MemFunc;
|
||||
MemFunc fGetThis = c.from_nasal<MemFunc>(thisGetter);
|
||||
BOOST_REQUIRE( fGetThis );
|
||||
BOOST_CHECK_EQUAL( fGetThis(derived), (unsigned long)d.get() );
|
||||
BOOST_CHECK_EQUAL( fGetThis(Me{derived}), (unsigned long)d.get() );
|
||||
|
||||
BasePtr d2( new DoubleDerived );
|
||||
derived = c.to_nasal(d2);
|
||||
@ -369,10 +369,10 @@ BOOST_AUTO_TEST_CASE( cppbind_misc_testing )
|
||||
BOOST_CHECK_EQUAL( objects[2], d3 );
|
||||
|
||||
// Calling fallback setter for unset values
|
||||
BOOST_CHECK_EQUAL( c.exec<int>("me.test = 3;", derived), 3 );
|
||||
BOOST_CHECK_EQUAL( c.exec<int>("me.test = 3;", Me{derived}), 3 );
|
||||
|
||||
// Calling generic (fallback) getter
|
||||
BOOST_CHECK_EQUAL( c.exec<std::string>("var a = me.get_test;", derived),
|
||||
BOOST_CHECK_EQUAL( c.exec<std::string>("var a = me.get_test;", Me{derived}),
|
||||
"generic-get" );
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -218,13 +218,13 @@ BOOST_AUTO_TEST_CASE( bind_methods )
|
||||
TestContext ctx;
|
||||
auto test = boost::make_shared<TestClass>();
|
||||
|
||||
ctx.exec("me.set(1, \"s2\", \"s3\", 4);", ctx.to_nasal(test));
|
||||
ctx.exec("me.set(1, \"s2\", \"s3\", 4);", ctx.to_me(test));
|
||||
BOOST_CHECK_EQUAL(test->arg1, 1);
|
||||
BOOST_CHECK_EQUAL(test->arg2, "s2");
|
||||
BOOST_CHECK_EQUAL(test->arg3, "s3");
|
||||
BOOST_CHECK_EQUAL(test->arg4, 4);
|
||||
|
||||
ctx.exec("me.setReverse(1, \"s2\", \"s3\", 4);", ctx.to_nasal(test));
|
||||
ctx.exec("me.setReverse(1, \"s2\", \"s3\", 4);", ctx.to_me(test));
|
||||
BOOST_CHECK_EQUAL(test->arg1, 4);
|
||||
BOOST_CHECK_EQUAL(test->arg2, "s3");
|
||||
BOOST_CHECK_EQUAL(test->arg3, "s2");
|
||||
|
Loading…
Reference in New Issue
Block a user