From a84145421f15eec3de767816425cd782597a534e Mon Sep 17 00:00:00 2001 From: Lukas Joergensen Date: Sat, 21 Apr 2018 09:06:16 +0200 Subject: [PATCH] Fix EngineAPI xml generation, utilizing fixed_tuple for default args --- Engine/source/console/engineFunctions.h | 9 +- Engine/source/console/engineXMLExport.cpp | 2 +- Engine/source/console/fixedTuple.h | 153 ++++++++++++++++++++++ 3 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 Engine/source/console/fixedTuple.h diff --git a/Engine/source/console/engineFunctions.h b/Engine/source/console/engineFunctions.h index 0f2a3f45d..eb935d995 100644 --- a/Engine/source/console/engineFunctions.h +++ b/Engine/source/console/engineFunctions.h @@ -25,6 +25,10 @@ #include +#ifndef _FIXEDTUPLE_H_ +#include "fixedTuple.h" +#endif + #ifndef _ENGINEEXPORTS_H_ #include "console/engineExports.h" #endif @@ -94,6 +98,7 @@ template struct _EngineFunctionDefaultArguments< void(ArgTs...) > : public EngineFunctionDefaultArguments { template using DefVST = typename EngineTypeTraits::DefaultArgumentValueStoreType; + fixed_tuple ...> mFixedArgs; std::tuple ...> mArgs; private: using SelfType = _EngineFunctionDefaultArguments< void(ArgTs...) >; @@ -130,7 +135,9 @@ private: public: template _EngineFunctionDefaultArguments(TailTs ...tail) : EngineFunctionDefaultArguments({sizeof...(TailTs)}), mArgs(SelfType::tailInit(tail...)) - {} + { + fixed_tuple_mutator...), void(DefVST...)>::copy(mArgs, mFixedArgs); + } }; #pragma pack( pop ) diff --git a/Engine/source/console/engineXMLExport.cpp b/Engine/source/console/engineXMLExport.cpp index ce12121e8..51951c52b 100644 --- a/Engine/source/console/engineXMLExport.cpp +++ b/Engine/source/console/engineXMLExport.cpp @@ -197,7 +197,7 @@ static String getDefaultArgumentValue( const EngineFunctionInfo* function, const //TODO: for now we store string literals in ASCII; needs to be sorted out if( TYPE< const char* >() == type ) { - const char* val = getArgValue< const char* >( defaultArgs, offset ); + const char* val = reinterpret_cast< const char* >(defaultArgs->getArgs() + offset); value = val; } diff --git a/Engine/source/console/fixedTuple.h b/Engine/source/console/fixedTuple.h new file mode 100644 index 000000000..871cd7011 --- /dev/null +++ b/Engine/source/console/fixedTuple.h @@ -0,0 +1,153 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef _FIXEDTUPLE_H_ +#define _FIXEDTUPLE_H_ +/// @name Fixed-layout tuple definition +/// These structs and templates serve as a way to pass arguments from external +/// applications and into the T3D console system. +/// They work as std::tuple, but they ensure a standardized fixed memory +/// layout. Allowing for unmanaged calls with these tuples as the parameter +/// lists. +/// +/// The implementation is from a SO solution: +/// https://codereview.stackexchange.com/a/52279 +/// As out use-case is pretty simple, this code could probably be simplified by +/// stripping out a lot of extra functionality. But eh. +/// +/// @{ + +template +struct fixed_tuple; + +template +struct fixed_tuple +{ + T first; + fixed_tuple rest; + + fixed_tuple() = default; + template ::type>::value>::type> + fixed_tuple(U&& u, Us&&...tail) : + first(::std::forward(u)), + rest(::std::forward(tail)...) {} +}; + +template +struct fixed_tuple +{ + T first; + + fixed_tuple() = default; + template ::type>::value>::type> + fixed_tuple(U&& u) : + first(::std::forward(u)) {} +}; + +template <> +struct fixed_tuple<> {}; + + +template < ::std::size_t i, class T> +struct fixed_tuple_element; + +template < ::std::size_t i, class T, class... Ts> +struct fixed_tuple_element > + : fixed_tuple_element > +{}; + +template +struct fixed_tuple_element<0, fixed_tuple > +{ + using type = T; +}; + +template < ::std::size_t i> +struct fixed_tuple_accessor +{ + template + static inline typename fixed_tuple_element >::type & get(fixed_tuple & t) + { + return fixed_tuple_accessor::get(t.rest); + } + + template + static inline const typename fixed_tuple_element >::type & get(const fixed_tuple & t) + { + return fixed_tuple_accessor::get(t.rest); + } +}; + +template <> +struct fixed_tuple_accessor<0> +{ + template + static inline typename fixed_tuple_element<0, fixed_tuple >::type & get(fixed_tuple & t) + { + return t.first; + } + + template + static inline const typename fixed_tuple_element<0, fixed_tuple >::type & get(const fixed_tuple & t) + { + return t.first; + } +}; + +template< typename T1, typename T2 > +struct fixed_tuple_mutator {}; + +template +struct fixed_tuple_mutator +{ + template + static inline typename std::enable_if::type + copy_r_t_l(fixed_tuple& src, fixed_tuple& dest) + { } + + template + static inline typename std::enable_if::type + copy_r_t_l(fixed_tuple& src, fixed_tuple& dest) + { + fixed_tuple_accessor::get(dest) = fixed_tuple_accessor::get(src); + copy_r_t_l(src, dest); + } + + template + static inline typename std::enable_if::type + copy(std::tuple& src, fixed_tuple& dest) + { } + + template + static inline typename std::enable_if::type + copy(std::tuple& src, fixed_tuple& dest) + { + fixed_tuple_accessor::get(dest) = std::get(src); + copy(src, dest); + } +}; + + +/// @} + + +#endif // !_FIXEDTUPLE_H_ \ No newline at end of file