Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(WIP) Separate ElunaTemplate and Method registration #227

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/LuaEngine/ElunaIncludes.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ typedef Opcodes OpcodesList;

/*
* Note: if you add or change a CORE_NAME or CORE_VERSION #define,
* please update LuaGlobalFunctions::GetCoreName or LuaGlobalFunctions::GetCoreVersion documentation example string.
* please update LuaGlobal::GetCoreName or LuaGlobal::GetCoreVersion documentation example string.
*/
#define CORE_NAME "AzerothCore"

Expand Down
51 changes: 51 additions & 0 deletions src/LuaEngine/ElunaTemplate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2010 - 2024 Eluna Lua Engine <https://elunaluaengine.github.io/>
* This program is free software licensed under GPL version 3
* Please see the included DOCS/LICENSE.md for more information
*/

// Eluna
#include "LuaEngine.h"
#include "ElunaIncludes.h"
#include "ElunaTemplate.h"
#include "ElunaUtility.h"

// fix compile error about accessing vehicle destructor
template<> int ElunaTemplate<Vehicle>::CollectGarbage(lua_State* L)
{
ASSERT(!manageMemory);

// Get object pointer (and check type, no error)
ElunaObject* obj = Eluna::CHECKOBJ<ElunaObject>(L, 1, false);
delete obj;
return 0;
}

template<> inline int ElunaTemplate<unsigned long long>::Add(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::plus()); }
template<> inline int ElunaTemplate<unsigned long long>::Subtract(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::minus()); }
template<> inline int ElunaTemplate<unsigned long long>::Multiply(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::multiplies()); }
template<> inline int ElunaTemplate<unsigned long long>::Divide(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::divides()); }
template<> inline int ElunaTemplate<unsigned long long>::Mod(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::modulus()); }
template<> inline int ElunaTemplate<unsigned long long>::Equal(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::equal_to()); }
template<> inline int ElunaTemplate<unsigned long long>::Less(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::less()); }
template<> inline int ElunaTemplate<unsigned long long>::LessOrEqual(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::less_equal()); }
template<> inline int ElunaTemplate<unsigned long long>::ToString(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::ToString(L); }
template<> inline int ElunaTemplate<unsigned long long>::Pow(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::Pow(L); }

template<> inline int ElunaTemplate<long long>::Add(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::plus()); }
template<> inline int ElunaTemplate<long long>::Subtract(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::minus()); }
template<> inline int ElunaTemplate<long long>::Multiply(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::multiplies()); }
template<> inline int ElunaTemplate<long long>::Divide(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::divides()); }
template<> inline int ElunaTemplate<long long>::Mod(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::modulus()); }
template<> inline int ElunaTemplate<long long>::UnaryMinus(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::negate()); }
template<> inline int ElunaTemplate<long long>::Equal(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::equal_to()); }
template<> inline int ElunaTemplate<long long>::Less(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::less()); }
template<> inline int ElunaTemplate<long long>::LessOrEqual(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::less_equal()); }
template<> inline int ElunaTemplate<long long>::ToString(lua_State* L) { return ElunaTemplateHelper<long long>::ToString(L); }
template<> inline int ElunaTemplate<long long>::Pow(lua_State* L) { return ElunaTemplateHelper<long long>::Pow(L); }

template<> inline int ElunaTemplate<ObjectGuid>::Equal(lua_State* L) { Eluna::Push(L, Eluna::CHECKVAL<ObjectGuid>(L, 1) == Eluna::CHECKVAL<ObjectGuid>(L, 2)); return 1; }
template<> inline int ElunaTemplate<ObjectGuid>::ToString(lua_State* L)
{
Eluna::Push(L, Eluna::CHECKVAL<ObjectGuid>(L, 1).ToString());
}
50 changes: 43 additions & 7 deletions src/LuaEngine/ElunaTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,14 @@ class ElunaObject
const char* type_name;
};

template<typename T>
template<typename T = void>
struct ElunaRegister
{
const char* name;
int(*mfunc)(lua_State*, T*);
};

template<typename T>
template<typename T = void>
class ElunaTemplate
{
public:
Expand Down Expand Up @@ -170,7 +170,7 @@ class ElunaTemplate
lua_setfield(E->L, metatable, "__add");

// make new indexes saved to methods
lua_pushcfunction(E->L, Substract);
lua_pushcfunction(E->L, Subtract);
lua_setfield(E->L, metatable, "__sub");

// make new indexes saved to methods
Expand Down Expand Up @@ -347,9 +347,8 @@ class ElunaTemplate
{
// Get object pointer (and check type, no error)
ElunaObject* obj = Eluna::CHECKOBJ<ElunaObject>(L, 1, false);
if (obj && manageMemory)
delete static_cast<T*>(obj->GetObj());
delete obj;
obj->~ElunaObject();

return 0;
}

Expand All @@ -363,7 +362,7 @@ class ElunaTemplate
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); }
Expand All @@ -375,6 +374,9 @@ class ElunaTemplate
static int Less(lua_State* L) { return CompareError(L); }
static int LessOrEqual(lua_State* L) { return CompareError(L); }
static int Call(lua_State* L) { return luaL_error(L, "attempt to call a %s value", tname); }

static int MethodWrongState(lua_State* L) { luaL_error(L, "attempt to call method '%s' that does not exist for state: %d", lua_tostring(L, lua_upvalueindex(1)), lua_tointeger(L, lua_upvalueindex(2))); return 0; }
static int MethodUnimpl(lua_State* L) { luaL_error(L, "attempt to call method '%s' that is not implemented for this emulator", lua_tostring(L, lua_upvalueindex(1))); return 0; }
};

template<typename T>
Expand All @@ -386,4 +388,38 @@ ElunaObject::ElunaObject(T * obj, bool manageMemory) : callstackid(1), _invalida
template<typename T> const char* ElunaTemplate<T>::tname = NULL;
template<typename T> bool ElunaTemplate<T>::manageMemory = false;

template <typename T>
class ElunaTemplateHelper
{
public:
static int PerformOp(lua_State* L, std::function<T(T, T)> op)
{
T val1 = Eluna::CHECKVAL<T>(L, 1);
T val2 = Eluna::CHECKVAL<T>(L, 2);
Eluna::Push(L, op(val1, val2));
return 1;
}
static int PerformOp(lua_State* L, std::function<T(T)> op)
{
T val = Eluna::CHECKVAL<T>(L, 1);
Eluna::Push(L, op(val));
return 1;
}
static int ToString(lua_State* L)
{
T val = Eluna::CHECKVAL<T>(L, 1);
std::ostringstream ss;
ss << val;
Eluna::Push(L, ss.str());
return 1;
}
static int Pow(lua_State* L)
{
T val1 = Eluna::CHECKVAL<T>(L, 1);
T val2 = Eluna::CHECKVAL<T>(L, 2);
Eluna::Push(L, static_cast<T>(powl(static_cast<long double>(val1), static_cast<long double>(val2))));
return 1;
}
};

#endif
4 changes: 2 additions & 2 deletions src/LuaEngine/LuaEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ bool Eluna::reload = false;
bool Eluna::initialized = false;
Eluna::LockType Eluna::lock;

extern void RegisterFunctions(Eluna* E);
extern void RegisterMethods(Eluna* E);

void Eluna::Initialize()
{
Expand Down Expand Up @@ -221,7 +221,7 @@ void Eluna::OpenLua()
// open additional lua libraries

// Register methods and functions
RegisterFunctions(this);
RegisterMethods(this);

// Set lua require folder paths (scripts folder structure)
lua_getglobal(L, "package");
Expand Down
Loading