diff options
author | Mattes D <github@xoft.cz> | 2017-08-30 10:35:19 +0200 |
---|---|---|
committer | Mattes D <github@xoft.cz> | 2017-08-30 15:25:13 +0200 |
commit | a24147d970b5825619df39d06b39437effd04b41 (patch) | |
tree | 3d809acc62e3f165896bf48f6d39eb13a3e4460d /src | |
parent | Update core plugins to latest version (#3951) (diff) | |
download | cuberite-a24147d970b5825619df39d06b39437effd04b41.tar cuberite-a24147d970b5825619df39d06b39437effd04b41.tar.gz cuberite-a24147d970b5825619df39d06b39437effd04b41.tar.bz2 cuberite-a24147d970b5825619df39d06b39437effd04b41.tar.lz cuberite-a24147d970b5825619df39d06b39437effd04b41.tar.xz cuberite-a24147d970b5825619df39d06b39437effd04b41.tar.zst cuberite-a24147d970b5825619df39d06b39437effd04b41.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/Bindings/.gitignore | 1 | ||||
-rw-r--r-- | src/Bindings/BindingsProcessor.lua | 15 | ||||
-rw-r--r-- | src/Bindings/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/Bindings/LuaState.cpp | 6 | ||||
-rw-r--r-- | src/Bindings/LuaState.h | 3 | ||||
-rw-r--r-- | src/Bindings/LuaStateParams.h | 571 | ||||
-rw-r--r-- | src/CMakeLists.txt | 1 |
7 files changed, 595 insertions, 5 deletions
diff --git a/src/Bindings/.gitignore b/src/Bindings/.gitignore index 16f9db55d..2ed84f9a2 100644 --- a/src/Bindings/.gitignore +++ b/src/Bindings/.gitignore @@ -3,3 +3,4 @@ lua51.dll LuaState_Declaration.inc LuaState_Implementation.cpp LuaState_Typedefs.inc +LuaStateParams_TypeDescs.inc diff --git a/src/Bindings/BindingsProcessor.lua b/src/Bindings/BindingsProcessor.lua index d6c39dec6..f013b3918 100644 --- a/src/Bindings/BindingsProcessor.lua +++ b/src/Bindings/BindingsProcessor.lua @@ -206,7 +206,7 @@ local function OutputLuaStateHelpers(a_Package) local f = assert(io.open("LuaState_Declaration.inc", "w")) f:write("\n// LuaState_Declaration.inc\n\n// This file is generated along with the Lua bindings by ToLua. Do not edit manually, do not commit to repo.\n") f:write("// Implements a Push() and GetStackValue() function for each class exported to the Lua API.\n") - f:write("// This file expects to be included form inside the cLuaState class definition\n") + f:write("// This file expects to be included from inside the cLuaState class definition\n") f:write("\n\n\n\n\n") for _, item in ipairs(types) do if not(g_HasCustomPushImplementation[item.name]) then @@ -218,6 +218,7 @@ local function OutputLuaStateHelpers(a_Package) f:write("bool GetStackValue(int a_StackPos, ConstPtr" .. item.lname .. " & a_ReturnedVal);\n") end f:write("\n\n\n\n\n") + f:close() end @@ -266,6 +267,18 @@ local function OutputLuaStateHelpers(a_Package) end f:close() end + + do + local f = assert(io.open("LuaStateParams_TypeDescs.inc", "w")) + f:write("\n// LuaStateParams_TypeDescs.inc\n\n// This file is generated along with the Lua bindings by ToLua. Do not edit manually, do not commit to repo.\n") + f:write("// Implements a TypeDescription<type>::desc() specialization for each class exported to the Lua API.\n") + f:write("// This file expects to be included from inside the cLuaStateParams class definition\n") + f:write("\n\n\n\n\n") + for _, item in ipairs(types) do + f:write("template <> struct TypeDescription<" .. item.lname .. "> { static const char * desc() { return \"" .. item.lname .. "\"; } };\n") + end + f:close() + end end diff --git a/src/Bindings/CMakeLists.txt b/src/Bindings/CMakeLists.txt index 0ab21467b..e736640d2 100644 --- a/src/Bindings/CMakeLists.txt +++ b/src/Bindings/CMakeLists.txt @@ -36,6 +36,8 @@ SET (HDRS LuaState.h LuaState_Declaration.inc LuaState_Typedefs.inc + LuaStateParams.h + LuaStateParams_TypeDescs.inc LuaTCPLink.h LuaUDPEndpoint.h LuaWindow.h @@ -53,6 +55,7 @@ set (BINDING_OUTPUTS ${CMAKE_CURRENT_SOURCE_DIR}/LuaState_Declaration.inc ${CMAKE_CURRENT_SOURCE_DIR}/LuaState_Implementation.cpp ${CMAKE_CURRENT_SOURCE_DIR}/LuaState_Typedefs.inc + ${CMAKE_CURRENT_SOURCE_DIR}/LuaStateParams_TypeDescs.inc ) set(BINDING_DEPENDENCIES diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 7bd4becb6..9fdcca0d3 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -42,7 +42,6 @@ extern "C" - const cLuaState::cRet cLuaState::Return = {}; const cLuaState::cNil cLuaState::Nil = {}; @@ -50,7 +49,6 @@ const cLuaState::cNil cLuaState::Nil = {}; - //////////////////////////////////////////////////////////////////////////////// // cCanonLuaStates: @@ -2050,7 +2048,9 @@ int cLuaState::ApiParamError(const char * a_MsgFormat, ...) AString cLuaState::GetTypeText(int a_StackPos) { - return lua_typename(m_LuaState, lua_type(m_LuaState, a_StackPos)); + AString ret(tolua_typename(m_LuaState, a_StackPos)); + lua_pop(m_LuaState, 1); + return ret; } diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 98f1cbc28..491e60d64 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -100,7 +100,7 @@ public: #define STRINGIFY2(X, Y) X##Y #define STRINGIFY(X, Y) STRINGIFY2(X, Y) - #define ASSERT_LUA_STACK_BALANCE(...) cStackBalanceCheck STRINGIFY(Check, __COUNTER__)(__FILE__, __LINE__, __VA_ARGS__) + #define ASSERT_LUA_STACK_BALANCE(...) cLuaState::cStackBalanceCheck STRINGIFY(Check, __COUNTER__)(__FILE__, __LINE__, __VA_ARGS__) #else #define ASSERT_LUA_STACK_BALANCE(...) #endif @@ -694,6 +694,7 @@ public: return GetStackValue(a_StackPos, a_ReturnedVal.GetDest()); } + /** Pushes the named value in the table at the top of the stack. a_Name may be a path containing multiple table levels, such as "cChatColor.Blue". If the value is found, it is pushed on top of the stack and the returned cStackValue is valid. diff --git a/src/Bindings/LuaStateParams.h b/src/Bindings/LuaStateParams.h new file mode 100644 index 000000000..0e8dc1b2d --- /dev/null +++ b/src/Bindings/LuaStateParams.h @@ -0,0 +1,571 @@ +// LuaStateParams.h + +// Declares the cLuaStateParams class that provides high-level functions for reading API parameters from Lua state + +#pragma once + + + + + +#include "LuaState.h" + + + + + +namespace Detail +{ + /** Utility struct that provides the functionality to cLuaStateParams::GetTypeDescription. + Supports decorators such as cLuaStateParams::cSelf<T>. + Must be a struct in order to support decorators, and must not be inside a class (gcc / clang complain about that). + The general declaration must not be used by the code, all types need a specialization returning the correct type. */ + template <typename T> + struct TypeDescription + { + static const char * desc() + { + static_assert(false, "Type is missing a TypeDescription<> template"); + /* If compiler complains on the previous line, you need to make sure that the type + passed as the template parameter to this structure has an appropriate TypeDescription specialization. + Usually these are created automatically for all API classes by ToLua++ in the LuaStateParams_TypeDescs.inc file. + For basic types, the specializations are below. + */ + } + }; + + // Specializations are defined after the cLuaStateParams class declaration +} + + + + + +/** A namespace-like class for reading parameters to API functions from Lua, using templates. +The Read() function is the main entrypoint for this, and does all the work. +Example usage: +int Param1, Param2, Param3; +AString ParamA, ParamB; +cItem * Item; +switch (cLuaStateParams::Read(LuaState, + std::tie(cLuaStateParams::self(Item), Param1, Param2, Param3), + std::tie(cLuaStateParams::self(Item), ParamA, ParamB) +)) +{ + case 0: + { + // The first overload was used; Item, Param1, Param2 and Param3 are valid + Item->DoSomething(Param1, Param2, Param3); + break; + } + case 1: + { + // The second overload was used; Item, ParamA and ParamB are valid + Item->DoSomething(ParamA, ParamB); + break; + } + // No need for default: if no overloads match, the function raises a Lua error, returning to the Lua's caller +} +*/ +class cLuaStateParams +{ +public: + /** A wrapper used in cLuaStateParams::Read() to signalize that the value must be a non-nil pointer when read from Lua. */ + template <typename T> + class cNonNil + { + friend class cLuaStateParams; + typedef T * Tptr; + public: + typedef T ParentType; + + cNonNil(Tptr & a_Dest): + m_Dest(a_Dest) + { + } + + protected: + /** The destination pointer where the param will be written. */ + Tptr & m_Dest; + }; + template <typename T> static cNonNil<T> nonNil(T * & a_Dest) { return cNonNil<T>(a_Dest); } + + + /** A wrapper used in cLuaStateParams::Read() to signalize that the value is a "self" - it must be a non-nil pointer when read from Lua, + and has a special error message when mismatched. */ + template <typename T> + class cSelf + { + friend class cLuaStateParams; + typedef T * Tptr; + public: + typedef T ParentType; + + cSelf(Tptr & a_Self): + m_Self(a_Self) + { + } + + protected: + Tptr & m_Self; + }; + template <typename T> static cSelf<T> self(T * & a_Self) { return cSelf<T>(a_Self); } + + + /** A wrapper used in cLuaState::ReadParams() to signalize that the value is a "static self", + it must be the table representing the class T when read from Lua. */ + template <class T> + class cStaticSelf + { + public: + typedef T ParentType; + }; + template <class T> static cStaticSelf<T> staticSelf() { return cStaticSelf<T>(); } + + + +protected: + + /** Attempts to match the params on the Lua stack to the API function overloads given (recursively). + a_CurOverload is the index of the currently processed overload (recursion level), + Returns the index of the overload that matches the parameters. + If no overloads match, returns -1. */ + template <typename... T1, typename... T2> + static int ReadInternal(cLuaState & a_LuaState, int a_CurOverload, std::tuple<T1...> & a_Ovl, T2 &&... a_OtherParams) + { + // Try to read this overload + if (ReadSingleOverload(a_LuaState, a_Ovl)) + { + return a_CurOverload; + } + + // Try the next overload: + return ReadInternal(a_LuaState, a_CurOverload + 1, std::forward<T2>(a_OtherParams)...); + } + + + /** Terminator for the template-based recursion of the function above - for a single overload. */ + template <typename... T1> + static int ReadInternal(cLuaState & a_LuaState, int a_CurOverload, std::tuple<T1...> & a_Ovl) + { + // Try to read this overload + if (ReadSingleOverload(a_LuaState, a_Ovl)) + { + return a_CurOverload; + } + + // No more overloads, report failure + return -1; + } + + + + /** Helper struct to implement iterating over std::tuple elements */ + template <int N> struct SizeT {}; + + + + /** Attempts to match the params on the Lua stack to the given API function overload. + Returns true if successful, false on failure. */ + template <typename... T> + static bool ReadSingleOverload(cLuaState & a_LuaState, std::tuple<T...> & a_Overload) + { + // Check that there exactly as many params as the tuple items: + if (!lua_isnone(a_LuaState, sizeof...(T) + 1)) + { + // Too many params + return false; + } + if (lua_isnone(a_LuaState, sizeof...(T))) + { + // Too few params + return false; + } + + // Read the tuple, compile-time-recursively: + return ReadSingleOverloadRecurse(a_LuaState, std::forward<std::tuple<T...>>(a_Overload), SizeT<sizeof...(T)>()); + } + + + + /** Attempts to match the params on the Lua stack to the given API function overload. + The compile-time recursive worker implementation of ReadSingleOverload, recurses by the number of elements in the overload tuple. + Returns true on success, false on failure. */ + template <typename... T, size_t N> + static bool ReadSingleOverloadRecurse(cLuaState & a_LuaState, std::tuple<T...> & a_Overload, SizeT<N>) + { + // First read the params from the lower tuple indices: + if (!ReadSingleOverloadRecurse(a_LuaState, a_Overload, SizeT<N - 1>())) + { + return false; + } + + // Then read the param pointed to by our index: + return GetStackValue(a_LuaState, N, std::get<N - 1>(a_Overload)); + } + + + /** Terminator for the above compile-time-recursive function. */ + template <typename... T> + static bool ReadSingleOverloadRecurse(cLuaState & a_LuaState, std::tuple<T...> & a_Overload, SizeT<1>) + { + return GetStackValue(a_LuaState, 1, std::get<0>(a_Overload)); + } + + + + /** Reads one value from the Lua stack. + Returns true on success, false on failure. + The hard work is delegated into cLuaState that already has this function, but we need to specialize it for decorators (cNonNil, cSelf etc.). */ + template <typename T> + static bool GetStackValue(cLuaState & a_LuaState, int a_StackPos, T && a_ReturnedVal) + { + return a_LuaState.GetStackValue(a_StackPos, std::forward<T>(a_ReturnedVal)); + } + + + /** Reads one value from the Lua stack. + Returns true on success, false on failure. + Specialization: Retrieves a value that should represent a non-nil pointer. Used primarily for ReadParams(... nonNil(...)) */ + template <typename T> + static bool GetStackValue(cLuaState & a_LuaState, int a_StackPos, cNonNil<T> & a_ReturnedVal) + { + auto res = GetStackValue(a_LuaState, a_StackPos, a_ReturnedVal.m_Dest); + if (res) + { + if (a_ReturnedVal.m_Dest == nullptr) + { + return false; + } + } + return res; + } + + + /** Reads one value from the Lua stack. + Returns true on success, false on failure. + Specialization: Retrieves a value that should represent a pointer to self - must not be nil. Used primarily for ReadParams(self(...)) */ + template <typename T> + static bool GetStackValue(cLuaState & a_LuaState, int a_StackPos, cSelf<T> & a_ReturnedVal) + { + auto res = GetStackValue(a_LuaState, a_StackPos, a_ReturnedVal.m_Self); + if (res) + { + if (a_ReturnedVal.m_Self == nullptr) + { + return false; + } + } + return res; + } + + + /** Reads one value from the Lua stack. + Returns true on success, false on failure. + Specialization: The value should represent a class and has no useful meaning, it is not read, just type-checked. + Used primarily for ReadParams(staticSelf(...)) */ + template <typename T> + static bool GetStackValue(cLuaState & a_LuaState, int a_StackPos, cStaticSelf<T> & a_ReturnedVal) + { + return (CheckValueType(a_LuaState, a_StackPos, a_ReturnedVal).empty()); + } + + + + /** Raises a Lua error that the parameters don't match the overloads. + Builds and logs the whole error message, including the reason why each overload wasn't matched. */ + template <typename... T> + static void RaiseError(cLuaState & a_LuaState, T &&... a_Overloads) + { + auto matcherMsgs = BuildMatcherErrorMessages(a_LuaState, std::forward<T>(a_Overloads)...); + a_LuaState.ApiParamError("Parameters don't match function signatures:\n%s", + StringJoin(matcherMsgs, "\n\t").c_str() + ); + } + + + + /** Returns a vector of string, each item representing a single overload's signature + and the error message from the matcher why the signature cannot be used. */ + template <typename... T1, typename... T2> + static AStringVector BuildMatcherErrorMessages( + cLuaState & a_LuaState, + const std::tuple<T1...> & a_Overload1, + T2 &&... a_OtherOverloads + ) + { + auto res = BuildMatcherErrorMessages(a_LuaState, std::forward<T2>(a_OtherOverloads)...); + auto signature = BuildSingleOverloadDescription<T1...>(); + auto msg = GetMatcherErrorMessage(a_LuaState, a_Overload1); + res.emplace_back(std::move(Printf("(%s): %s", signature.c_str(), msg.c_str()))); + return res; + } + + + /** Terminator for the function above. */ + static AStringVector BuildMatcherErrorMessages(cLuaState & a_LuaState) + { + return AStringVector(); + } + + + + /** Returns the error message why the specified overload signature cannot be used for current params. */ + template <typename... T> + static AString GetMatcherErrorMessage(cLuaState & a_LuaState, const std::tuple<T...> & a_Overload) + { + if (!lua_isnone(a_LuaState, static_cast<int>(sizeof...(T) + 1))) + { + return Printf("There are more parameters present (%d) than the signature allows (%u)", + lua_gettop(a_LuaState), + static_cast<unsigned>(sizeof...(T)) + ); + } + if (lua_isnone(a_LuaState, static_cast<int>(sizeof...(T)))) + { + return Printf("There are not enough parameters present (%d) to match the signature (%u).", + lua_gettop(a_LuaState), + static_cast<unsigned>(sizeof...(T)) + ); + } + return GetParamMatchError(a_LuaState, a_Overload, SizeT<sizeof...(T)>()); + } + + + + /** Returns the string describing why the specified overload signature doesn't match current params. + Checks each individual param using compile-time recursion. + Doesn't check param end (checked by GetMatcherErrorMessage(), which is the only one calling this function). */ + template <typename... T, size_t N> + static AString GetParamMatchError(cLuaState & a_LuaState, const std::tuple<T...> & a_Overload, SizeT<N>) + { + // Try to read the param into a dummy variable of the proper type: + auto res = CheckValueType(a_LuaState, static_cast<int>(N), std::get<N - 1>(a_Overload)); + if (!res.empty()) + { + return Printf("Parameter %u: %s", static_cast<unsigned>(N), res.c_str()); + } + + // Reading succeeded, try the next param: + return GetParamMatchError(a_LuaState, a_Overload, SizeT<N - 1>()); + } + + + /** Terminator for the above function + We've checked all the params, so this should never be reached. */ + template <typename... T> + static AString GetParamMatchError(cLuaState & a_LuaState, const std::tuple<T...> & a_Overload, SizeT<0>) + { + return "[internal matcher error - no reason for mismatch can be found]"; + } + + + + /** Returns an error message if the value on the specified index on the Lua stack is of the wrong (template) type. + If the type matches, returns an empty string. + This is the generic version for regular values. */ + template <typename T> + static AString CheckValueType(cLuaState & a_LuaState, int a_StackPos, const T & a_Dest) + { + typename std::remove_reference<T>::type dummy; + if (!a_LuaState.GetStackValue(a_StackPos, dummy)) + { + return Printf("Mismatch, expected %s, got %s", + GetTypeDescription<std::remove_reference<T>::type>().c_str(), + a_LuaState.GetTypeText(a_StackPos).c_str() + ); + } + return AString(); + } + + + /** Returns an error message if the value on the specified index on the Lua stack is of the wrong (template) type. + This is the specialization for "cNonNil"-decorated values. */ + template <typename T> + static AString CheckValueType(cLuaState & a_LuaState, int a_StackPos, const cNonNil<T> & a_Dest) + { + if (lua_isnil(a_LuaState, a_StackPos)) + { + return Printf("Expected a non-nil instance of %s, got a nil", + GetTypeDescription<std::remove_reference<T>::type>().c_str(), + a_LuaState.GetTypeText(a_StackPos).c_str() + ); + } + return CheckValueType(a_LuaState, a_StackPos, a_Dest.m_Dest); + } + + + /** Returns an error message if the value on the specified index on the Lua stack is of the wrong (template) type. + This is the specialization for "cSelf"-decorated values. */ + template <typename T> + static AString CheckValueType(cLuaState & a_LuaState, int a_StackPos, const cSelf<T> & a_Dest) + { + if (lua_isnil(a_LuaState, a_StackPos)) + { + return Printf("Expected an instance of %s, got a %s. Did you use the right calling convention?", + GetTypeDescription<std::remove_reference<T>::type>().c_str(), + a_LuaState.GetTypeText(a_StackPos).c_str() + ); + } + return CheckValueType(a_LuaState, a_StackPos, a_Dest.m_Self); + } + + + /** Returns an error message if the value on the specified index on the Lua stack is of the wrong (template) type. + This is the specialization for "cStaticSelf"-decorated values. */ + template <typename T> + static AString CheckValueType(cLuaState & a_LuaState, int a_StackPos, const cStaticSelf<T> & a_Dest) + { + tolua_Error err; + auto type = GetTypeDescription<std::remove_pointer<typename std::remove_reference<T>::type>::type>(); + if (lua_isnil(a_LuaState, a_StackPos)) + { + return Printf("Expected the class %s, got a nil", type.c_str()); + } + if (tolua_isusertype(a_LuaState, a_StackPos, type.c_str(), 0, &err)) + { + return Printf("Expected the class %s, got a %s. This function is static, remember to use the right calling convention.", + type.c_str(), + a_LuaState.GetTypeText(a_StackPos).c_str() + ); + } + return AString(); + } + + + + /** Returns a string describing the function overload composed of the specified (template) types. */ + template <typename T1, typename T2, typename... T3> + static AString BuildSingleOverloadDescription() + { + return GetTypeDescription<T1>() + ", " + BuildSingleOverloadDescription<T2, T3...>(); + } + + + /** Terminator for the above function. */ + template <typename T> + static AString BuildSingleOverloadDescription() + { + return GetTypeDescription<T>(); + } + + + + /** Returns the Lua type representing the specified C++ type. + Supports decorators such as cSelf, references and pointers. */ + template <typename T> + static AString GetTypeDescription(void) + { + return Detail::TypeDescription<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::desc(); + } + + + +public: + + /** The main entrypoint for API param reading. + Tries to match the parameters on the Lua stack onto the specified overloads. + Each overload is a std::tuple<...> of references which are to be filled with the values read. + Returns the 0-based index of the first overload that matched the Lua params. + If no overloads match, raises a Lua error with detailed information about why there was no match. + The design goals: + - In case of success, use as little overhead as possible + - In case of error, provide as much information as possible, even at the cost of huge overhead + The caller should order the overloads in the order by expected usage - the most used ones first. + Because the overloads are checked sequentially, this provides the least overhead. + Uses compile-time template recursion to iterate over all overloads and all their items. + + Call tree: + Read + +- ReadInternal <recursive> + | +- ReadSingleOverload + | +- ReadSingleOverloadRecurse <recursive> + | +- GetStackValue + | +- cLuaState::GetStackValue + | +- CheckValueType [for cStaticSelf] + +- RaiseError + | +- BuildMatcherErrorMessages <recursive> + | | +- BuildSingleOverloadDescription <recursive> + | | | +- GetTypeDescription + | | | +- Detail::TypeDescription<T>::desc + | | +- GetMatcherErrorMessage + | | +- GetParamMatchError <recursive> + | | +- CheckValueType + | | +- cLuaState::GetStackValue + | +- cLuaState::ApiParamError + +- return [never reached] + */ + template <typename... OverloadTuples> + static int Read(cLuaState & a_LuaState, OverloadTuples &&... a_Overloads) + { + // If the reading succeeded, return success + auto res = ReadInternal(a_LuaState, 0, std::forward<OverloadTuples>(a_Overloads)...); + if (res >= 0) + { + return res; + } + + // The reading failed, raise an error: + RaiseError(a_LuaState, std::forward<OverloadTuples>(a_Overloads)...); + return 0; // Never reached, but undefined behavior if not present + } +}; + + + + + +namespace Detail +{ + // Specializations for basic types: + template <> struct TypeDescription<AString> { static const char * desc() { return "string"; } }; + template <> struct TypeDescription<const char *> { static const char * desc() { return "string"; } }; + template <> struct TypeDescription<int> { static const char * desc() { return "number"; } }; + template <> struct TypeDescription<unsigned> { static const char * desc() { return "number"; } }; + template <> struct TypeDescription<float> { static const char * desc() { return "number"; } }; + template <> struct TypeDescription<double> { static const char * desc() { return "number"; } }; + + // Specializations for decorated types: + template <typename T> + struct TypeDescription<cLuaStateParams::cNonNil<T>> + { + static const char * desc() { return TypeDescription<T>::desc(); } + }; + + template <typename T> + struct TypeDescription<cLuaStateParams::cNonNil<T> &> + { + static const char * desc() { return TypeDescription<T>::desc(); } + }; + + template <typename T> + struct TypeDescription<cLuaStateParams::cSelf<T>> + { + static const char * desc() { return TypeDescription<T>::desc(); } + }; + + template <typename T> + struct TypeDescription<cLuaStateParams::cSelf<T> &> + { + static const char * desc() { return TypeDescription<T>::desc(); } + }; + + template <typename T> + struct TypeDescription<cLuaStateParams::cStaticSelf<T>> + { + static const char * desc() { return TypeDescription<T>::desc(); } + }; + + template <typename T> + struct TypeDescription<cLuaStateParams::cStaticSelf<T> &> + { + static const char * desc() { return TypeDescription<T>::desc(); } + }; + + // Include the TypeDecription<T> specializations generated for all known API classes: + #include "LuaStateParams_TypeDescs.inc" +} + + + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d7eb4e903..d081e7a89 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -211,6 +211,7 @@ else () FILE(GLOB FOLDER_FILES "${PATH}/*.cpp" "${PATH}/*.h" + "${PATH}/*.inc" "${PATH}/*.rc" "${PATH}/*.pkg" ) |