Skip to content

Commit edbc7e5

Browse files
committed
Separate ElunaTemplate and Method registration
1 parent 5d912ee commit edbc7e5

30 files changed

+1482
-1452
lines changed

src/LuaEngine/ElunaIncludes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ typedef Opcodes OpcodesList;
5656

5757
/*
5858
* Note: if you add or change a CORE_NAME or CORE_VERSION #define,
59-
* please update LuaGlobalFunctions::GetCoreName or LuaGlobalFunctions::GetCoreVersion documentation example string.
59+
* please update LuaGlobal::GetCoreName or LuaGlobal::GetCoreVersion documentation example string.
6060
*/
6161
#define CORE_NAME "AzerothCore"
6262

src/LuaEngine/ElunaTemplate.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (C) 2010 - 2024 Eluna Lua Engine <https://elunaluaengine.github.io/>
3+
* This program is free software licensed under GPL version 3
4+
* Please see the included DOCS/LICENSE.md for more information
5+
*/
6+
7+
// Eluna
8+
#include "LuaEngine.h"
9+
#include "ElunaIncludes.h"
10+
#include "ElunaTemplate.h"
11+
#include "ElunaUtility.h"
12+
13+
// fix compile error about accessing vehicle destructor
14+
template<> int ElunaTemplate<Vehicle>::CollectGarbage(lua_State* L)
15+
{
16+
ASSERT(!manageMemory);
17+
18+
// Get object pointer (and check type, no error)
19+
ElunaObject* obj = Eluna::CHECKOBJ<ElunaObject>(L, 1, false);
20+
delete obj;
21+
return 0;
22+
}
23+
24+
template<> inline int ElunaTemplate<unsigned long long>::Add(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::plus()); }
25+
template<> inline int ElunaTemplate<unsigned long long>::Subtract(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::minus()); }
26+
template<> inline int ElunaTemplate<unsigned long long>::Multiply(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::multiplies()); }
27+
template<> inline int ElunaTemplate<unsigned long long>::Divide(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::divides()); }
28+
template<> inline int ElunaTemplate<unsigned long long>::Mod(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::modulus()); }
29+
template<> inline int ElunaTemplate<unsigned long long>::Equal(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::equal_to()); }
30+
template<> inline int ElunaTemplate<unsigned long long>::Less(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::less()); }
31+
template<> inline int ElunaTemplate<unsigned long long>::LessOrEqual(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::less_equal()); }
32+
template<> inline int ElunaTemplate<unsigned long long>::ToString(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::ToString(L); }
33+
template<> inline int ElunaTemplate<unsigned long long>::Pow(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::Pow(L); }
34+
35+
template<> inline int ElunaTemplate<long long>::Add(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::plus()); }
36+
template<> inline int ElunaTemplate<long long>::Subtract(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::minus()); }
37+
template<> inline int ElunaTemplate<long long>::Multiply(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::multiplies()); }
38+
template<> inline int ElunaTemplate<long long>::Divide(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::divides()); }
39+
template<> inline int ElunaTemplate<long long>::Mod(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::modulus()); }
40+
template<> inline int ElunaTemplate<long long>::UnaryMinus(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::negate()); }
41+
template<> inline int ElunaTemplate<long long>::Equal(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::equal_to()); }
42+
template<> inline int ElunaTemplate<long long>::Less(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::less()); }
43+
template<> inline int ElunaTemplate<long long>::LessOrEqual(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::less_equal()); }
44+
template<> inline int ElunaTemplate<long long>::ToString(lua_State* L) { return ElunaTemplateHelper<long long>::ToString(L); }
45+
template<> inline int ElunaTemplate<long long>::Pow(lua_State* L) { return ElunaTemplateHelper<long long>::Pow(L); }
46+
47+
template<> inline int ElunaTemplate<ObjectGuid>::Equal(lua_State* L) { Eluna::Push(L, Eluna::CHECKVAL<ObjectGuid>(L, 1) == Eluna::CHECKVAL<ObjectGuid>(L, 2)); return 1; }
48+
template<> inline int ElunaTemplate<ObjectGuid>::ToString(lua_State* L)
49+
{
50+
Eluna::Push(L, Eluna::CHECKVAL<ObjectGuid>(L, 1).ToString());
51+
}

src/LuaEngine/ElunaTemplate.h

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,14 @@ class ElunaObject
112112
const char* type_name;
113113
};
114114

115-
template<typename T>
115+
template<typename T = void>
116116
struct ElunaRegister
117117
{
118118
const char* name;
119119
int(*mfunc)(lua_State*, T*);
120120
};
121121

122-
template<typename T>
122+
template<typename T = void>
123123
class ElunaTemplate
124124
{
125125
public:
@@ -170,7 +170,7 @@ class ElunaTemplate
170170
lua_setfield(E->L, metatable, "__add");
171171

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

176176
// make new indexes saved to methods
@@ -347,9 +347,8 @@ class ElunaTemplate
347347
{
348348
// Get object pointer (and check type, no error)
349349
ElunaObject* obj = Eluna::CHECKOBJ<ElunaObject>(L, 1, false);
350-
if (obj && manageMemory)
351-
delete static_cast<T*>(obj->GetObj());
352-
delete obj;
350+
obj->~ElunaObject();
351+
353352
return 0;
354353
}
355354

@@ -363,7 +362,7 @@ class ElunaTemplate
363362
static int ArithmeticError(lua_State* L) { return luaL_error(L, "attempt to perform arithmetic on a %s value", tname); }
364363
static int CompareError(lua_State* L) { return luaL_error(L, "attempt to compare %s", tname); }
365364
static int Add(lua_State* L) { return ArithmeticError(L); }
366-
static int Substract(lua_State* L) { return ArithmeticError(L); }
365+
static int Subtract(lua_State* L) { return ArithmeticError(L); }
367366
static int Multiply(lua_State* L) { return ArithmeticError(L); }
368367
static int Divide(lua_State* L) { return ArithmeticError(L); }
369368
static int Mod(lua_State* L) { return ArithmeticError(L); }
@@ -375,6 +374,9 @@ class ElunaTemplate
375374
static int Less(lua_State* L) { return CompareError(L); }
376375
static int LessOrEqual(lua_State* L) { return CompareError(L); }
377376
static int Call(lua_State* L) { return luaL_error(L, "attempt to call a %s value", tname); }
377+
378+
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; }
379+
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; }
378380
};
379381

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

391+
template <typename T>
392+
class ElunaTemplateHelper
393+
{
394+
public:
395+
static int PerformOp(lua_State* L, std::function<T(T, T)> op)
396+
{
397+
T val1 = Eluna::CHECKVAL<T>(L, 1);
398+
T val2 = Eluna::CHECKVAL<T>(L, 2);
399+
Eluna::Push(L, op(val1, val2));
400+
return 1;
401+
}
402+
static int PerformOp(lua_State* L, std::function<T(T)> op)
403+
{
404+
T val = Eluna::CHECKVAL<T>(L, 1);
405+
Eluna::Push(L, op(val));
406+
return 1;
407+
}
408+
static int ToString(lua_State* L)
409+
{
410+
T val = Eluna::CHECKVAL<T>(L, 1);
411+
std::ostringstream ss;
412+
ss << val;
413+
Eluna::Push(L, ss.str());
414+
return 1;
415+
}
416+
static int Pow(lua_State* L)
417+
{
418+
T val1 = Eluna::CHECKVAL<T>(L, 1);
419+
T val2 = Eluna::CHECKVAL<T>(L, 2);
420+
Eluna::Push(L, static_cast<T>(powl(static_cast<long double>(val1), static_cast<long double>(val2))));
421+
return 1;
422+
}
423+
};
424+
389425
#endif

src/LuaEngine/LuaEngine.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ bool Eluna::reload = false;
4545
bool Eluna::initialized = false;
4646
Eluna::LockType Eluna::lock;
4747

48-
extern void RegisterFunctions(Eluna* E);
48+
extern void RegisterMethods(Eluna* E);
4949

5050
void Eluna::Initialize()
5151
{
@@ -221,7 +221,7 @@ void Eluna::OpenLua()
221221
// open additional lua libraries
222222

223223
// Register methods and functions
224-
RegisterFunctions(this);
224+
RegisterMethods(this);
225225

226226
// Set lua require folder paths (scripts folder structure)
227227
lua_getglobal(L, "package");

0 commit comments

Comments
 (0)