1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 01:00:05 +08:00
SpaceVim/bundle/neo-tree.nvim/lua/neo-tree/events/queue.lua
2023-05-30 21:09:18 +08:00

145 lines
4.3 KiB
Lua

local utils = require("neo-tree.utils")
local log = require("neo-tree.log")
local Queue = require("neo-tree.collections").Queue
local event_queues = {}
local event_definitions = {}
local M = {}
local validate_event_handler = function(event_handler)
if type(event_handler) ~= "table" then
error("Event handler must be a table")
end
if type(event_handler.event) ~= "string" then
error("Event handler must have an event")
end
if type(event_handler.handler) ~= "function" then
error("Event handler must have a handler")
end
end
M.clear_all_events = function()
for event_name, queue in pairs(event_queues) do
M.destroy_event(event_name)
end
event_queues = {}
end
M.define_event = function(event_name, opts)
local existing = event_definitions[event_name]
if existing ~= nil then
error("Event already defined: " .. event_name)
end
event_definitions[event_name] = opts
end
M.destroy_event = function(event_name)
local existing = event_definitions[event_name]
if existing == nil then
return false
end
if existing.setup_was_run and type(existing.teardown) == "function" then
local success, result = pcall(existing.teardown)
if not success then
error("Error in teardown for " .. event_name .. ": " .. result)
end
existing.setup_was_run = false
end
event_queues[event_name] = nil
return true
end
local fire_event_internal = function(event, args)
local queue = event_queues[event]
if queue == nil then
return nil
end
--log.trace("Firing event: ", event, " with args: ", args)
if queue:is_empty() then
--log.trace("Event queue is empty")
return nil
end
local seed = utils.get_value(event_definitions, event .. ".seed")
if seed ~= nil then
local success, result = pcall(seed, args)
if success and result then
log.trace("Seed for " .. event .. " returned: " .. tostring(result))
elseif success then
log.trace("Seed for " .. event .. " returned falsy, cancelling event")
else
log.error("Error in seed function for " .. event .. ": " .. result)
end
end
return queue:for_each(function(event_handler)
local remove_node = event_handler == nil or event_handler.cancelled
if not remove_node then
local success, result = pcall(event_handler.handler, args)
local id = event_handler.id or event_handler
if success then
log.trace("Handler ", id, " for " .. event .. " called successfully.")
else
log.error(string.format("Error in event handler for event %s[%s]: %s", event, id, result))
end
if event_handler.once then
event_handler.cancelled = true
return true
end
return result
end
end)
end
M.fire_event = function(event, args)
local freq = utils.get_value(event_definitions, event .. ".debounce_frequency", 0, true)
local strategy = utils.get_value(event_definitions, event .. ".debounce_strategy", 0, true)
log.trace("Firing event: ", event, " with args: ", args)
if freq > 0 then
utils.debounce("EVENT_FIRED: " .. event, function()
fire_event_internal(event, args or {})
end, freq, strategy)
else
return fire_event_internal(event, args or {})
end
end
M.subscribe = function(event_handler)
validate_event_handler(event_handler)
local queue = event_queues[event_handler.event]
if queue == nil then
log.debug("Creating queue for event: " .. event_handler.event)
queue = Queue:new()
local def = event_definitions[event_handler.event]
if def and type(def.setup) == "function" then
local success, result = pcall(def.setup)
if success then
def.setup_was_run = true
log.debug("Setup for event " .. event_handler.event .. " was run")
else
log.error("Error in setup for " .. event_handler.event .. ": " .. result)
end
end
event_queues[event_handler.event] = queue
end
log.debug("Adding event handler [", event_handler.id, "] for event: ", event_handler.event)
queue:add(event_handler)
end
M.unsubscribe = function(event_handler)
local queue = event_queues[event_handler.event]
if queue == nil then
return nil
end
queue:remove_by_id(event_handler.id or event_handler)
if queue:is_empty() then
M.destroy_event(event_handler.event)
event_queues[event_handler.event] = nil
else
event_queues[event_handler.event] = queue
end
end
return M