Skip to content

Commit dd15602

Browse files
AGrabertheSpool
authored andcommitted
Use templates to generate an array of natives
* Each native is specifically bound to a string so it acts as a unique native, which plays good with multiple plugins
1 parent bccc107 commit dd15602

File tree

1 file changed

+40
-7
lines changed

1 file changed

+40
-7
lines changed

amx-deps/src/syscalls.cpp

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,7 @@ extern map < string, HMODULE > loadedPlugins;
1010

1111
AMX_NATIVE_INFO *sampNatives = NULL;
1212

13-
static cell AMX_NATIVE_CALL n_samp(AMX *amx, const cell *params) {
14-
char fnName[128];
15-
*fnName = 0;
16-
if(amx_GetNative(amx, *(cell *)(amx->code + amx->cip - sizeof(cell)), fnName) != AMX_ERR_NONE)
17-
return 0;
18-
13+
static cell AMX_NATIVE_CALL n_samp(AMX *amx, const cell *params, const char* fnName) {
1914
int mainTop = lua_gettop(mainVM);
2015

2116
lua_getglobal(mainVM, "syscall");
@@ -66,6 +61,36 @@ static cell AMX_NATIVE_CALL n_samp(AMX *amx, const cell *params) {
6661
}
6762
}
6863

64+
65+
66+
constexpr size_t MAX_SAMP_NATIVES = 700; // Should be enough for now
67+
68+
const char** boundNativeNames[MAX_SAMP_NATIVES];
69+
AMX_NATIVE boundNatives[MAX_SAMP_NATIVES];
70+
71+
template<size_t index>
72+
struct NativeGenerator {
73+
static const char* BoundNativeName;
74+
75+
static cell AMX_NATIVE_CALL DoNative(AMX* amx, const cell* params) {
76+
return n_samp(amx, params, BoundNativeName);
77+
}
78+
79+
static void Generate() {
80+
boundNativeNames[index] = &BoundNativeName;
81+
boundNatives[index] = reinterpret_cast<AMX_NATIVE>(&DoNative);
82+
83+
NativeGenerator<index + 1>::Generate();
84+
}
85+
};
86+
87+
template<> struct NativeGenerator<MAX_SAMP_NATIVES> {
88+
static void Generate() {}
89+
};
90+
91+
template<size_t index>
92+
const char* NativeGenerator<index>::BoundNativeName = nullptr;
93+
6994
int callLuaMTRead(lua_State *luaVM) {
7095
luaL_checktype(luaVM, 1, LUA_TTABLE);
7196
lua_getfield(luaVM, 1, "amx");
@@ -438,6 +463,8 @@ void initSAMPSyscalls() {
438463
if(!mainVM || sampNatives)
439464
return;
440465

466+
NativeGenerator<0>::Generate();
467+
441468
lua_getglobal(mainVM, "g_SAMPSyscallPrototypes");
442469
int numNatives = 0;
443470
lua_pushnil(mainVM);
@@ -450,8 +477,14 @@ void initSAMPSyscalls() {
450477
int i = 0;
451478
lua_pushnil(mainVM);
452479
while(lua_next(mainVM, -2)) {
480+
if (i >= MAX_SAMP_NATIVES) {
481+
pModuleManager->ErrorPrintf("syscall count exceeded MAX_SAMP_NATIVES (%d) definition - Recompile with higher value");
482+
break;
483+
}
484+
485+
*boundNativeNames[i] = strdup(lua_tostring(mainVM, -2));
453486
sampNatives[i].name = strdup(lua_tostring(mainVM, -2));
454-
sampNatives[i].func = n_samp;
487+
sampNatives[i].func = boundNatives[i];
455488
lua_pop(mainVM, 1);
456489
i++;
457490
}

0 commit comments

Comments
 (0)