refactor: Drop loadstring for hooks

This commit is contained in:
Lucas Schwiderski 2023-02-22 14:48:47 +01:00
parent 09c0d3a5ae
commit 36afe1466c
Signed by: lucas
GPG key ID: AA12679AAA6DF4D8
2 changed files with 27 additions and 46 deletions

View file

@ -30,23 +30,24 @@ end
-- --
-- Get function by function name -- Get function by function name
-- --
local function get_func(func_name) local function get_func(obj, func_name)
return assert(loadstring("return " .. func_name))() return obj[func_name]
end end
-- --
-- Get item by function name -- Get item by function name
-- --
local function get_item(func_name) local function get_item(obj, func_name)
-- Find existing item -- Find existing item
for _, item in ipairs(MODS_HOOKS) do for _, item in ipairs(MODS_HOOKS) do
if item.name == func_name then if item.obj == obj and item.name == func_name then
return item return item
end end
end end
-- Create new item -- Create new item
local item = table.clone(item_template) local item = table.clone(item_template)
item.obj = obj
item.name = func_name item.name = func_name
item.func = get_func(func_name) item.func = get_func(func_name)
@ -82,48 +83,30 @@ end
-- --
local function patch() local function patch()
for i, item in ipairs(MODS_HOOKS) do for i, item in ipairs(MODS_HOOKS) do
local item_name = "MODS_HOOKS[" .. i .. "]"
local last_j = 1 local last_j = 1
for j, hook in ipairs(item.hooks) do for j, hook in ipairs(item.hooks) do
local hook_name = item_name .. ".hooks[" .. j .. "]" local is_first_hook = j == 1
local before_hook_name = item_name .. ".hooks[" .. (j - 1) .. "]" if is_first_hook then
if j == 1 then
if hook.enable then if hook.enable then
assert( MODS_HOOKS[i].hooks[j].exec = function(...)
loadstring( local mod_hook = MODS_HOOKS[i]
hook_name .. ".exec = function(...)" .. return mod_hook.hooks[j].func(mod_hook.func, ...)
" return " .. hook_name .. ".func(" .. item_name .. ".func, ...)" .. end
"end"
)
)()
else else
assert( MODS_HOOKS[i].hooks[j].exec = function(...)
loadstring( return MODS_HOOKS[i].func(...)
hook_name .. ".exec = function(...)" .. end
" return " .. item_name .. ".func(...)" ..
"end"
)
)()
end end
else else
if hook.enable then if hook.enable then
assert( MODS_HOOKS[i].hooks[j].exec = function(...)
loadstring( local mod_hook = MODS_HOOKS[i]
hook_name .. ".exec = function(...)" .. return mod_hook.hooks[j].func(mod_hook.hooks[j - 1].exec, ...)
" return " .. hook_name .. ".func(" .. before_hook_name .. ".exec, ...)" .. end
"end"
)
)()
else else
assert( MODS_HOOKS[i].hooks[j].exec = function(...)
loadstring( return MODS_HOOKS[i].hooks[j - 1].exec(...)
hook_name .. ".exec = function(...)" .. end
" return " .. before_hook_name .. ".exec(...)" ..
"end"
)
)()
end end
end end
@ -131,7 +114,7 @@ local function patch()
end end
-- Patch orginal function call -- Patch orginal function call
assert(loadstring(item.name .. " = " .. item_name .. ".hooks[" .. last_j .. "].exec"))() item.obj[item.name] = MODS_HOOKS[i].hooks[last_j].exec
end end
end end
@ -225,10 +208,8 @@ local function remove(func_name, mod_name)
end end
end end
else else
local item_name = "MODS_HOOKS[" .. tostring(i) .. "]"
-- Restore orginal function -- Restore orginal function
assert(loadstring(item.name .. " = " .. item_name .. ".func"))() item.obj[item.name] = MODS_HOOKS[i].func
-- Remove hook function -- Remove hook function
table.remove(MODS_HOOKS, i) table.remove(MODS_HOOKS, i)

View file

@ -20,13 +20,13 @@ function loader:init(libs, mod_data, boot_gui)
-- The mod loader needs to remain active during game play, to -- The mod loader needs to remain active during game play, to
-- enable reloads -- enable reloads
Mods.hook.set("DML", "StateGame.update", function(func, dt, ...) Mods.hook.set("DML", GameState, "update", function(func, dt, ...)
mod_loader:update(dt) mod_loader:update(dt)
return func(dt, ...) return func(dt, ...)
end) end)
-- Skip splash view -- Skip splash view
Mods.hook.set("Base", "StateSplash.on_enter", function(func, self, ...) Mods.hook.set("Base", StateSplash, "on_enter", function(func, self, ...)
local result = func(self, ...) local result = func(self, ...)
self._should_skip = true self._should_skip = true
@ -36,7 +36,7 @@ function loader:init(libs, mod_data, boot_gui)
end) end)
-- Trigger state change events -- Trigger state change events
Mods.hook.set("Base", "GameStateMachine._change_state", function(func, self, ...) Mods.hook.set("Base", GameStateMachine, "_change_state", function(func, self, ...)
local old_state = self._state local old_state = self._state
local old_state_name = old_state and self:current_state_name() local old_state_name = old_state and self:current_state_name()
@ -57,7 +57,7 @@ function loader:init(libs, mod_data, boot_gui)
end) end)
-- Trigger ending state change event -- Trigger ending state change event
Mods.hook.set("Base", "GameStateMachine.destroy", function(func, self, ...) Mods.hook.set("Base", GameStateMachine, "destroy", function(func, self, ...)
local old_state = self._state local old_state = self._state
local old_state_name = old_state and self:current_state_name() local old_state_name = old_state and self:current_state_name()