Files
love-luigi/luigi/hooker.lua
airstruck f866442cf1 cleanup
2015-11-08 16:49:50 -05:00

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