Merge pull request #14 from FireSiku/new_hooks
Delay disabling delayed hooks and fix a crash
This commit is contained in:
commit
4b890a616a
2 changed files with 28 additions and 12 deletions
|
@ -6,9 +6,9 @@ local vmf = get_mod("VMF")
|
||||||
|
|
||||||
-- hook_type is an identifier to help distinguish the different api calls.
|
-- hook_type is an identifier to help distinguish the different api calls.
|
||||||
local HOOK_TYPES = {
|
local HOOK_TYPES = {
|
||||||
hook = 1,
|
hook = 1,
|
||||||
safe = 2,
|
hook_safe = 2,
|
||||||
origin = 3,
|
hook_origin = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Constants to ease on table lookups when not needed
|
-- Constants to ease on table lookups when not needed
|
||||||
|
@ -204,7 +204,7 @@ local function create_hook(self, orig, obj, method, handler, func_name, hook_typ
|
||||||
|
|
||||||
-- Check to make sure it wasn't hooked before
|
-- Check to make sure it wasn't hooked before
|
||||||
if not _registry[self][orig] then
|
if not _registry[self][orig] then
|
||||||
_registry[self][orig] = { active = true }
|
_registry[self][orig] = { active = self:is_enabled() }
|
||||||
|
|
||||||
local hook_registry = _registry.hooks[hook_type]
|
local hook_registry = _registry.hooks[hook_type]
|
||||||
-- Add to the hook to registry. Origin hooks are unique, so we check for that too.
|
-- Add to the hook to registry. Origin hooks are unique, so we check for that too.
|
||||||
|
@ -269,7 +269,7 @@ local function generic_hook(self, obj, method, handler, func_name)
|
||||||
if obj and not success then
|
if obj and not success then
|
||||||
if _delaying_enabled and type(obj) == "string" then
|
if _delaying_enabled and type(obj) == "string" then
|
||||||
-- Call this func at a later time, using upvalues.
|
-- Call this func at a later time, using upvalues.
|
||||||
vmf:info("(%s): [%s.%s] needs to be delayed.", func_name, obj, method)
|
self:info("(%s): [%s.%s] needs to be delayed.", func_name, obj, method)
|
||||||
table.insert(_delayed, function()
|
table.insert(_delayed, function()
|
||||||
generic_hook(self, obj, method, handler, func_name)
|
generic_hook(self, obj, method, handler, func_name)
|
||||||
end)
|
end)
|
||||||
|
@ -291,6 +291,11 @@ local function generic_hook(self, obj, method, handler, func_name)
|
||||||
|
|
||||||
-- obj can't be a string for these now.
|
-- obj can't be a string for these now.
|
||||||
local orig = get_orig_function(self, obj, method)
|
local orig = get_orig_function(self, obj, method)
|
||||||
|
if type(orig) ~= "function" then
|
||||||
|
self:error("(%s): trying to hook %s (a %s), not a function.", func_name, method, type(orig))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
return create_hook(self, orig, obj, method, handler, func_name, hook_type)
|
return create_hook(self, orig, obj, method, handler, func_name, hook_type)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -313,8 +318,17 @@ local function generic_hook_toggle(self, obj, method, enabled_state)
|
||||||
|
|
||||||
local obj, success = get_object_reference(obj) --luacheck: ignore
|
local obj, success = get_object_reference(obj) --luacheck: ignore
|
||||||
if obj and not success then
|
if obj and not success then
|
||||||
self:error("(%s): object doesn't exist.", func_name)
|
if _delaying_enabled and type(obj) == "string" then
|
||||||
return
|
-- Call this func at a later time, using upvalues.
|
||||||
|
self:info("(%s): [%s.%s] needs to be delayed.", func_name, obj, method)
|
||||||
|
table.insert(_delayed, function()
|
||||||
|
generic_hook_toggle(self, obj, method, enabled_state)
|
||||||
|
end)
|
||||||
|
return
|
||||||
|
else
|
||||||
|
self:error("(%s): trying to toggle hook on object that doesn't exist: %s", func_name, obj)
|
||||||
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local orig = get_orig_function(self, obj, method)
|
local orig = get_orig_function(self, obj, method)
|
||||||
|
@ -336,7 +350,7 @@ end
|
||||||
-- The handler is never given the a "func" parameter.
|
-- The handler is never given the a "func" parameter.
|
||||||
-- These will always be executed the original function and the hook chain.
|
-- These will always be executed the original function and the hook chain.
|
||||||
function VMFMod:hook_safe(obj, method, handler)
|
function VMFMod:hook_safe(obj, method, handler)
|
||||||
return generic_hook(self, obj, method, handler, "safe")
|
return generic_hook(self, obj, method, handler, "hook_safe")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- :hook() will allow you to hook a function, allowing your handler to replace the function in the stack,
|
-- :hook() will allow you to hook a function, allowing your handler to replace the function in the stack,
|
||||||
|
@ -354,7 +368,7 @@ end
|
||||||
-- This there is a limit of a single origin hook for any given function.
|
-- This there is a limit of a single origin hook for any given function.
|
||||||
-- This should only be used as a last resort due to its limitation and its potential to break the game if not careful.
|
-- This should only be used as a last resort due to its limitation and its potential to break the game if not careful.
|
||||||
function VMFMod:hook_origin(obj, method, handler)
|
function VMFMod:hook_origin(obj, method, handler)
|
||||||
return generic_hook(self, obj, method, handler, "origin")
|
return generic_hook(self, obj, method, handler, "hook_origin")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Enable/disable functions for all hook types:
|
-- Enable/disable functions for all hook types:
|
||||||
|
@ -394,8 +408,10 @@ vmf.hooks_unload = function()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
vmf.apply_delayed_hooks = function()
|
vmf.apply_delayed_hooks = function(status, state)
|
||||||
_delaying_enabled = false
|
if status == "enter" and state == "StateIngame" then
|
||||||
|
_delaying_enabled = false
|
||||||
|
end
|
||||||
if #_delayed > 0 then
|
if #_delayed > 0 then
|
||||||
vmf:info("Attempt to hook %s delayed hooks", #_delayed)
|
vmf:info("Attempt to hook %s delayed hooks", #_delayed)
|
||||||
-- Go through the table in reverse so we don't get any issues removing entries inside the loop
|
-- Go through the table in reverse so we don't get any issues removing entries inside the loop
|
||||||
|
|
|
@ -98,7 +98,7 @@ function vmf_mod_object:on_game_state_changed(status, state)
|
||||||
print("VMF:ON_GAME_STATE_CHANGED(), status: " .. tostring(status) .. ", state: " .. tostring(state))
|
print("VMF:ON_GAME_STATE_CHANGED(), status: " .. tostring(status) .. ", state: " .. tostring(state))
|
||||||
vmf.mods_game_state_changed_event(status, state)
|
vmf.mods_game_state_changed_event(status, state)
|
||||||
vmf.save_unsaved_settings_to_file()
|
vmf.save_unsaved_settings_to_file()
|
||||||
vmf.apply_delayed_hooks()
|
vmf.apply_delayed_hooks(status, state)
|
||||||
|
|
||||||
if status == "enter" and state == "StateIngame" then
|
if status == "enter" and state == "StateIngame" then
|
||||||
vmf.initialize_keybinds()
|
vmf.initialize_keybinds()
|
||||||
|
|
Loading…
Add table
Reference in a new issue