@@ -41,137 +41,177 @@ impl Event {
4141 }
4242}
4343
44- /// What happens after the handler is called?
45- #[ derive( Debug , Copy , Clone , Eq , PartialEq ) ]
46- enum AfterHandle {
47- /// The handler is removed (once).
48- Remove ,
49-
50- /// Nothing is done (regular).
51- DoNothing ,
44+ /// What to do with the pending handler when resolving it?
45+ enum Pending < Event : Tag , Window : Tag > {
46+ Unlisten ( EventHandler ) ,
47+ Listen ( EventHandler , Event , Handler < Window > ) ,
48+ Trigger ( Event , Option < Window > , Option < String > ) ,
5249}
5350
5451/// Stored in [`Listeners`] to be called upon when the event that stored it is triggered.
5552struct Handler < Window : Tag > {
5653 window : Option < Window > ,
57- callback : Box < dyn Fn ( Event ) -> AfterHandle + Send > ,
54+ callback : Box < dyn Fn ( Event ) + Send > ,
5855}
5956
6057/// A collection of handlers. Multiple handlers can represent the same event.
6158type Handlers < Event , Window > = HashMap < Event , HashMap < EventHandler , Handler < Window > > > ;
6259
63- #[ derive( Clone ) ]
64- pub ( crate ) struct Listeners < Event : Tag , Window : Tag > {
65- inner : Arc < Mutex < Handlers < Event , Window > > > ,
60+ /// Holds event handlers and pending event handlers, along with the salts associating them.
61+ struct InnerListeners < Event : Tag , Window : Tag > {
62+ handlers : Mutex < Handlers < Event , Window > > ,
63+ pending : Mutex < Vec < Pending < Event , Window > > > ,
6664 function_name : Uuid ,
6765 listeners_object_name : Uuid ,
6866 queue_object_name : Uuid ,
6967}
7068
71- impl < E : Tag , L : Tag > Default for Listeners < E , L > {
69+ /// A self-contained event manager.
70+ pub ( crate ) struct Listeners < Event : Tag , Window : Tag > {
71+ inner : Arc < InnerListeners < Event , Window > > ,
72+ }
73+
74+ impl < Event : Tag , Window : Tag > Default for Listeners < Event , Window > {
7275 fn default ( ) -> Self {
7376 Self {
74- inner : Arc :: new ( Mutex :: default ( ) ) ,
75- function_name : Uuid :: new_v4 ( ) ,
76- listeners_object_name : Uuid :: new_v4 ( ) ,
77- queue_object_name : Uuid :: new_v4 ( ) ,
77+ inner : Arc :: new ( InnerListeners {
78+ handlers : Mutex :: default ( ) ,
79+ pending : Mutex :: default ( ) ,
80+ function_name : Uuid :: new_v4 ( ) ,
81+ listeners_object_name : Uuid :: new_v4 ( ) ,
82+ queue_object_name : Uuid :: new_v4 ( ) ,
83+ } ) ,
84+ }
85+ }
86+ }
87+
88+ impl < Event : Tag , Window : Tag > Clone for Listeners < Event , Window > {
89+ fn clone ( & self ) -> Self {
90+ Self {
91+ inner : self . inner . clone ( ) ,
7892 }
7993 }
8094}
8195
82- impl < E : Tag , L : Tag > Listeners < E , L > {
96+ impl < Event : Tag , Window : Tag > Listeners < Event , Window > {
8397 /// Randomly generated function name to represent the JavaScript event function.
8498 pub ( crate ) fn function_name ( & self ) -> String {
85- self . function_name . to_string ( )
99+ self . inner . function_name . to_string ( )
86100 }
87101
88102 /// Randomly generated listener object name to represent the JavaScript event listener object.
89103 pub ( crate ) fn listeners_object_name ( & self ) -> String {
90- self . function_name . to_string ( )
104+ self . inner . listeners_object_name . to_string ( )
91105 }
92106
93107 /// Randomly generated queue object name to represent the JavaScript event queue object.
94108 pub ( crate ) fn queue_object_name ( & self ) -> String {
95- self . queue_object_name . to_string ( )
109+ self . inner . queue_object_name . to_string ( )
96110 }
97111
98- fn listen_internal < F > ( & self , event : E , window : Option < L > , handler : F ) -> EventHandler
99- where
100- F : Fn ( Event ) -> AfterHandle + Send + ' static ,
101- {
102- let id = EventHandler ( Uuid :: new_v4 ( ) ) ;
103-
112+ /// Insert a pending event action to the queue.
113+ fn insert_pending ( & self , action : Pending < Event , Window > ) {
104114 self
105115 . inner
116+ . pending
106117 . lock ( )
107- . expect ( "poisoned event mutex" )
108- . entry ( event)
109- . or_default ( )
110- . insert (
111- id,
112- Handler {
113- window,
114- callback : Box :: new ( handler) ,
115- } ,
116- ) ;
118+ . expect ( "poisoned pending event queue" )
119+ . push ( action)
120+ }
117121
118- id
122+ /// Finish all pending event actions.
123+ fn flush_pending ( & self ) {
124+ let pending = {
125+ let mut lock = self
126+ . inner
127+ . pending
128+ . lock ( )
129+ . expect ( "poisoned pending event queue" ) ;
130+ std:: mem:: take ( & mut * lock)
131+ } ;
132+
133+ for action in pending {
134+ match action {
135+ Pending :: Unlisten ( id) => self . unlisten ( id) ,
136+ Pending :: Listen ( id, event, handler) => self . listen_ ( id, event, handler) ,
137+ Pending :: Trigger ( event, window, payload) => self . trigger ( event, window, payload) ,
138+ }
139+ }
140+ }
141+
142+ fn listen_ ( & self , id : EventHandler , event : Event , handler : Handler < Window > ) {
143+ match self . inner . handlers . try_lock ( ) {
144+ Err ( _) => self . insert_pending ( Pending :: Listen ( id, event, handler) ) ,
145+ Ok ( mut lock) => {
146+ lock. entry ( event) . or_default ( ) . insert ( id, handler) ;
147+ }
148+ }
119149 }
120150
121151 /// Adds an event listener for JS events.
122- pub ( crate ) fn listen < F > ( & self , event : E , window : Option < L > , handler : F ) -> EventHandler
123- where
124- F : Fn ( Event ) + Send + ' static ,
125- {
126- self . listen_internal ( event, window, move |event| {
127- handler ( event) ;
128- AfterHandle :: DoNothing
129- } )
152+ pub ( crate ) fn listen < F : Fn ( self :: Event ) + Send + ' static > (
153+ & self ,
154+ event : Event ,
155+ window : Option < Window > ,
156+ handler : F ,
157+ ) -> EventHandler {
158+ let id = EventHandler ( Uuid :: new_v4 ( ) ) ;
159+ let handler = Handler {
160+ window,
161+ callback : Box :: new ( handler) ,
162+ } ;
163+
164+ self . listen_ ( id, event, handler) ;
165+
166+ id
130167 }
131168
132169 /// Listen to a JS event and immediately unlisten.
133- pub ( crate ) fn once < F : Fn ( Event ) + Send + ' static > (
170+ pub ( crate ) fn once < F : Fn ( self :: Event ) + Send + ' static > (
134171 & self ,
135- event : E ,
136- window : Option < L > ,
172+ event : Event ,
173+ window : Option < Window > ,
137174 handler : F ,
138175 ) -> EventHandler {
139- self . listen_internal ( event, window, move |event| {
176+ let self_ = self . clone ( ) ;
177+ self . listen ( event, window, move |event| {
178+ self_. unlisten ( event. id ) ;
140179 handler ( event) ;
141- AfterHandle :: Remove
142180 } )
143181 }
144182
145183 /// Removes an event listener.
146184 pub ( crate ) fn unlisten ( & self , handler_id : EventHandler ) {
147- self
148- . inner
149- . lock ( )
150- . expect ( "poisoned event mutex" )
151- . values_mut ( )
152- . for_each ( |handler| {
185+ match self . inner . handlers . try_lock ( ) {
186+ Err ( _) => self . insert_pending ( Pending :: Unlisten ( handler_id) ) ,
187+ Ok ( mut lock) => lock. values_mut ( ) . for_each ( |handler| {
153188 handler. remove ( & handler_id) ;
154- } )
189+ } ) ,
190+ }
155191 }
156192
157193 /// Triggers the given global event with its payload.
158- pub ( crate ) fn trigger ( & self , event : E , window : Option < L > , data : Option < String > ) {
159- if let Some ( handlers ) = self
160- . inner
161- . lock ( )
162- . expect ( "poisoned event mutex" )
163- . get_mut ( & event)
164- {
165- handlers . retain ( | & id , handler| {
166- if window . is_none ( ) || window == handler . window {
167- let data = data . clone ( ) ;
168- let payload = Event { id, data } ;
169- ( handler . callback ) ( payload ) != AfterHandle :: Remove
170- } else {
171- // skip and retain all handlers specifying a different window
172- true
194+ pub ( crate ) fn trigger ( & self , event : Event , window : Option < Window > , payload : Option < String > ) {
195+ let mut maybe_pending = false ;
196+ match self . inner . handlers . try_lock ( ) {
197+ Err ( _ ) => self . insert_pending ( Pending :: Trigger ( event , window , payload ) ) ,
198+ Ok ( lock ) => {
199+ if let Some ( handlers ) = lock . get ( & event) {
200+ for ( & id , handler ) in handlers {
201+ if window . is_none ( ) || window == handler. window {
202+ maybe_pending = true ;
203+ ( handler . callback ) ( self :: Event {
204+ id,
205+ data : payload . clone ( ) ,
206+ } )
207+ }
208+ }
173209 }
174- } )
210+ }
211+ }
212+
213+ if maybe_pending {
214+ self . flush_pending ( ) ;
175215 }
176216 }
177217}
@@ -199,7 +239,7 @@ mod test {
199239 listeners. listen( e, None , event_fn) ;
200240
201241 // lock mutex
202- let l = listeners. inner. lock( ) . unwrap( ) ;
242+ let l = listeners. inner. handlers . lock( ) . unwrap( ) ;
203243
204244 // check if the generated key is in the map
205245 assert_eq!( l. contains_key( & key) , true ) ;
@@ -215,7 +255,7 @@ mod test {
215255 listeners. listen( e, None , event_fn) ;
216256
217257 // lock mutex
218- let mut l = listeners. inner. lock( ) . unwrap( ) ;
258+ let mut l = listeners. inner. handlers . lock( ) . unwrap( ) ;
219259
220260 // check if l contains key
221261 if l. contains_key( & key) {
@@ -243,7 +283,7 @@ mod test {
243283 listeners. trigger( e, None , Some ( d) ) ;
244284
245285 // lock the mutex
246- let l = listeners. inner. lock( ) . unwrap( ) ;
286+ let l = listeners. inner. handlers . lock( ) . unwrap( ) ;
247287
248288 // assert that the key is contained in the listeners map
249289 assert!( l. contains_key( & key) ) ;
0 commit comments