1+ /*
2+ Due to @types/three r168 breaking change
3+ we have to manually copy the EventDispatcher class from three.js.
4+ So this files merges the declarations from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/three/src/core/EventDispatcher.d.ts
5+ with the implementation from https://github.com/mrdoob/three.js/blob/dev/src/core/EventDispatcher.js
6+ More info in https://github.com/pmndrs/three-stdlib/issues/387
7+ */
8+
9+ /**
10+ * The minimal basic Event that can be dispatched by a {@link EventDispatcher<>}.
11+ */
12+ export interface BaseEvent < TEventType extends string = string > {
13+ readonly type : TEventType ;
14+ // not defined in @types /three
15+ target : any ;
16+ }
17+
18+ /**
19+ * The minimal expected contract of a fired Event that was dispatched by a {@link EventDispatcher<>}.
20+ */
21+ export interface Event < TEventType extends string = string , TTarget = unknown > {
22+ readonly type : TEventType ;
23+ readonly target : TTarget ;
24+ }
25+
26+ export type EventListener < TEventData , TEventType extends string , TTarget > = (
27+ event : TEventData & Event < TEventType , TTarget > ,
28+ ) => void ;
29+
30+ export class EventDispatcher < TEventMap extends { } = { } > {
31+ // not defined in @types /three
32+ private _listeners : any ;
33+
34+ /**
35+ * Adds a listener to an event type.
36+ * @param type The type of event to listen to.
37+ * @param listener The function that gets called when the event is fired.
38+ */
39+ addEventListener < T extends Extract < keyof TEventMap , string > > (
40+ type : T ,
41+ listener : EventListener < TEventMap [ T ] , T , this> ,
42+ ) : void {
43+
44+ if ( this . _listeners === undefined ) this . _listeners = { } ;
45+
46+ const listeners = this . _listeners ;
47+
48+ if ( listeners [ type ] === undefined ) {
49+
50+ listeners [ type ] = [ ] ;
51+
52+ }
53+
54+ if ( listeners [ type ] . indexOf ( listener ) === - 1 ) {
55+
56+ listeners [ type ] . push ( listener ) ;
57+
58+ }
59+
60+ }
61+
62+ /**
63+ * Checks if listener is added to an event type.
64+ * @param type The type of event to listen to.
65+ * @param listener The function that gets called when the event is fired.
66+ */
67+ hasEventListener < T extends Extract < keyof TEventMap , string > > (
68+ type : T ,
69+ listener : EventListener < TEventMap [ T ] , T , this> ,
70+ ) : boolean {
71+
72+ if ( this . _listeners === undefined ) return false ;
73+
74+ const listeners = this . _listeners ;
75+
76+ return listeners [ type ] !== undefined && listeners [ type ] . indexOf ( listener ) !== - 1 ;
77+
78+ }
79+
80+ /**
81+ * Removes a listener from an event type.
82+ * @param type The type of the listener that gets removed.
83+ * @param listener The listener function that gets removed.
84+ */
85+ removeEventListener < T extends Extract < keyof TEventMap , string > > (
86+ type : T ,
87+ listener : EventListener < TEventMap [ T ] , T , this> ,
88+ ) : void {
89+
90+ if ( this . _listeners === undefined ) return ;
91+
92+ const listeners = this . _listeners ;
93+ const listenerArray = listeners [ type ] ;
94+
95+ if ( listenerArray !== undefined ) {
96+
97+ const index = listenerArray . indexOf ( listener ) ;
98+
99+ if ( index !== - 1 ) {
100+
101+ listenerArray . splice ( index , 1 ) ;
102+
103+ }
104+
105+ }
106+
107+ }
108+
109+ /**
110+ * Fire an event type.
111+ * @param event The event that gets fired.
112+ */
113+ dispatchEvent < T extends Extract < keyof TEventMap , string > > ( event : BaseEvent < T > & TEventMap [ T ] ) : void {
114+
115+ if ( this . _listeners === undefined ) return ;
116+
117+ const listeners = this . _listeners ;
118+ const listenerArray = listeners [ event . type ] ;
119+
120+ if ( listenerArray !== undefined ) {
121+
122+ event . target = this ;
123+
124+ // Make a copy, in case listeners are removed while iterating.
125+ const array = listenerArray . slice ( 0 ) ;
126+
127+ for ( let i = 0 , l = array . length ; i < l ; i ++ ) {
128+
129+ array [ i ] . call ( this , event ) ;
130+
131+ }
132+
133+ event . target = null ;
134+
135+ }
136+
137+ }
138+
139+ }
0 commit comments