From c9a9b3c9d0d4fed0b02d9935923bfd7dcbc45d1e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 14 Apr 2020 16:43:21 +0200 Subject: Bindings: Allow coercion between Vector3 subtypes. (#4646) In manually bound functions, allows one to use any Vector3 value, as well as a {x, y, z} table, in Lua as any Vector3 parameter. Has example in Debuggers' /vector command. Unfortunately doesn't work in auto-bindings. --- src/Bindings/LuaState.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 4 deletions(-) (limited to 'src/Bindings/LuaState.cpp') diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index ad1021001..0541af793 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -1451,6 +1451,57 @@ bool cLuaState::GetStackValue(int a_StackPos, cUUID & a_Value) +template +bool cLuaState::GetStackValue(int a_StackPos, Vector3 & a_ReturnedVal) +{ + tolua_Error err; + if (lua_isnil(m_LuaState, a_StackPos)) + { + return false; + } + if (tolua_isusertype(m_LuaState, a_StackPos, "Vector3", 0, &err)) + { + a_ReturnedVal = **(static_cast(lua_touserdata(m_LuaState, a_StackPos))); + return true; + } + if (tolua_isusertype(m_LuaState, a_StackPos, "Vector3", 0, &err)) + { + a_ReturnedVal = **(static_cast(lua_touserdata(m_LuaState, a_StackPos))); + return true; + } + if (tolua_isusertype(m_LuaState, a_StackPos, "Vector3", 0, &err)) + { + a_ReturnedVal = **(static_cast(lua_touserdata(m_LuaState, a_StackPos))); + return true; + } + + // Bonus: Allow simple tables to work as Vector3: + if (lua_istable(m_LuaState, a_StackPos)) + { + lua_rawgeti(m_LuaState, a_StackPos, 1); + lua_rawgeti(m_LuaState, a_StackPos, 2); + lua_rawgeti(m_LuaState, a_StackPos, 3); + T x, y, z; + if (!GetStackValues(-3, x, y, z)) + { + return false; + } + a_ReturnedVal = Vector3(x, y, z); + return true; + } + + return false; +} + +// Explicitly instantiate the previous function for all Vector3 types: +template bool cLuaState::GetStackValue(int a_StackPos, Vector3d & a_ReturnedVal); +template bool cLuaState::GetStackValue(int a_StackPos, Vector3f & a_ReturnedVal); +template bool cLuaState::GetStackValue(int a_StackPos, Vector3i & a_ReturnedVal); + + + + + cLuaState::cStackValue cLuaState::WalkToValue(const AString & a_Name) { // There needs to be at least one value on the stack: @@ -1937,24 +1988,40 @@ bool cLuaState::CheckParamStaticSelf(const char * a_SelfClassName) -bool cLuaState::IsParamUserType(int a_Param, AString a_UserType) +bool cLuaState::IsParamUserType(int a_ParamIdx, AString a_UserType) { ASSERT(IsValid()); tolua_Error tolua_err; - return (tolua_isusertype(m_LuaState, a_Param, a_UserType.c_str(), 0, &tolua_err) == 1); + return (tolua_isusertype(m_LuaState, a_ParamIdx, a_UserType.c_str(), 0, &tolua_err) == 1); } -bool cLuaState::IsParamNumber(int a_Param) +bool cLuaState::IsParamNumber(int a_ParamIdx) { ASSERT(IsValid()); tolua_Error tolua_err; - return (tolua_isnumber(m_LuaState, a_Param, 0, &tolua_err) == 1); + return (tolua_isnumber(m_LuaState, a_ParamIdx, 0, &tolua_err) == 1); +} + + + + + +bool cLuaState::IsParamVector3(int a_ParamIdx) +{ + ASSERT(IsValid()); + + return ( + IsParamUserType(a_ParamIdx, "Vector3") || + IsParamUserType(a_ParamIdx, "Vector3") || + IsParamUserType(a_ParamIdx, "Vector3") || + lua_istable(m_LuaState, a_ParamIdx) // Assume any table is good enough + ); } -- cgit v1.2.3