@@ -6,8 +6,8 @@ local utils = lazy.require("diffview.utils")
66
77local M = {}
88
9- --- @enum Event
10- local Event = {
9+ --- @enum EventName
10+ local EventName = {
1111 FILES_STAGED = 1 ,
1212}
1313
@@ -18,10 +18,26 @@ local Event = {
1818--- @field callback function The original callback
1919--- @field call function
2020
21+ --- @class Event : diffview.Object
22+ --- @operator call : Event
23+ --- @field id any
24+ --- @field propagate boolean
25+ local Event = oop .create_class (" Event" )
26+
27+ function Event :init (opt )
28+ self .id = opt .id
29+ self .propagate = true
30+ end
31+
32+ function Event :stop_propagation ()
33+ self .propagate = false
34+ end
35+
36+
2137--- @class EventEmitter : diffview.Object
22- --- @field event_map table<Event , Listener[]> # Registered events mapped to subscribed listeners.
38+ --- @field event_map table<any , Listener[]> # Registered events mapped to subscribed listeners.
2339--- @field any_listeners Listener[] # Listeners subscribed to all events.
24- --- @field emit_lock table<Event , boolean>
40+ --- @field emit_lock table<any , boolean>
2541local EventEmitter = oop .create_class (" EventEmitter" )
2642
2743--- EventEmitter constructor.
@@ -32,49 +48,48 @@ function EventEmitter:init()
3248end
3349
3450--- Subscribe to a given event.
35- --- @param event any Event identifier.
36- --- @param callback function
37- function EventEmitter :on (event , callback )
38- if not self .event_map [event ] then
39- self .event_map [event ] = {}
51+ --- @param event_id any Event identifier.
52+ --- @param callback fun ( event : Event , ... )
53+ function EventEmitter :on (event_id , callback )
54+ if not self .event_map [event_id ] then
55+ self .event_map [event_id ] = {}
4056 end
4157
42- table.insert (self .event_map [event ] , {
58+ table.insert (self .event_map [event_id ], 1 , {
4359 type = " normal" ,
4460 callback = callback ,
45- call = function (args )
46- return callback (utils .tbl_unpack (args ))
61+ call = function (event , args )
62+ return callback (event , utils .tbl_unpack (args ))
4763 end ,
4864 })
4965end
5066
5167--- Subscribe a one-shot listener to a given event.
52- --- @param event any Event identifier.
53- --- @param callback function
54- function EventEmitter :once (event , callback )
55- if not self .event_map [event ] then
56- self .event_map [event ] = {}
68+ --- @param event_id any Event identifier.
69+ --- @param callback fun ( event : Event , ... )
70+ function EventEmitter :once (event_id , callback )
71+ if not self .event_map [event_id ] then
72+ self .event_map [event_id ] = {}
5773 end
5874
5975 local emitted = false
6076
61- table.insert (self .event_map [event ] , {
77+ table.insert (self .event_map [event_id ], 1 , {
6278 type = " once" ,
6379 callback = callback ,
64- call = function (args )
80+ call = function (event , args )
6581 if not emitted then
6682 emitted = true
67- self :off (callback , event )
68- return callback (utils .tbl_unpack (args ))
83+ return callback (event , utils .tbl_unpack (args ))
6984 end
7085 end ,
7186 })
7287end
7388
7489--- Add a new any-listener, subscribed to all events.
75- --- @param callback function
90+ --- @param callback fun ( event : Event , ... )
7691function EventEmitter :on_any (callback )
77- table.insert (self .any_listeners , {
92+ table.insert (self .any_listeners , 1 , {
7893 type = " any" ,
7994 callback = callback ,
8095 call = function (event , args )
@@ -84,11 +99,11 @@ function EventEmitter:on_any(callback)
8499end
85100
86101--- Add a new one-shot any-listener, subscribed to all events.
87- --- @param callback function
102+ --- @param callback fun ( event : Event , ... )
88103function EventEmitter :once_any (callback )
89104 local emitted = false
90105
91- table.insert (self .any_listeners , {
106+ table.insert (self .any_listeners , 1 , {
92107 type = " any_once" ,
93108 callback = callback ,
94109 call = function (event , args )
@@ -103,13 +118,13 @@ end
103118--- Unsubscribe a listener. If no event is given, the listener is unsubscribed
104119--- from all events.
105120--- @param callback function
106- --- @param event ? any Only unsubscribe listeners from this event.
107- function EventEmitter :off (callback , event )
121+ --- @param event_id ? any Only unsubscribe listeners from this event.
122+ function EventEmitter :off (callback , event_id )
108123 --- @type Listener[][]
109124 local all
110125
111- if event then
112- all = { self .event_map [event ] }
126+ if event_id then
127+ all = { self .event_map [event_id ] }
113128 else
114129 all = utils .vec_join (
115130 vim .tbl_values (self .event_map ),
@@ -133,63 +148,87 @@ function EventEmitter:off(callback, event)
133148end
134149
135150--- Clear all listeners for a given event. If no event is given: clear all listeners.
136- --- @param event any ?
137- function EventEmitter :clear (event )
151+ --- @param event_id any ?
152+ function EventEmitter :clear (event_id )
138153 for e , _ in pairs (self .event_map ) do
139- if event == nil or event == e then
154+ if event_id == nil or event_id == e then
140155 self .event_map [e ] = nil
141156 end
142157 end
143158end
144159
160+ --- @param listeners Listener[]
161+ --- @param event Event
162+ --- @param args table
163+ --- @return Listener[]
164+ local function filter_call (listeners , event , args )
165+ listeners = utils .vec_slice (listeners ) --[[ @as Listener[] ]]
166+ local result = {}
167+
168+ for i = 1 , # listeners do
169+ local cur = listeners [i ]
170+ local ret = cur .call (event , args )
171+
172+ if not (cur .type == " once" or cur .type == " any_once" ) and not ret then
173+ result [# result + 1 ] = cur
174+ end
175+
176+ if not event .propagate then
177+ for j = i + 1 , # listeners do result [j ] = listeners [j ] end
178+ break
179+ end
180+ end
181+
182+ return result
183+ end
184+
145185--- Notify all listeners subscribed to a given event.
146- --- @param event any Event identifier.
186+ --- @param event_id any Event identifier.
147187--- @param ... any Event callback args.
148- function EventEmitter :emit (event , ...)
149- if not self .emit_lock [event ] then
188+ function EventEmitter :emit (event_id , ...)
189+ if not self .emit_lock [event_id ] then
150190 local args = utils .tbl_pack (... )
191+ local e = Event ({ id = event_id })
151192
152- if type (self .event_map [event ]) == " table" then
153- self .event_map [event ] = utils .tbl_fmap (self .event_map [event ], function (listeners )
154- return not listeners .call (args ) and listeners or nil
155- end )
193+ if type (self .event_map [event_id ]) == " table" then
194+ self .event_map [event_id ] = filter_call (self .event_map [event_id ], e , args )
156195 end
157196
158- self . any_listeners = utils . tbl_fmap ( self . any_listeners , function ( listeners )
159- return not listeners . call ( event , args ) and listeners or nil
160- end )
197+ if e . propagate then
198+ self . any_listeners = filter_call ( self . any_listeners , e , args )
199+ end
161200 end
162201end
163202
164203--- Non-recursively notify all listeners subscribed to a given event.
165- --- @param event any Event identifier.
204+ --- @param event_id any Event identifier.
166205--- @param ... any Event callback args.
167- function EventEmitter :nore_emit (event , ...)
168- if not self .emit_lock [event ] then
169- self .emit_lock [event ] = true
206+ function EventEmitter :nore_emit (event_id , ...)
207+ if not self .emit_lock [event_id ] then
208+ self .emit_lock [event_id ] = true
170209 local args = utils .tbl_pack (... )
210+ local e = Event ({ id = event_id })
171211
172- if type (self .event_map [event ]) == " table" then
173- self .event_map [event ] = utils .tbl_fmap (self .event_map [event ], function (listeners )
174- return not listeners .call (args ) and listeners or nil
175- end )
212+ if type (self .event_map [event_id ]) == " table" then
213+ self .event_map [event_id ] = filter_call (self .event_map [event_id ], e , args )
176214 end
177215
178- self . any_listeners = utils . tbl_fmap ( self . any_listeners , function ( listeners )
179- return not listeners . call ( event , args ) and listeners or nil
180- end )
216+ if e . propagate then
217+ self . any_listeners = filter_call ( self . any_listeners , e , args )
218+ end
181219
182- self .emit_lock [event ] = false
220+ self .emit_lock [event_id ] = false
183221 end
184222end
185223
186224--- Get all listeners subscribed to the given event.
187- --- @param event any Event identifier.
225+ --- @param event_id any Event identifier.
188226--- @return Listener[] ?
189- function EventEmitter :get (event )
190- return self .event_map [event ]
227+ function EventEmitter :get (event_id )
228+ return self .event_map [event_id ]
191229end
192230
231+ M .EventName = EventName
193232M .Event = Event
194233M .EventEmitter = EventEmitter
195234return M
0 commit comments