mirror of
https://github.com/Insality/druid.git
synced 2025-06-27 18:37:44 +02:00
Update event to remove middleclass, using defold-event as a base
This commit is contained in:
parent
ba1ab07e0d
commit
0aeb0b3fea
163
druid/event.lua
163
druid/event.lua
@ -8,10 +8,16 @@
|
|||||||
-- @module DruidEvent
|
-- @module DruidEvent
|
||||||
-- @alias druid.event
|
-- @alias druid.event
|
||||||
|
|
||||||
local class = require("druid.system.middleclass")
|
local M = {}
|
||||||
|
M.COUNTER = 0
|
||||||
|
|
||||||
local DruidEvent = class("druid.event")
|
-- Forward declaration
|
||||||
|
local EVENT_METATABLE
|
||||||
|
|
||||||
|
-- Local versions
|
||||||
|
local pcall = pcall
|
||||||
|
local tinsert = table.insert
|
||||||
|
local tremove = table.remove
|
||||||
|
|
||||||
--- DruidEvent constructor
|
--- DruidEvent constructor
|
||||||
-- @tparam DruidEvent self @{DruidEvent}
|
-- @tparam DruidEvent self @{DruidEvent}
|
||||||
@ -20,19 +26,44 @@ local DruidEvent = class("druid.event")
|
|||||||
-- local Event = require("druid.event")
|
-- local Event = require("druid.event")
|
||||||
-- ...
|
-- ...
|
||||||
-- local event = Event(initial_callback)
|
-- local event = Event(initial_callback)
|
||||||
function DruidEvent.initialize(self, initial_callback)
|
function M.create(callback, callback_context)
|
||||||
self._callbacks = nil -- initialize later
|
local instance = setmetatable({}, EVENT_METATABLE)
|
||||||
|
|
||||||
if initial_callback then
|
if callback then
|
||||||
self:subscribe(initial_callback)
|
instance:subscribe(callback, callback_context)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
M.COUNTER = M.COUNTER + 1
|
||||||
|
return instance
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Check is event subscribed.
|
||||||
|
-- @tparam DruidEvent self @{DruidEvent}
|
||||||
|
-- @tparam function callback Callback itself
|
||||||
|
-- @tparam any|nil callback_context Additional context as first param to callback call
|
||||||
|
-- @treturn boolean, number|nil @Is event subscribed, return index of callback in event as second param
|
||||||
|
function M.is_subscribed(self, callback, callback_context)
|
||||||
|
if #self == 0 then
|
||||||
|
return false, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
for index = 1, #self do
|
||||||
|
local cb = self[index]
|
||||||
|
if cb[1] == callback and cb[2] == callback_context then
|
||||||
|
return true, index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false, nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Subscribe callback on event
|
--- Subscribe callback on event
|
||||||
-- @tparam DruidEvent self @{DruidEvent}
|
-- @tparam DruidEvent self @{DruidEvent}
|
||||||
-- @tparam function callback Callback itself
|
-- @tparam function callback Callback itself
|
||||||
-- @tparam any|nil context Additional context as first param to callback call, usually it's self
|
-- @tparam any|nil callback_context Additional context as first param to callback call, usually it's self
|
||||||
|
-- @treturn boolean True if callback was subscribed
|
||||||
-- @usage
|
-- @usage
|
||||||
-- local function on_long_callback(self)
|
-- local function on_long_callback(self)
|
||||||
-- print("Long click!")
|
-- print("Long click!")
|
||||||
@ -40,41 +71,39 @@ end
|
|||||||
-- ...
|
-- ...
|
||||||
-- local button = self.druid:new_button("button", callback)
|
-- local button = self.druid:new_button("button", callback)
|
||||||
-- button.on_long_click:subscribe(on_long_callback, self)
|
-- button.on_long_click:subscribe(on_long_callback, self)
|
||||||
function DruidEvent.subscribe(self, callback, context)
|
function M.subscribe(self, callback, callback_context)
|
||||||
assert(type(self) == "table", "You should subscribe to event with : syntax")
|
assert(type(self) == "table", "You should subscribe to event with : syntax")
|
||||||
assert(type(callback) == "function", "Callback should be function")
|
assert(callback, "A function must be passed to subscribe to an event")
|
||||||
|
|
||||||
self._callbacks = self._callbacks or {}
|
if self:is_subscribed(callback, callback_context) then
|
||||||
table.insert(self._callbacks, {
|
return false
|
||||||
callback = callback,
|
end
|
||||||
context = context
|
|
||||||
})
|
|
||||||
|
|
||||||
return callback
|
tinsert(self, { callback, callback_context })
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Unsubscribe callback on event
|
--- Unsubscribe callback on event
|
||||||
-- @tparam DruidEvent self @{DruidEvent}
|
-- @tparam DruidEvent self @{DruidEvent}
|
||||||
-- @tparam function callback Callback itself
|
-- @tparam function callback Callback itself
|
||||||
-- @tparam any|nil context Additional context as first param to callback call
|
-- @tparam any|nil callback_context Additional context as first param to callback call
|
||||||
-- @usage
|
-- @usage
|
||||||
-- local function on_long_callback(self)
|
-- local function on_long_callback(self)
|
||||||
-- print("Long click!")
|
-- print("Long click!")
|
||||||
-- end
|
-- end
|
||||||
-- ...
|
-- ...
|
||||||
-- button.on_long_click:unsubscribe(on_long_callback, self)
|
-- button.on_long_click:unsubscribe(on_long_callback, self)
|
||||||
function DruidEvent.unsubscribe(self, callback, context)
|
function M.unsubscribe(self, callback, callback_context)
|
||||||
if not self._callbacks then
|
assert(callback, "A function must be passed to subscribe to an event")
|
||||||
return
|
|
||||||
|
local _, event_index = self:is_subscribed(callback, callback_context)
|
||||||
|
if not event_index then
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
for index, callback_info in ipairs(self._callbacks) do
|
tremove(self, event_index --[[@as number]])
|
||||||
if callback_info.callback == callback and callback_info.context == context then
|
return true
|
||||||
table.remove(self._callbacks, index)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -83,11 +112,18 @@ end
|
|||||||
-- @treturn boolean True if event have handlers
|
-- @treturn boolean True if event have handlers
|
||||||
-- @usage
|
-- @usage
|
||||||
-- local is_long_click_handler_exists = button.on_long_click:is_exist()
|
-- local is_long_click_handler_exists = button.on_long_click:is_exist()
|
||||||
function DruidEvent.is_exist(self)
|
function M.is_exist(self)
|
||||||
if not self._callbacks then
|
return #self > 0
|
||||||
return false
|
end
|
||||||
end
|
|
||||||
return #self._callbacks > 0
|
|
||||||
|
--- Return true, if event not have handler
|
||||||
|
--- @tparam DruidEvent self @{DruidEvent}
|
||||||
|
--- @treturn boolean True if event not have handlers
|
||||||
|
--- @usage
|
||||||
|
--- local is_long_click_handler_not_exists = button.on_long_click:is_empty()
|
||||||
|
function M:is_empty()
|
||||||
|
return #self == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -95,8 +131,10 @@ end
|
|||||||
-- @tparam DruidEvent self @{DruidEvent}
|
-- @tparam DruidEvent self @{DruidEvent}
|
||||||
-- @usage
|
-- @usage
|
||||||
-- button.on_long_click:clear()
|
-- button.on_long_click:clear()
|
||||||
function DruidEvent.clear(self)
|
function M.clear(self)
|
||||||
self._callbacks = nil
|
for index = #self, 1, -1 do
|
||||||
|
self[index] = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -108,19 +146,60 @@ end
|
|||||||
-- ...
|
-- ...
|
||||||
-- local event = Event()
|
-- local event = Event()
|
||||||
-- event:trigger("Param1", "Param2")
|
-- event:trigger("Param1", "Param2")
|
||||||
function DruidEvent.trigger(self, ...)
|
function M.trigger(self, ...)
|
||||||
if not self._callbacks then
|
if #self == 0 then
|
||||||
return false
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, callback_info in ipairs(self._callbacks) do
|
local result = nil
|
||||||
if callback_info.context then
|
|
||||||
callback_info.callback(callback_info.context, ...)
|
local call_callback = self.call_callback
|
||||||
else
|
for index = 1, #self do
|
||||||
callback_info.callback(...)
|
result = call_callback(self, self[index], ...)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return DruidEvent
|
-- @tparam table callback Callback data {function, context}
|
||||||
|
-- @tparam any ... All event params
|
||||||
|
-- @treturn any Result of the callback
|
||||||
|
-- @local
|
||||||
|
function M:call_callback(callback, ...)
|
||||||
|
local event_callback = callback[1]
|
||||||
|
local event_callback_context = callback[2]
|
||||||
|
|
||||||
|
-- Call callback
|
||||||
|
local ok, result_or_error
|
||||||
|
if event_callback_context then
|
||||||
|
ok, result_or_error = pcall(event_callback, event_callback_context, ...)
|
||||||
|
else
|
||||||
|
ok, result_or_error = pcall(event_callback, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Handle errors
|
||||||
|
if not ok then
|
||||||
|
local caller_info = debug.getinfo(2)
|
||||||
|
pprint("An error occurred during event processing", {
|
||||||
|
trigger = caller_info.short_src .. ":" .. caller_info.currentline,
|
||||||
|
error = result_or_error,
|
||||||
|
})
|
||||||
|
pprint("Traceback", debug.traceback())
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return result_or_error
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Construct event metatable
|
||||||
|
EVENT_METATABLE = {
|
||||||
|
__index = M,
|
||||||
|
__call = M.trigger,
|
||||||
|
}
|
||||||
|
|
||||||
|
return setmetatable(M, {
|
||||||
|
__call = function(_, callback)
|
||||||
|
return M.create(callback)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user