112 lines
2.4 KiB
Lua
112 lines
2.4 KiB
Lua
-- require('mobdebug').start()
|
|
|
|
-- Event module
|
|
local Event = {}
|
|
|
|
-- Event handler registry
|
|
Event.handlers = {}
|
|
|
|
-- Remove an event handler from the registry
|
|
local function remove (self)
|
|
if not self.isRegistered then
|
|
return self
|
|
end
|
|
if self.prevHandler then
|
|
self.prevHandler.nextHandler = self.nextHandler
|
|
end
|
|
if self.nextHandler then
|
|
self.nextHandler.prevHandler = self.prevHandler
|
|
end
|
|
if Event.handlers[self.name] == self then
|
|
Event.handlers[self.name] = self.nextHandler
|
|
end
|
|
self.prevHandler = nil
|
|
self.nextHandler = nil
|
|
self.isRegistered = false
|
|
|
|
return self
|
|
end
|
|
|
|
-- Insert an event handler into the registry
|
|
local function register (self)
|
|
if self.isRegistered then
|
|
return self
|
|
end
|
|
self.nextHandler = Event.handlers[self.name]
|
|
if self.nextHandler then
|
|
self.nextHandler.prevHandler = self
|
|
end
|
|
Event.handlers[self.name] = self
|
|
self.isRegistered = true
|
|
|
|
return self
|
|
end
|
|
|
|
-- Create an event handler
|
|
local function Handler (name, callback)
|
|
return {
|
|
name = name,
|
|
callback = callback,
|
|
isRegistered = false,
|
|
remove = remove,
|
|
register = register
|
|
}
|
|
end
|
|
|
|
|
|
|
|
-- Create and register a new event handler
|
|
function Event.on (name, callback)
|
|
return register(Handler(name, callback))
|
|
end
|
|
|
|
-- Dispatch an event
|
|
function Event.dispatch (name, ...)
|
|
local handler = Event.handlers[name]
|
|
|
|
while handler do
|
|
if handler.callback(...) == false then
|
|
return handler
|
|
end
|
|
handler = handler.nextHandler
|
|
end
|
|
end
|
|
|
|
local function isCallable (value)
|
|
return type(value) == 'function' or
|
|
getmetatable(value) and getmetatable(value).__call
|
|
end
|
|
|
|
-- Inject a dispatcher into a table.
|
|
local function hookDispatcher (t, key)
|
|
local original = t[key]
|
|
|
|
if isCallable(original) then
|
|
t[key] = function (...)
|
|
original(...)
|
|
return Event.dispatch(key, ...)
|
|
end
|
|
else
|
|
t[key] = function (...)
|
|
return Event.dispatch(key, ...)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Inject dispatchers into a table. Examples:
|
|
-- Event.hook(love.handlers)
|
|
-- Event.hook(love, { 'load', 'update', 'draw' })
|
|
function Event.hook (t, keys)
|
|
if keys then
|
|
for _, key in ipairs(keys) do
|
|
hookDispatcher(t, key)
|
|
end
|
|
else
|
|
for key in pairs(t) do
|
|
hookDispatcher(t, key)
|
|
end
|
|
end
|
|
end
|
|
|
|
return Event
|