mirror of
https://github.com/airstruck/luigi.git
synced 2025-11-18 12:25:06 +00:00
92 lines
1.8 KiB
Lua
92 lines
1.8 KiB
Lua
local Hooker = {}
|
|
|
|
local wrapped = setmetatable({}, { __mode = 'k' })
|
|
|
|
local hooks = setmetatable({}, { __mode = 'k' })
|
|
|
|
local function unhook (item)
|
|
if item.prev then
|
|
item.prev.next = item.next
|
|
end
|
|
|
|
if item.next then
|
|
item.next.prev = item.prev
|
|
end
|
|
|
|
if hooks[item.host][item.key] == item then
|
|
hooks[item.host][item.key] = item.next
|
|
end
|
|
end
|
|
|
|
local function hook (host, key, func, atEnd)
|
|
if not func then
|
|
return
|
|
end
|
|
|
|
if not hooks[host] then
|
|
hooks[host] = {}
|
|
end
|
|
|
|
local current = hooks[host][key]
|
|
local item = {
|
|
next = not atEnd and current or nil,
|
|
unhook = unhook,
|
|
host = host,
|
|
key = key,
|
|
func = func,
|
|
}
|
|
|
|
if atEnd then
|
|
if current then
|
|
while current.next do
|
|
current = current.next
|
|
end
|
|
current.next = item
|
|
item.prev = current
|
|
else
|
|
hooks[host][key] = item
|
|
end
|
|
return item
|
|
end
|
|
|
|
if current then
|
|
current.prev = item
|
|
end
|
|
|
|
hooks[host][key] = item
|
|
|
|
return item
|
|
end
|
|
|
|
function Hooker.unhook (item)
|
|
return unhook(item)
|
|
end
|
|
|
|
function Hooker.hook (host, key, func, atEnd)
|
|
if not wrapped[host] then
|
|
wrapped[host] = {}
|
|
end
|
|
|
|
if not wrapped[host][key] then
|
|
wrapped[host][key] = true
|
|
|
|
hook(host, key, host[key])
|
|
|
|
host[key] = function (...)
|
|
local item = hooks[host][key]
|
|
|
|
while item do
|
|
local result = item.func(...)
|
|
if result ~= nil then
|
|
return result
|
|
end
|
|
item = item.next
|
|
end -- while
|
|
end -- function
|
|
end -- if
|
|
|
|
return hook(host, key, func, atEnd)
|
|
end
|
|
|
|
return Hooker
|