Update EngineAPI, use fixed_tuple as main underlying data structure

This also fixes a few issues related to type conversions before data is sent to the engine function.
Squash
This commit is contained in:
Lukas Joergensen 2019-08-03 13:41:02 +02:00 committed by Lukas Aldershaab
parent 4eabbd5bb0
commit 6a9c09f145
3 changed files with 79 additions and 71 deletions

View file

@ -26,6 +26,7 @@
namespace Con namespace Con
{ {
/* Consumer Callback is not defined as EngineType yet, until then we have to define these methods directly.
DefineNewEngineFunction(AddConsumer, void, (ConsumerCallback cb), , "") DefineNewEngineFunction(AddConsumer, void, (ConsumerCallback cb), , "")
{ {
addConsumer(cb); addConsumer(cb);
@ -35,6 +36,17 @@ namespace Con
{ {
removeConsumer(cb); removeConsumer(cb);
} }
*/
TORQUE_API void fnAddConsumer(ConsumerCallback cb)
{
addConsumer(cb);
}
TORQUE_API void fnRemoveConsumer(ConsumerCallback cb)
{
removeConsumer(cb);
}
DefineNewEngineFunction(GetConsoleString, String, (String name),, "") DefineNewEngineFunction(GetConsoleString, String, (String name),, "")
{ {
@ -75,4 +87,4 @@ namespace Con
{ {
setBoolVariable(StringTable->insert(name), value); setBoolVariable(StringTable->insert(name), value);
} }
} }

View file

@ -335,10 +335,9 @@ template<typename T> struct _EngineTrampoline {
template< typename R, typename ...ArgTs > template< typename R, typename ...ArgTs >
struct _EngineTrampoline< R( ArgTs ... ) > struct _EngineTrampoline< R( ArgTs ... ) >
{ {
typedef std::tuple<ArgTs ...> Args; template<typename T> using AVT = typename EngineTypeTraits<T>::ArgumentValueType;
std::tuple<ArgTs ...> argT; typedef fixed_tuple<AVT<ArgTs> ...> Args;
typedef fixed_tuple<ArgTs ...> FixedArgs; Args argT;
fixed_tuple<ArgTs ...> fixedArgT;
}; };
template< typename T > template< typename T >
@ -356,21 +355,21 @@ struct _EngineFunctionTrampoline< R(ArgTs...) > : public _EngineFunctionTrampoli
{ {
private: private:
using Super = _EngineFunctionTrampolineBase< R(ArgTs...) >; using Super = _EngineFunctionTrampolineBase< R(ArgTs...) >;
using ArgsType = typename Super::Args; using SelfType = _EngineFunctionTrampoline< R(ArgTs...) >;
using FixedArgsType = typename Super::FixedArgs; using ArgsType = typename _EngineFunctionTrampolineBase< R(ArgTs ...) >::Args;
template<size_t ...> struct Seq {}; template<size_t ...> struct Seq {};
template<size_t N, size_t ...S> struct Gens : Gens<N-1, N-1, S...> {}; template<size_t N, size_t ...S> struct Gens : Gens<N-1, N-1, S...> {};
template<size_t ...I> struct Gens<0, I...>{ typedef Seq<I...> type; }; template<size_t ...I> struct Gens<0, I...>{ typedef Seq<I...> type; };
template<size_t I>
static typename fixed_tuple_element<I, fixed_tuple<ArgTs...>>::type getAndToType(const ArgsType& args) {
return typename EngineTypeTraits<typename fixed_tuple_element<I, fixed_tuple<ArgTs...>>::type>::ArgumentToValue(fixed_tuple_accessor<I>::get(args));
}
template<size_t ...I> template<size_t ...I>
static R dispatchHelper(typename Super::FunctionType fn, const ArgsType& args, Seq<I...>) { static R dispatchHelper(typename Super::FunctionType fn, const ArgsType& args, Seq<I...>) {
return R( fn(std::get<I>(args) ...) ); return R( fn(SelfType::template getAndToType<I>(args) ...) );
}
template<size_t ...I>
static R dispatchHelper(typename Super::FunctionType fn, const FixedArgsType& args, Seq<I...>) {
return R( fn(fixed_tuple_accessor<I>::get(args) ...) );
} }
using SeqType = typename Gens<sizeof...(ArgTs)>::type; using SeqType = typename Gens<sizeof...(ArgTs)>::type;
@ -379,11 +378,6 @@ public:
{ {
return dispatchHelper(fn, args, SeqType()); return dispatchHelper(fn, args, SeqType());
} }
static R jmp(typename Super::FunctionType fn, const FixedArgsType& args )
{
return dispatchHelper(fn, args, SeqType());
}
}; };
// Trampolines for engine methods // Trampolines for engine methods
@ -400,21 +394,21 @@ struct _EngineMethodTrampoline< Frame, R(ArgTs ...) > : public _EngineMethodTram
using FunctionType = R( typename Frame::ObjectType*, ArgTs ...); using FunctionType = R( typename Frame::ObjectType*, ArgTs ...);
private: private:
using Super = _EngineMethodTrampolineBase< R(ArgTs ...) >; using Super = _EngineMethodTrampolineBase< R(ArgTs ...) >;
using ArgsType = typename _EngineFunctionTrampolineBase< R(ArgTs ...) >::Args; using SelfType = _EngineMethodTrampoline< Frame, R(ArgTs ...) >;
using FixedArgsType = typename Super::FixedArgs; using ArgsType = typename _EngineMethodTrampolineBase< R(ArgTs ...) >::Args;
template<size_t ...> struct Seq {}; template<size_t ...> struct Seq {};
template<size_t N, size_t ...S> struct Gens : Gens<N-1, N-1, S...> {}; template<size_t N, size_t ...S> struct Gens : Gens<N-1, N-1, S...> {};
template<size_t ...I> struct Gens<0, I...>{ typedef Seq<I...> type; }; template<size_t ...I> struct Gens<0, I...>{ typedef Seq<I...> type; };
template<size_t ...I> template<size_t I>
static R dispatchHelper(Frame f, const ArgsType& args, Seq<I...>) { static typename fixed_tuple_element<I, fixed_tuple<ArgTs...>>::type getAndToType(const ArgsType& args) {
return R( f._exec(std::get<I>(args) ...) ); return typename EngineTypeTraits<typename fixed_tuple_element<I, fixed_tuple<ArgTs...>>::type>::ArgumentToValue(fixed_tuple_accessor<I>::get(args));
} }
template<size_t ...I> template<size_t ...I>
static R dispatchHelper(Frame f, const FixedArgsType& args, Seq<I...>) { static R dispatchHelper(Frame f, const ArgsType& args, Seq<I...>) {
return R( f._exec(fixed_tuple_accessor<I>::get(args) ...) ); return R(f._exec(SelfType::template getAndToType<I>(args) ...));
} }
using SeqType = typename Gens<sizeof...(ArgTs)>::type; using SeqType = typename Gens<sizeof...(ArgTs)>::type;
@ -426,14 +420,6 @@ public:
f.object = object; f.object = object;
return dispatchHelper(f, args, SeqType()); return dispatchHelper(f, args, SeqType());
} }
static R jmp( typename Frame::ObjectType* object, const FixedArgsType& args )
{
Frame f;
f.object = object;
return dispatchHelper(f, args, SeqType());
}
}; };
/// @} /// @}
@ -568,7 +554,7 @@ namespace engineAPI{
{ {
return EngineUnmarshallData< IthArgType<index> >()( argv[ startArgc + index ] ); return EngineUnmarshallData< IthArgType<index> >()( argv[ startArgc + index ] );
} else { } else {
return std::get<index + method_offset>(defaultArgs.mArgs); return fixed_tuple_accessor<index + method_offset>::get(defaultArgs.mArgs);
} }
} }
@ -700,7 +686,7 @@ public:
#define DefineEngineFunction( name, returnType, args, defaultArgs, usage ) \ #define DefineEngineFunction( name, returnType, args, defaultArgs, usage ) \
static inline returnType _fn ## name ## impl args; \ static inline returnType _fn ## name ## impl args; \
TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name \ TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name \
( _EngineFunctionTrampoline< returnType args >::FixedArgs a ) \ ( _EngineFunctionTrampoline< returnType args >::Args a ) \
{ \ { \
_CHECK_ENGINE_INITIALIZED( name, returnType ); \ _CHECK_ENGINE_INITIALIZED( name, returnType ); \
return EngineTypeTraits< returnType >::ReturnValue( \ return EngineTypeTraits< returnType >::ReturnValue( \
@ -754,7 +740,7 @@ public:
#define _DefineMethodTrampoline( className, name, returnType, args ) \ #define _DefineMethodTrampoline( className, name, returnType, args ) \
TORQUE_API EngineTypeTraits< returnType >::ReturnValueType \ TORQUE_API EngineTypeTraits< returnType >::ReturnValueType \
fn ## className ## _ ## name ( className* object, _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::FixedArgs a )\ fn ## className ## _ ## name ( className* object, _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::Args a )\
{ \ { \
_CHECK_ENGINE_INITIALIZED( className::name, returnType ); \ _CHECK_ENGINE_INITIALIZED( className::name, returnType ); \
return EngineTypeTraits< returnType >::ReturnValue( \ return EngineTypeTraits< returnType >::ReturnValue( \
@ -837,7 +823,7 @@ public:
#define DefineEngineStaticMethod( className, name, returnType, args, defaultArgs, usage ) \ #define DefineEngineStaticMethod( className, name, returnType, args, defaultArgs, usage ) \
static inline returnType _fn ## className ## name ## impl args; \ static inline returnType _fn ## className ## name ## impl args; \
TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name \ TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name \
( _EngineFunctionTrampoline< returnType args >::FixedArgs a ) \ ( _EngineFunctionTrampoline< returnType args >::Args a ) \
{ \ { \
_CHECK_ENGINE_INITIALIZED( className::name, returnType ); \ _CHECK_ENGINE_INITIALIZED( className::name, returnType ); \
return EngineTypeTraits< returnType >::ReturnValue( \ return EngineTypeTraits< returnType >::ReturnValue( \
@ -872,25 +858,25 @@ public:
); \ ); \
static inline returnType _fn ## className ## name ## impl args static inline returnType _fn ## className ## name ## impl args
# define DefineEngineStringlyVariadicFunction(name,returnType,minArgs,maxArgs,usage) \ # define DefineEngineStringlyVariadicFunction(name,returnType,minArgs,maxArgs,usage) \
static inline returnType _fn ## name ## impl (SimObject *, S32 argc, ConsoleValueRef *argv); \ static inline returnType _fn ## name ## impl (SimObject *, S32 argc, ConsoleValueRef *argv); \
TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name \ TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name \
(S32 argc, const char** argv) \ (Vector<const char*>* vec) \
{ \ { \
_CHECK_ENGINE_INITIALIZED( name, returnType ); \ _CHECK_ENGINE_INITIALIZED( name, returnType ); \
StringStackConsoleWrapper args(argc, argv); \ StringStackConsoleWrapper args(vec->size(), vec->address()); \
return EngineTypeTraits< returnType >::ReturnValue( \ return EngineTypeTraits< returnType >::ReturnValue( \
_fn ## name ## impl(NULL, args.count(), args) \ _fn ## name ## impl(NULL, args.count(), args) \
); \ ); \
} \ } \
static _EngineFunctionDefaultArguments< void (S32 argc, const char** argv) > _fn ## name ## DefaultArgs; \ static _EngineFunctionDefaultArguments< void (Vector<const char*>* vec) > _fn ## name ## DefaultArgs; \
static EngineFunctionInfo _fn ## name ## FunctionInfo( \ static EngineFunctionInfo _fn ## name ## FunctionInfo( \
#name, \ #name, \
&_SCOPE<>()(), \ &_SCOPE<>()(), \
usage, \ usage, \
#returnType " " #name "(S32 argc, const char** argv)", \ #returnType " " #name "(Vector<String> args)", \
"fn" #name, \ "fn" #name, \
TYPE< returnType (S32 argc, const char** argv) >(), \ TYPE< returnType (Vector<const char*>* vec) >(), \
&_fn ## name ## DefaultArgs, \ &_fn ## name ## DefaultArgs, \
( void* ) &fn ## name, \ ( void* ) &fn ## name, \
0 \ 0 \
@ -899,34 +885,44 @@ public:
returnType _fn ## name ## impl(SimObject *, S32 argc, ConsoleValueRef *argv) returnType _fn ## name ## impl(SimObject *, S32 argc, ConsoleValueRef *argv)
# define DefineEngineStringlyVariadicMethod(className, name,returnType,minArgs,maxArgs,usage) \ # define DefineEngineStringlyVariadicMethod(className, name,returnType,minArgs,maxArgs,usage) \
static inline returnType _fn ## className ## _ ## name ## impl (className* object, S32 argc, ConsoleValueRef* argv); \ struct _ ## className ## name ## frame \
{ \
typedef className ObjectType; \
className* object; \
inline returnType _exec (S32 argc, ConsoleValueRef* argv) const; \
}; \
TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name \ TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name \
(className* object, S32 argc, const char** argv) \ (className* object, Vector<const char*>* vec) \
{ \ { \
_CHECK_ENGINE_INITIALIZED( name, returnType ); \ _CHECK_ENGINE_INITIALIZED( name, returnType ); \
StringStackConsoleWrapper args(argc, argv); \ StringStackConsoleWrapper args(vec->size(), vec->address()); \
_ ## className ## name ## frame frame {}; \
frame.object = static_cast< className* >( object ); \
return EngineTypeTraits< returnType >::ReturnValue( \ return EngineTypeTraits< returnType >::ReturnValue( \
_fn ## className ## _ ## name ## impl(object, args.count(), args) \ frame._exec(args.count(), args) \
); \ ); \
} \ } \
static _EngineFunctionDefaultArguments< void (className* object, S32 argc, const char** argv) > _fn ## className ## _ ## name ## DefaultArgs; \ static _EngineFunctionDefaultArguments< void (className* object, S32 argc, const char** argv) > \
static EngineFunctionInfo _fn ## className ## _ ## name ## FunctionInfo( \ _fn ## className ## name ## DefaultArgs; \
static EngineFunctionInfo _fn ## className ## name ## FunctionInfo( \
#name, \ #name, \
&_SCOPE<>()(), \ &_SCOPE< className >()(), \
usage, \ usage, \
#returnType " " #name "(SimObject* object, S32 argc, const char** argv)", \ "virtual " #returnType " " #name "(Vector<String> args)", \
"fn" #className "_" #name, \ "fn" #className "_" #name, \
TYPE< returnType (SimObject* object, S32 argc, const char** argv) >(), \ TYPE< _EngineMethodTrampoline< _ ## className ## name ## frame, returnType (Vector<const char*> vec) >::FunctionType >(), \
&_fn ## className ## _ ## name ## DefaultArgs, \ &_fn ## className ## name ## DefaultArgs, \
( void* ) &fn ## className ## _ ## name, \ ( void* ) &fn ## className ## _ ## name, \
0 \ 0 \
); \ ); \
returnType cm_##className##_##name##_caster(SimObject* object, S32 argc, ConsoleValueRef* argv) { \ returnType cm_##className##_##name##_caster(SimObject* object, S32 argc, ConsoleValueRef* argv) { \
AssertFatal( dynamic_cast<className*>( object ), "Object passed to " #name " is not a " #className "!" ); \ AssertFatal( dynamic_cast<className*>( object ), "Object passed to " #name " is not a " #className "!" ); \
conmethod_return_##returnType ) _fn ## className ## _ ## name ## impl(static_cast<className*>(object),argc,argv); \ _ ## className ## name ## frame frame {}; \
frame.object = static_cast< className* >( object ); \
conmethod_return_##returnType ) frame._exec(argc,argv); \
}; \ }; \
ConsoleConstructor cc_##className##_##name##_obj(#className,#name,cm_##className##_##name##_caster,usage,minArgs,maxArgs); \ ConsoleConstructor cc_##className##_##name##_obj(#className,#name,cm_##className##_##name##_caster,usage,minArgs,maxArgs); \
static inline returnType _fn ## className ## _ ## name ## impl(className *object, S32 argc, ConsoleValueRef *argv) inline returnType _ ## className ## name ## frame::_exec(S32 argc, ConsoleValueRef *argv) const
@ -937,7 +933,7 @@ public:
#define DefineNewEngineFunction( name, returnType, args, defaultArgs, usage ) \ #define DefineNewEngineFunction( name, returnType, args, defaultArgs, usage ) \
static inline returnType _fn ## name ## impl args; \ static inline returnType _fn ## name ## impl args; \
TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name \ TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name \
( _EngineFunctionTrampoline< returnType args >::FixedArgs a ) \ ( _EngineFunctionTrampoline< returnType args >::Args a ) \
{ \ { \
_CHECK_ENGINE_INITIALIZED( name, returnType ); \ _CHECK_ENGINE_INITIALIZED( name, returnType ); \
return EngineTypeTraits< returnType >::ReturnValue( \ return EngineTypeTraits< returnType >::ReturnValue( \
@ -984,7 +980,7 @@ public:
#define DefineNewEngineStaticMethod( className, name, returnType, args, defaultArgs, usage ) \ #define DefineNewEngineStaticMethod( className, name, returnType, args, defaultArgs, usage ) \
static inline returnType _fn ## className ## name ## impl args; \ static inline returnType _fn ## className ## name ## impl args; \
TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name \ TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name \
( _EngineFunctionTrampoline< returnType args >::FixedArgs a ) \ ( _EngineFunctionTrampoline< returnType args >::Args a ) \
{ \ { \
_CHECK_ENGINE_INITIALIZED( className::name, returnType ); \ _CHECK_ENGINE_INITIALIZED( className::name, returnType ); \
return EngineTypeTraits< returnType >::ReturnValue( \ return EngineTypeTraits< returnType >::ReturnValue( \

View file

@ -94,22 +94,21 @@ struct EngineFunctionDefaultArguments
template< typename T > template< typename T >
struct _EngineFunctionDefaultArguments {}; struct _EngineFunctionDefaultArguments {};
template<typename ...ArgTs> template<typename R, typename ...ArgTs>
struct _EngineFunctionDefaultArguments< void(ArgTs...) > : public EngineFunctionDefaultArguments struct _EngineFunctionDefaultArguments< R(ArgTs...) > : public EngineFunctionDefaultArguments
{ {
template<typename T> using DefVST = typename EngineTypeTraits<T>::DefaultArgumentValueStoreType; template<typename T> using DefVST = typename EngineTypeTraits<T>::DefaultArgumentValueStoreType;
fixed_tuple<DefVST<ArgTs> ...> mFixedArgs; using SelfType = _EngineFunctionDefaultArguments< R(ArgTs...) >;
std::tuple<DefVST<ArgTs> ...> mArgs; fixed_tuple<DefVST<ArgTs>...> mArgs;
private: private:
using SelfType = _EngineFunctionDefaultArguments< void(ArgTs...) >;
template<size_t ...> struct Seq {}; template<size_t ...> struct Seq {};
template<size_t N, size_t ...S> struct Gens : Gens<N-1, N-1, S...> {}; template<size_t N, size_t ...S> struct Gens : Gens<N-1, N-1, S...> {};
template<size_t ...I> struct Gens<0, I...>{ typedef Seq<I...> type; }; template<size_t ...I> struct Gens<0, I...>{ typedef Seq<I...> type; };
template<typename ...TailTs, size_t ...I> template<typename ...TailTs, size_t ...I>
static void copyHelper(std::tuple<DefVST<ArgTs> ...> &args, std::tuple<DefVST<TailTs> ...> &defaultArgs, Seq<I...>) { static void copyHelper(std::tuple<DefVST<ArgTs> ...> &args, std::tuple<DefVST<TailTs> ...> &defaultArgs, Seq<I...>) {
std::tie(std::get<I + (sizeof...(ArgTs) - sizeof...(TailTs))>(args)...) = defaultArgs; std::tie(std::get<I + (sizeof...(ArgTs) - sizeof...(TailTs))>(args)...) = defaultArgs;
} }
@ -117,7 +116,7 @@ private:
template<typename ...TailTs> template<typename ...TailTs>
struct DodgyVCHelper struct DodgyVCHelper
{ {
using type = typename std::enable_if<sizeof...(TailTs) <= sizeof...(ArgTs), decltype(mArgs)>::type; using type = typename std::enable_if<sizeof...(TailTs) <= sizeof...(ArgTs), std::tuple<DefVST<ArgTs>...>>::type;
}; };
template<typename ...TailTs> using MaybeSelfEnabled = typename DodgyVCHelper<TailTs...>::type; template<typename ...TailTs> using MaybeSelfEnabled = typename DodgyVCHelper<TailTs...>::type;
@ -128,15 +127,16 @@ private:
template<typename ...TailTs> static MaybeSelfEnabled<TailTs...> tailInit(TailTs ...tail) { template<typename ...TailTs> static MaybeSelfEnabled<TailTs...> tailInit(TailTs ...tail) {
std::tuple<DefVST<ArgTs>...> argsT; std::tuple<DefVST<ArgTs>...> argsT;
std::tuple<DefVST<TailTs>...> tailT = std::make_tuple(tail...); std::tuple<DefVST<TailTs>...> tailT = std::make_tuple(tail...);
SelfType::copyHelper<TailTs...>(argsT, tailT, typename Gens<sizeof...(TailTs)>::type()); SelfType::template copyHelper<TailTs...>(argsT, tailT, typename Gens<sizeof...(TailTs)>::type());
return argsT; return argsT;
}; };
public: public:
template<typename ...TailTs> _EngineFunctionDefaultArguments(TailTs ...tail) template<typename ...TailTs> _EngineFunctionDefaultArguments(TailTs ...tail)
: EngineFunctionDefaultArguments({sizeof...(TailTs)}), mArgs(SelfType::tailInit(tail...)) : EngineFunctionDefaultArguments({sizeof...(TailTs)})
{ {
fixed_tuple_mutator<void(DefVST<ArgTs>...), void(DefVST<ArgTs>...)>::copy(mArgs, mFixedArgs); std::tuple<DefVST<ArgTs>...> tmpTup = SelfType::tailInit(tail...);
fixed_tuple_mutator<void(DefVST<ArgTs>...), void(DefVST<ArgTs>...)>::copy(tmpTup, mArgs);
} }
}; };