Replace old vmf hook system.

- Comment out the old hooks.lua
- Remove the HookMixin table in favor of using VMFMod.
- Update UIRenderer hook to adjust for changes in the new system.
This commit is contained in:
FireSiku 2018-05-30 19:28:28 -04:00
parent be0e9075ef
commit 78a1f5cbc0
3 changed files with 24 additions and 27 deletions

View file

@ -1,13 +1,15 @@
local vmf = get_mod("VMF") local vmf = get_mod("VMF")
-- Private members -- ####################################################################################################################
local HookMixin = {} -- ##### Locals and Variables #########################################################################################
-- ####################################################################################################################
local HOOK_TYPE_BEFORE = 1 -- Constants for hook_type
local HOOK_TYPE_AFTER = 2 local HOOK_TYPE_NORMAL = 1
local HOOK_TYPE_NORMAL = 3 local HOOK_TYPE_BEFORE = 2
local HOOK_TYPE_AFTER = 3
local HOOK_TYPE_RAW = 4 local HOOK_TYPE_RAW = 4
local HOOK_ERR_NAME = { "before-hook", "after-hook", "hook", "rawhook", } local HOOK_ERR_NAME = { "hook", "before", "after", "rawhook", }
--[[ Planned registry structure: --[[ Planned registry structure:
_registry[self][hook_type] = { _registry[self][hook_type] = {
@ -154,7 +156,7 @@ local function create_hook(self, orig, obj, method, handler, hook_type)
end end
if type(obj) == "string" then if type(obj) == "string" then
if not _G[obj] then if not rawget(_G, obj) then
return return
end end
obj = _G[obj] obj = _G[obj]
@ -197,11 +199,11 @@ end
local function get_orig_function(self, obj, method) local function get_orig_function(self, obj, method)
-- Validate types -- Validate types
if obj and not (type(obj) == "table" or type(obj) == "string") then if obj and not (type(obj) == "table" or type(obj) == "string") then
self:error("(hook): 'object' - table or string expected, got %s", type(obj)) self:error("(hook): 'object' - table or string expected, got %s [args: %s, %s", type(obj), obj or "nil", method or "nil")
return return
end end
if type(method) ~= "string" then if type(method) ~= "string" then
self:error("(hook): 'method' - string expected, got %s", type(method)) self:error("(hook): 'method' - string expected, got %s [args: %s, %s]", type(method), obj or "nil", method or "nil")
return return
end end
@ -209,7 +211,7 @@ local function get_orig_function(self, obj, method)
-- obj can be a string. We'll need to grab the actual object first. -- obj can be a string. We'll need to grab the actual object first.
-- if we can't find object, we don't need to go any further. -- if we can't find object, we don't need to go any further.
if type(obj) == "string" then if type(obj) == "string" then
if not _G[obj] then return end if not rawget(_G, obj) then return end
obj = _G[obj] obj = _G[obj]
end end
if is_orig_hooked(obj, method) then if is_orig_hooked(obj, method) then
@ -240,7 +242,7 @@ end
-- This type of hook is typically used if you need to know a function was called, but dont want to modify it. -- This type of hook is typically used if you need to know a function was called, but dont want to modify it.
-- These will always be executed before the hook chain. -- These will always be executed before the hook chain.
-- Due to discussion, handler may not receive any arguments, but will see what the use cases are with them first. -- Due to discussion, handler may not receive any arguments, but will see what the use cases are with them first.
function HookMixin:new_before(obj, method, handler) function VMFMod:before(obj, method, handler)
if type(method) == "function" then if type(method) == "function" then
method, handler, obj = obj, method, nil method, handler, obj = obj, method, nil
end end
@ -253,7 +255,7 @@ end
-- original function, nor can you change its return values. -- original function, nor can you change its return values.
-- These will always be executed after the hook chain. -- These will always be executed after the hook chain.
-- This is similar to :front() functionality in V1 modding. -- This is similar to :front() functionality in V1 modding.
function HookMixin:new_after(obj, method, handler) function VMFMod:after(obj, method, handler)
if type(method) == "function" then if type(method) == "function" then
method, handler, obj = obj, method, nil method, handler, obj = obj, method, nil
end end
@ -266,7 +268,7 @@ end
-- and control it's execution. All hooks on the same function will be part of a chain, with the -- and control it's execution. All hooks on the same function will be part of a chain, with the
-- original function at the end. Your handler has to call the next function in the chain manually. -- original function at the end. Your handler has to call the next function in the chain manually.
-- The chain of event is determined by mod load order. -- The chain of event is determined by mod load order.
function HookMixin:new_hook(obj, method, handler) function VMFMod:hook(obj, method, handler)
if type(method) == "function" then if type(method) == "function" then
method, handler, obj = obj, method, nil method, handler, obj = obj, method, nil
end end
@ -280,7 +282,7 @@ end
-- This is similar to :back functionality that was sparsely used in old V1 mods. -- This is similar to :back functionality that was sparsely used in old V1 mods.
-- This there is a limit of a single rawhook for any given function. -- This there is a limit of a single rawhook 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 HookMixin:new_rawhook(obj, method, handler) function VMFMod:rawhook(obj, method, handler)
if type(method) == "function" then if type(method) == "function" then
method, handler, obj = obj, method, nil method, handler, obj = obj, method, nil
end end
@ -289,7 +291,7 @@ function HookMixin:new_rawhook(obj, method, handler)
create_hook(self, orig, obj, method, handler, HOOK_TYPE_RAW) create_hook(self, orig, obj, method, handler, HOOK_TYPE_RAW)
end end
function HookMixin:enable_all_hooks() function VMFMod:enable_all_hooks()
-- Using pairs because the self table may contain nils, and order isnt important. -- Using pairs because the self table may contain nils, and order isnt important.
for _, hooks in pairs(_registry[self]) do for _, hooks in pairs(_registry[self]) do
for orig, _ in pairs(hooks.active) do for orig, _ in pairs(hooks.active) do
@ -298,7 +300,7 @@ function HookMixin:enable_all_hooks()
end end
end end
function HookMixin:disable_all_hooks() function VMFMod:disable_all_hooks()
-- Using pairs because the self table may contain nils, and order isnt important. -- Using pairs because the self table may contain nils, and order isnt important.
for _, hooks in pairs(_registry[self]) do for _, hooks in pairs(_registry[self]) do
for orig, _ in pairs(hooks.active) do for orig, _ in pairs(hooks.active) do
@ -313,11 +315,4 @@ end
-- -- removes all hooks when VMF is about to be reloaded -- -- removes all hooks when VMF is about to be reloaded
-- vmf.hooks_unload = function() -- vmf.hooks_unload = function()
-- end -- end
-- put the hook mixin inside VMFMod
do
for k, v in pairs(HookMixin) do
VMFMod[k] = v
end
end

View file

@ -172,6 +172,7 @@ end
-- ##### Hooks ######################################################################################################## -- ##### Hooks ########################################################################################################
-- #################################################################################################################### -- ####################################################################################################################
local LUA_SCRIPT_CALLER_POSITION = 4
vmf:hook("UIRenderer.create", function(func, world, ...) vmf:hook("UIRenderer.create", function(func, world, ...)
local is_modified = false local is_modified = false
@ -182,11 +183,11 @@ vmf:hook("UIRenderer.create", function(func, world, ...)
local callstack = debug.traceback() local callstack = debug.traceback()
-- get the name of lua script which called 'UIRenderer.create' -- get the name of lua script which called 'UIRenderer.create'
-- it's always the 3rd string of the 'debug.traceback()' output -- it's the 4th string of the 'debug.traceback()' output
local i = 0 local i = 0
for s in callstack:gmatch("(.-)\n") do for s in callstack:gmatch("(.-)\n") do
i = i + 1 i = i + 1
if i == 3 then if i == LUA_SCRIPT_CALLER_POSITION then
ui_renderer_creator = s:match("([^%/]+)%.lua:") ui_renderer_creator = s:match("([^%/]+)%.lua:")
break break
end end

View file

@ -18,7 +18,8 @@ function vmf_mod_object:init()
dofile("scripts/mods/vmf/modules/core/persistent_tables") dofile("scripts/mods/vmf/modules/core/persistent_tables")
dofile("scripts/mods/vmf/modules/debug/dev_console") dofile("scripts/mods/vmf/modules/debug/dev_console")
dofile("scripts/mods/vmf/modules/debug/table_dump") dofile("scripts/mods/vmf/modules/debug/table_dump")
dofile("scripts/mods/vmf/modules/core/hooks") --dofile("scripts/mods/vmf/modules/core/hooks")
dofile("scripts/mods/vmf/modules/core/newhooks")
dofile("scripts/mods/vmf/modules/core/toggling") dofile("scripts/mods/vmf/modules/core/toggling")
dofile("scripts/mods/vmf/modules/core/keybindings") dofile("scripts/mods/vmf/modules/core/keybindings")
dofile("scripts/mods/vmf/modules/core/delayed_chat_messages") dofile("scripts/mods/vmf/modules/core/delayed_chat_messages")