diff --git a/ElunaTemplate.h b/ElunaTemplate.h index 4cbf77f7d0..63ff4f91c3 100644 --- a/ElunaTemplate.h +++ b/ElunaTemplate.h @@ -227,7 +227,7 @@ class ElunaTemplate lua_setfield(L, metatable, "__add"); // make new indexes saved to methods - lua_pushcfunction(L, Substract); + lua_pushcfunction(L, Subtract); lua_setfield(L, metatable, "__sub"); // make new indexes saved to methods @@ -474,10 +474,54 @@ class ElunaTemplate return 1; } + template + static int PerformBinaryOp(lua_State* L, std::function binaryOp) + { + Eluna* E = Eluna::GetEluna(L); + + T val1 = E->CHECKVAL(1); + T val2 = E->CHECKVAL(2); + E->Push(binaryOp(val1, val2)); + return 1; + } + + template + static int PerformUnaryOp(lua_State* L, std::function unaryOp) + { + Eluna* E = Eluna::GetEluna(L); + + T val1 = E->CHECKVAL(1); + E->Push(unaryOp(val1)); + return 1; + } + + template + static int ToStringHelper(lua_State* L) + { + Eluna* E = Eluna::GetEluna(L); + + T val = E->CHECKVAL(1); + std::ostringstream ss; + ss << val; + E->Push(ss.str()); + return 1; + } + + template + static int PowHelper(lua_State* L) + { + Eluna* E = Eluna::GetEluna(L); + + T val1 = E->CHECKVAL(1); + T val2 = E->CHECKVAL(2); + E->Push(static_cast(powl(static_cast(val1), static_cast(val2)))); + return 1; + } + static int ArithmeticError(lua_State* L) { return luaL_error(L, "attempt to perform arithmetic on a %s value", tname); } static int CompareError(lua_State* L) { return luaL_error(L, "attempt to compare %s", tname); } static int Add(lua_State* L) { return ArithmeticError(L); } - static int Substract(lua_State* L) { return ArithmeticError(L); } + static int Subtract(lua_State* L) { return ArithmeticError(L); } static int Multiply(lua_State* L) { return ArithmeticError(L); } static int Divide(lua_State* L) { return ArithmeticError(L); } static int Mod(lua_State* L) { return ArithmeticError(L); } diff --git a/LuaFunctions.cpp b/LuaFunctions.cpp index 6ad9873429..df9522df28 100644 --- a/LuaFunctions.cpp +++ b/LuaFunctions.cpp @@ -1,5 +1,5 @@ /* -* Copyright (C) 2010 - 2023 Eluna Lua Engine +* Copyright (C) 2010 - 2024 Eluna Lua Engine * This program is free software licensed under GPL version 3 * Please see the included DOCS/LICENSE.md for more information */ @@ -78,71 +78,6 @@ ElunaConstrainedObjectRef GetWeakPtrFor(Vehicle const* obj) #endif #endif -// Template by Mud from http://stackoverflow.com/questions/4484437/lua-integer-type/4485511#4485511 -template<> int ElunaTemplate::Add(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) + E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::Substract(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) - E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::Multiply(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) * E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::Divide(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) / E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::Mod(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) % E->CHECKVAL(2)); return 1; } -// template<> int ElunaTemplate::UnaryMinus(lua_State* L) { Eluna::GetEluna(L)->Push(-E->CHECKVAL(L, 1)); return 1; } -template<> int ElunaTemplate::Equal(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) == E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::Less(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) < E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::LessOrEqual(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) <= E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::Pow(lua_State* L) -{ - Eluna* E = Eluna::GetEluna(L); - E->Push(static_cast(powl(static_cast(E->CHECKVAL(1)), static_cast(E->CHECKVAL(2))))); - return 1; -} -template<> int ElunaTemplate::ToString(lua_State* L) -{ - Eluna* E = Eluna::GetEluna(L); - - unsigned long long l = E->CHECKVAL(1); - std::ostringstream ss; - ss << l; - E->Push(ss.str()); - return 1; -} - -template<> int ElunaTemplate::Add(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) + E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::Substract(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) - E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::Multiply(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) * E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::Divide(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) / E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::Mod(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) % E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::UnaryMinus(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(-E->CHECKVAL(1)); return 1; } -template<> int ElunaTemplate::Equal(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) == E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::Less(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) < E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::LessOrEqual(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) <= E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::Pow(lua_State* L) -{ - Eluna* E = Eluna::GetEluna(L); - E->Push(static_cast(powl(static_cast(E->CHECKVAL(1)), static_cast(E->CHECKVAL(2))))); - return 1; -} -template<> int ElunaTemplate::ToString(lua_State* L) -{ - Eluna* E = Eluna::GetEluna(L); - - long long l = E->CHECKVAL(1); - std::ostringstream ss; - ss << l; - E->Push(ss.str()); - return 1; -} - -template<> int ElunaTemplate::Equal(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) == E->CHECKVAL(2)); return 1; } -template<> int ElunaTemplate::ToString(lua_State* L) -{ - Eluna* E = Eluna::GetEluna(L); -#if defined ELUNA_TRINITY - E->Push(E->CHECKVAL(1).ToString()); -#else - E->Push(E->CHECKVAL(1).GetString()); -#endif - return 1; -} - void RegisterFunctions(Eluna* E) { ElunaTemplate<>::SetMethods(E, LuaGlobalFunctions::GlobalMethods); @@ -225,3 +160,38 @@ void RegisterFunctions(Eluna* E) LuaVal::Register(E->L); } + +template<> int ElunaTemplate::Add(lua_State* L) { return PerformBinaryOp(L, std::plus()); } +template<> int ElunaTemplate::Subtract(lua_State* L) { return PerformBinaryOp(L, std::minus()); } +template<> int ElunaTemplate::Multiply(lua_State* L) { return PerformBinaryOp(L, std::multiplies()); } +template<> int ElunaTemplate::Divide(lua_State* L) { return PerformBinaryOp(L, std::divides()); } +template<> int ElunaTemplate::Mod(lua_State* L) { return PerformBinaryOp(L, std::modulus()); } +template<> int ElunaTemplate::Equal(lua_State* L) { return PerformBinaryOp(L, std::equal_to()); } +template<> int ElunaTemplate::Less(lua_State* L) { return PerformBinaryOp(L, std::less()); } +template<> int ElunaTemplate::LessOrEqual(lua_State* L) { return PerformBinaryOp(L, std::less_equal()); } +template<> int ElunaTemplate::ToString(lua_State* L) { return ToStringHelper(L); } +template<> int ElunaTemplate::Pow(lua_State* L) { return PowHelper(L); } + +template<> int ElunaTemplate::Add(lua_State* L) { return PerformBinaryOp(L, std::plus()); } +template<> int ElunaTemplate::Subtract(lua_State* L) { return PerformBinaryOp(L, std::minus()); } +template<> int ElunaTemplate::Multiply(lua_State* L) { return PerformBinaryOp(L, std::multiplies()); } +template<> int ElunaTemplate::Divide(lua_State* L) { return PerformBinaryOp(L, std::divides()); } +template<> int ElunaTemplate::Mod(lua_State* L) { return PerformBinaryOp(L, std::modulus()); } +template<> int ElunaTemplate::UnaryMinus(lua_State* L) { return PerformUnaryOp(L, std::negate()); } +template<> int ElunaTemplate::Equal(lua_State* L) { return PerformBinaryOp(L, std::equal_to()); } +template<> int ElunaTemplate::Less(lua_State* L) { return PerformBinaryOp(L, std::less()); } +template<> int ElunaTemplate::LessOrEqual(lua_State* L) { return PerformBinaryOp(L, std::less_equal()); } +template<> int ElunaTemplate::ToString(lua_State* L) { return ToStringHelper(L); } +template<> int ElunaTemplate::Pow(lua_State* L) { return PowHelper(L); } + +template<> int ElunaTemplate::Equal(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL(1) == E->CHECKVAL(2)); return 1; } +template<> int ElunaTemplate::ToString(lua_State* L) +{ + Eluna* E = Eluna::GetEluna(L); +#if defined ELUNA_TRINITY + E->Push(E->CHECKVAL(1).ToString()); +#else + E->Push(E->CHECKVAL(1).GetString()); +#endif + return 1; +}