@@ -23,7 +23,7 @@ EventDispatcher.prototype = {
2323 return ;
2424 }
2525
26- console . log ( 'Add listener' , type , listener ) ;
26+ // console.log('Add listener', type, listener);
2727
2828 if ( ! this . listeners [ type ] )
2929 {
@@ -38,19 +38,19 @@ EventDispatcher.prototype = {
3838 }
3939 else
4040 {
41- listeners . push ( { listener : listener , priority : priority , isOnce : isOnce } ) ;
41+ listeners . push ( { listener : listener , priority : priority , isOnce : isOnce , toRemove : false } ) ;
4242 }
4343
4444 listeners . sort ( this . sortHandler ) ;
4545 } ,
4646
4747 sortHandler : function ( listenerA , listenerB )
4848 {
49- if ( listenerA . priority < listenerB . priority )
49+ if ( listenerB . priority < listenerA . priority )
5050 {
5151 return - 1 ;
5252 }
53- else if ( listenerA . priority > listenerB . priority )
53+ else if ( listenerB . priority > listenerA . priority )
5454 {
5555 return 1 ;
5656 }
@@ -76,6 +76,8 @@ EventDispatcher.prototype = {
7676
7777 } ,
7878
79+ // Need to test what happens if array is sorted during DISPATCH phase (does it screw it all up?)
80+
7981 on : function ( type , listener , priority )
8082 {
8183 if ( priority === undefined ) { priority = 0 ; }
@@ -94,6 +96,16 @@ EventDispatcher.prototype = {
9496 return this ;
9597 } ,
9698
99+ total : function ( type )
100+ {
101+ if ( ! this . listeners || ! this . listeners [ type ] )
102+ {
103+ return - 1 ;
104+ }
105+
106+ return this . listeners [ type ] . length ;
107+ } ,
108+
97109 has : function ( type , listener )
98110 {
99111 if ( ! this . listeners || ! this . listeners [ type ] )
@@ -129,9 +141,17 @@ EventDispatcher.prototype = {
129141 {
130142 if ( listeners [ i ] . listener === listener )
131143 {
132- console . log ( 'Remove listener' , type , listener ) ;
144+ if ( this . _state === EventDispatcher . STATE_DISPATCHING )
145+ {
146+ console . log ( 'Flag listener for removal' , type ) ;
147+ listeners [ i ] . toRemove = true ;
148+ }
149+ else
150+ {
151+ console . log ( 'Remove listener' , type ) ;
152+ listeners . splice ( i , 1 ) ;
153+ }
133154
134- listeners . splice ( i , 1 ) ;
135155 break ;
136156 }
137157 }
@@ -148,21 +168,39 @@ EventDispatcher.prototype = {
148168 return false ;
149169 }
150170
151- this . _state = EventDispatcher . STATE_DISPATCHING ;
152-
153171 var listeners = this . listeners [ event . type ] ;
154172
173+ // This was a valid dispatch call, we just had nothing to do ...
174+ if ( listeners . length === 0 )
175+ {
176+ return true ;
177+ }
178+
179+ this . _state = EventDispatcher . STATE_DISPATCHING ;
180+
155181 event . reset ( this ) ;
156182
157183 var toRemove = [ ] ;
184+
185+ var entry ;
158186 var entries = listeners . slice ( ) ;
187+ // var entries = listeners;
159188
160189 console . log ( 'Dispatching' , entries . length , 'listeners' ) ;
161190
162191 for ( var i = 0 ; i < entries . length ; i ++ )
163192 {
193+ entry = entries [ i ] ;
194+
195+ if ( entry . toRemove )
196+ {
197+ toRemove . push ( entry ) ;
198+ continue ;
199+ }
200+
164201 // Add Custom Events
165- entries [ i ] . listener . call ( this , event ) ;
202+ // If this adjusts the entries.length for any reason, the reference is still valid
203+ entry . listener . call ( this , event ) ;
166204
167205 // Has the callback done something disastrous? Like called removeAll, or nuked the dispatcher?
168206 if ( this . _state !== EventDispatcher . STATE_DISPATCHING )
@@ -171,9 +209,10 @@ EventDispatcher.prototype = {
171209 break ;
172210 }
173211
174- if ( entries [ i ] . isOnce )
212+ // Was a 'once' or was removed during the callback
213+ if ( entry . isOnce || entry . toRemove )
175214 {
176- toRemove . push ( entries [ i ] ) ;
215+ toRemove . push ( entry ) ;
177216 }
178217
179218 // Has the event been halted?
@@ -200,9 +239,11 @@ EventDispatcher.prototype = {
200239
201240 for ( i = 0 ; i < toRemove . length ; i ++ )
202241 {
203- this . off ( toRemove [ i ] . type , toRemove [ i ] . listener ) ;
242+ this . off ( event . type , toRemove [ i ] . listener ) ;
204243 }
205244
245+ toRemove . length = 0 ;
246+
206247 this . _state = EventDispatcher . STATE_PENDING ;
207248 }
208249
0 commit comments