Lua: moved hook functions into their own file

This commit is contained in:
MysterD 2022-01-21 19:40:26 -08:00
parent 34e903b89a
commit 0626c77048
7 changed files with 182 additions and 167 deletions

View file

@ -512,6 +512,7 @@
<ClCompile Include="..\src\pc\lua\smlua_cobject.c" />
<ClCompile Include="..\src\pc\lua\smlua_functions.c" />
<ClCompile Include="..\src\pc\lua\smlua_functions_autogen.c" />
<ClCompile Include="..\src\pc\lua\smlua_hooks.c" />
<ClCompile Include="..\src\pc\lua\smlua_utils.c" />
<ClCompile Include="..\src\pc\mixer.c" />
<ClCompile Include="..\src\pc\network\discord\activity.c" />
@ -958,6 +959,7 @@
<ClInclude Include="..\src\pc\lua\smlua_cobject.h" />
<ClInclude Include="..\src\pc\lua\smlua_functions.h" />
<ClInclude Include="..\src\pc\lua\smlua_functions_autogen.h" />
<ClInclude Include="..\src\pc\lua\smlua_hooks.h" />
<ClInclude Include="..\src\pc\lua\smlua_utils.h" />
<ClInclude Include="..\src\pc\network\branch.h" />
<ClInclude Include="..\src\pc\network\discord\activity.h" />

View file

@ -4833,6 +4833,9 @@
<ClCompile Include="..\src\game\level_info.c">
<Filter>Source Files\src\game</Filter>
</ClCompile>
<ClCompile Include="..\src\pc\lua\smlua_hooks.c">
<Filter>Source Files\src\pc\lua</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\actors\common0.h">
@ -5956,5 +5959,8 @@
<ClInclude Include="..\src\game\level_info.h">
<Filter>Source Files\src\game</Filter>
</ClInclude>
<ClInclude Include="..\src\pc\lua\smlua_hooks.h">
<Filter>Source Files\src\pc\lua</Filter>
</ClInclude>
</ItemGroup>
</Project>

View file

@ -2,135 +2,6 @@
lua_State* gLuaState = NULL;
///////////////////
// hooked events //
///////////////////
#define MAX_HOOKED_REFERENCES 64
struct LuaHookedEvent {
int reference[MAX_HOOKED_REFERENCES];
int count;
};
static struct LuaHookedEvent sHookedEvents[HOOK_MAX] = { 0 };
int smlua_hook_event(lua_State* L) {
u16 hookType = lua_tointeger(L, -2);
if (hookType >= HOOK_MAX) {
LOG_LUA("LUA: Hook Type: %d exceeds max!", hookType);
return 0;
}
struct LuaHookedEvent* hook = &sHookedEvents[hookType];
if (hook->count >= MAX_HOOKED_REFERENCES) {
LOG_LUA("LUA: Hook Type: %d exceeded maximum references!", hookType);
return 0;
}
hook->reference[hook->count] = luaL_ref(L, LUA_REGISTRYINDEX);
hook->count++;
return 1;
}
void smlua_call_event_hooks(enum LuaHookedEventType hookType) {
lua_State* L = gLuaState;
struct LuaHookedEvent* hook = &sHookedEvents[hookType];
for (int i = 0; i < hook->count; i++) {
// push the callback onto the stack
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
// call the callback
if (0 != lua_pcall(L, 0, 0, 0)) {
LOG_LUA("LUA: Failed to call the callback: %s", lua_tostring(L, -1));
continue;
}
}
}
void smlua_call_event_hooks_mario_param(enum LuaHookedEventType hookType, struct MarioState* m) {
lua_State* L = gLuaState;
struct LuaHookedEvent* hook = &sHookedEvents[hookType];
for (int i = 0; i < hook->count; i++) {
// push the callback onto the stack
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
// push mario state
lua_getglobal(L, "gMarioStates");
lua_pushinteger(L, m->playerIndex);
lua_gettable(L, -2);
lua_remove(L, -2);
// call the callback
if (0 != lua_pcall(L, 1, 0, 0)) {
LOG_LUA("LUA: Failed to call the callback: %s", lua_tostring(L, -1));
continue;
}
}
}
////////////////////
// hooked actions //
////////////////////
struct LuaHookedMarioAction {
u32 action;
int reference;
};
#define MAX_HOOKED_ACTIONS 64
static struct LuaHookedMarioAction sHookedMarioActions[MAX_HOOKED_ACTIONS] = { 0 };
static int sHookedMarioActionsCount = 0;
int smlua_hook_mario_action(lua_State* L) {
if (sHookedMarioActionsCount >= MAX_HOOKED_ACTIONS) {
LOG_LUA("LUA: Hooked mario actions exceeded maximum references!");
return 0;
}
struct LuaHookedMarioAction* hooked = &sHookedMarioActions[sHookedMarioActionsCount];
hooked->action = lua_tointeger(L, -2);
hooked->reference = luaL_ref(L, LUA_REGISTRYINDEX);
sHookedMarioActionsCount++;
return 1;
}
bool smlua_call_action_hook(struct MarioState* m, s32* returnValue) {
lua_State* L = gLuaState;
for (int i = 0; i < sHookedMarioActionsCount; i++) {
if (sHookedMarioActions[i].action == m->action) {
// push the callback onto the stack
lua_rawgeti(L, LUA_REGISTRYINDEX, sHookedMarioActions[i].reference);
// push mario state
lua_getglobal(L, "gMarioStates");
lua_pushinteger(L, m->playerIndex);
lua_gettable(L, -2);
lua_remove(L, -2);
// call the callback
if (0 != lua_pcall(L, 1, 1, 0)) {
LOG_LUA("LUA: Failed to call the callback: %s", lua_tostring(L, -1));
continue;
}
// output the return value
*returnValue = lua_tointeger(L, -1);
lua_pop(L, 1);
return true;
}
}
return false;
}
//////////
// main //
//////////
static void smlua_execfile(char* path) {
lua_State* L = gLuaState;
if (luaL_dofile(L, path) != LUA_OK) {
@ -168,12 +39,7 @@ void smlua_init(void) {
luaL_requiref(L, "table", luaopen_table, 1);
//luaopen_utf8(L);
lua_pushcfunction(L, smlua_hook_event);
lua_setglobal(L, "hook_event");
lua_pushcfunction(L, smlua_hook_mario_action);
lua_setglobal(L, "hook_mario_action");
smlua_bind_hooks();
smlua_bind_cobject();
smlua_bind_functions();
smlua_bind_functions_autogen();
@ -190,18 +56,4 @@ void smlua_update(void) {
void smlua_shutdown(void) {
lua_State* L = gLuaState;
lua_close(L);
for (int i = 0; i < HOOK_MAX; i++) {
for (int j = 0; j < sHookedEvents[i].count; j++) {
sHookedEvents[i].reference[j] = 0;
}
sHookedEvents[i].count = 0;
}
for (int i = 0; i < sHookedMarioActionsCount; i++) {
sHookedMarioActions[i].action = 0;
sHookedMarioActions[i].reference = 0;
}
sHookedMarioActionsCount = 0;
}

View file

@ -11,25 +11,14 @@
#include "smlua_utils.h"
#include "smlua_functions.h"
#include "smlua_functions_autogen.h"
#include "smlua_hooks.h"
#include "pc/debuglog.h"
#define LOG_LUA LOG_INFO
enum LuaHookedEventType {
HOOK_UPDATE,
HOOK_MARIO_UPDATE,
HOOK_BEFORE_MARIO_UPDATE,
HOOK_MAX,
};
extern lua_State* gLuaState;
void smlua_call_event_hooks(enum LuaHookedEventType hookType);
void smlua_call_event_hooks_mario_param(enum LuaHookedEventType hookType, struct MarioState* m);
bool smlua_call_action_hook(struct MarioState* m, s32* returnValue);
void smlua_init(void);
void smlua_update(void);
void smlua_shutdown(void);

View file

@ -388,10 +388,7 @@ static int smlua__set_field(lua_State* L) {
void smlua_bind_cobject(void) {
lua_State* L = gLuaState;
lua_pushcfunction(L, smlua__get_field);
lua_setglobal(L, "_get_field");
lua_pushcfunction(L, smlua__set_field);
lua_setglobal(L, "_set_field");
smlua_bind_function(L, "_get_field", smlua__get_field);
smlua_bind_function(L, "_set_field", smlua__set_field);
}

150
src/pc/lua/smlua_hooks.c Normal file
View file

@ -0,0 +1,150 @@
#include "smlua.h"
#define MAX_HOOKED_REFERENCES 64
struct LuaHookedEvent {
int reference[MAX_HOOKED_REFERENCES];
int count;
};
static struct LuaHookedEvent sHookedEvents[HOOK_MAX] = { 0 };
int smlua_hook_event(lua_State* L) {
u16 hookType = lua_tointeger(L, -2);
if (hookType >= HOOK_MAX) {
LOG_LUA("LUA: Hook Type: %d exceeds max!", hookType);
return 0;
}
struct LuaHookedEvent* hook = &sHookedEvents[hookType];
if (hook->count >= MAX_HOOKED_REFERENCES) {
LOG_LUA("LUA: Hook Type: %d exceeded maximum references!", hookType);
return 0;
}
hook->reference[hook->count] = luaL_ref(L, LUA_REGISTRYINDEX);
hook->count++;
return 1;
}
void smlua_call_event_hooks(enum LuaHookedEventType hookType) {
lua_State* L = gLuaState;
struct LuaHookedEvent* hook = &sHookedEvents[hookType];
for (int i = 0; i < hook->count; i++) {
// push the callback onto the stack
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
// call the callback
if (0 != lua_pcall(L, 0, 0, 0)) {
LOG_LUA("LUA: Failed to call the callback: %s", lua_tostring(L, -1));
continue;
}
}
}
void smlua_call_event_hooks_mario_param(enum LuaHookedEventType hookType, struct MarioState* m) {
lua_State* L = gLuaState;
struct LuaHookedEvent* hook = &sHookedEvents[hookType];
for (int i = 0; i < hook->count; i++) {
// push the callback onto the stack
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
// push mario state
lua_getglobal(L, "gMarioStates");
lua_pushinteger(L, m->playerIndex);
lua_gettable(L, -2);
lua_remove(L, -2);
// call the callback
if (0 != lua_pcall(L, 1, 0, 0)) {
LOG_LUA("LUA: Failed to call the callback: %s", lua_tostring(L, -1));
continue;
}
}
}
////////////////////
// hooked actions //
////////////////////
struct LuaHookedMarioAction {
u32 action;
int reference;
};
#define MAX_HOOKED_ACTIONS 64
static struct LuaHookedMarioAction sHookedMarioActions[MAX_HOOKED_ACTIONS] = { 0 };
static int sHookedMarioActionsCount = 0;
int smlua_hook_mario_action(lua_State* L) {
if (sHookedMarioActionsCount >= MAX_HOOKED_ACTIONS) {
LOG_LUA("LUA: Hooked mario actions exceeded maximum references!");
return 0;
}
struct LuaHookedMarioAction* hooked = &sHookedMarioActions[sHookedMarioActionsCount];
hooked->action = lua_tointeger(L, -2);
hooked->reference = luaL_ref(L, LUA_REGISTRYINDEX);
sHookedMarioActionsCount++;
return 1;
}
bool smlua_call_action_hook(struct MarioState* m, s32* returnValue) {
lua_State* L = gLuaState;
for (int i = 0; i < sHookedMarioActionsCount; i++) {
if (sHookedMarioActions[i].action == m->action) {
// push the callback onto the stack
lua_rawgeti(L, LUA_REGISTRYINDEX, sHookedMarioActions[i].reference);
// push mario state
lua_getglobal(L, "gMarioStates");
lua_pushinteger(L, m->playerIndex);
lua_gettable(L, -2);
lua_remove(L, -2);
// call the callback
if (0 != lua_pcall(L, 1, 1, 0)) {
LOG_LUA("LUA: Failed to call the callback: %s", lua_tostring(L, -1));
continue;
}
// output the return value
*returnValue = lua_tointeger(L, -1);
lua_pop(L, 1);
return true;
}
}
return false;
}
//////////
// misc //
//////////
static void smlua_clear_hooks(void) {
for (int i = 0; i < HOOK_MAX; i++) {
for (int j = 0; j < sHookedEvents[i].count; j++) {
sHookedEvents[i].reference[j] = 0;
}
sHookedEvents[i].count = 0;
}
for (int i = 0; i < sHookedMarioActionsCount; i++) {
sHookedMarioActions[i].action = 0;
sHookedMarioActions[i].reference = 0;
}
sHookedMarioActionsCount = 0;
}
void smlua_bind_hooks(void) {
lua_State* L = gLuaState;
smlua_clear_hooks();
smlua_bind_function(L, "hook_event", smlua_hook_event);
smlua_bind_function(L, "hook_mario_action", smlua_hook_mario_action);
}

19
src/pc/lua/smlua_hooks.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef SMLUA_HOOKS_H
#define SMLUA_HOOKS_H
#include <stdbool.h>
enum LuaHookedEventType {
HOOK_UPDATE,
HOOK_MARIO_UPDATE,
HOOK_BEFORE_MARIO_UPDATE,
HOOK_MAX,
};
void smlua_call_event_hooks(enum LuaHookedEventType hookType);
void smlua_call_event_hooks_mario_param(enum LuaHookedEventType hookType, struct MarioState* m);
bool smlua_call_action_hook(struct MarioState* m, s32* returnValue);
void smlua_bind_hooks(void);
#endif