first commit

This commit is contained in:
2021-12-18 20:10:30 +01:00
parent 4d04f63b99
commit 215bed9faf
108 changed files with 3630 additions and 0 deletions

111
lib/knife/event.lua Normal file
View File

@@ -0,0 +1,111 @@
-- 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