forked from nvim-neo-tree/neo-tree.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqueue.lua
150 lines (136 loc) · 4.46 KB
/
queue.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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 = {}
---@class neotree.Event.Handler
---@field event neotree.Event|string
---@field handler fun(...)
---@field id string?
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
---@param event_handler neotree.Event.Handler
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