forked from Orillusion/orillusion
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CEventDispatcher.ts
210 lines (195 loc) · 7.47 KB
/
CEventDispatcher.ts
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
import { CEvent } from './CEvent';
import { CEventListener } from './CEventListener';
/**
* Basic class of event diapatcher.
* It includes the implementation of functions such as event registration,
* deregistration, distribution, and unregister.
* @group Events
*/
export class CEventDispatcher {
/**
* @internal
*/
protected listeners: any = {};
/**
* @internal
*/
public data: any;
/**
*
* Dispatch an event to all registered objects with a specific type of listener.
* @param event3D the event is dispatched.
*/
public dispatchEvent(event: CEvent) {
var list: any = this.listeners[event.type];
if (list != null) {
list = list.slice();
for (var i: number = 0; i < list.length; i++) {
var listener: CEventListener = list[i];
if (listener.handler) {
try {
event.param = listener.param;
event.currentTarget = listener;
if (!listener.thisObject) {
// log("nullListener thisObject");
}
listener.handler.call(listener.thisObject, event);
} catch (error) {
// if (window.//console) {
//console.error(error.stack);
// }
}
if (event.isStopImmediatePropagation) {
break;
}
}
}
}
}
/**
*
* release all registered event.
*/
public destroy() {
for (var key in this.listeners) {
var list: any = this.listeners[key];
while (list.length > 0) {
var listener: CEventListener = list[0];
listener.handler = null;
listener.thisObject = null;
list.splice(0, 1);
}
}
}
/**
*
* register an event listener to event distancher.
* @param type {string} event type.
* @param callback {Function} The callback function that handles events.
* This function must accept an Event3D object as its unique parameter and cannot return any result.
* for example: function(evt:Event3D):void.
* @param thisObject {any} Current registration object, it'll call callback function.
* @param param {any} the data binded to registered event, the default value is null.
* @param priority {number} The priority of callback function execution, with a larger set value having priority to call
* @returns {number} Returns register event id
*/
public addEventListener(type: string | number, callback: Function, thisObject: any, param: any = null, priority: number = 0): number {
if (this.listeners[type] == null) {
this.listeners[type] = [];
}
if (!this.hasEventListener(type, callback, thisObject)) {
var listener: CEventListener = new CEventListener(type, thisObject, callback, param, priority);
listener.id = ++CEventListener.event_id_count;
listener.current = this;
this.listeners[type].push(listener);
this.listeners[type].sort(function (listener1: CEventListener, listener2: CEventListener) {
return listener2.priority - listener1.priority;
});
return listener.id;
}
for (let i = 0; i < this.listeners[type].length; i++) {
let listener: CEventListener = this.listeners[type][i];
if (listener.equalCurrentListener(type, callback, thisObject, param)) {
return listener.id;
}
}
return 0;
}
/**
*
* Remove Event Listening
* @param type {string} event type
* @param callback {Function} callback function of event register
* @param thisObject {any} The current registered object.
*/
public removeEventListener(type: string | number, callback: Function, thisObject: any): void {
if (this.hasEventListener(type, callback, thisObject)) {
for (var i: number = 0; i < this.listeners[type].length; i++) {
var listener: CEventListener = this.listeners[type][i];
if (listener.equalCurrentListener(type, callback, thisObject, listener.param)) {
listener.handler = null;
listener.thisObject = null;
this.listeners[type].splice(i, 1);
return;
}
}
}
}
/**
*
* Remove an event Listening with id
* @param register event id, see {@link addEventListener}
* Returns true when removed success.
*/
public removeEventListenerAt(id: number): boolean {
for (var key in this.listeners) {
for (var i: number = 0; i < this.listeners[key].length; i++) {
var listener = this.listeners[key][i];
if (listener.id == id) {
listener.handler = null;
listener.thisObject = null;
this.listeners[key].splice(i, 1);
return true;
}
}
}
return false;
}
/**
*
* Specify a event type to remove all related event listeners
* eventType event type, set null to remove all event listeners
*/
public removeAllEventListener(eventType: string | number = null): void {
let listener: CEventListener;
if (eventType) {
if (this.listeners[eventType]) {
for (var i: number = 0; i < this.listeners[eventType].length; i++) {
listener = this.listeners[eventType][i];
listener.dispose();
this.listeners[eventType].splice(i, 1);
}
delete this.listeners[eventType];
}
} else {
for (let key in this.listeners) {
for (var i: number = 0; i < this.listeners[key].length; i++) {
listener = this.listeners[key][i];
listener.dispose();
this.listeners[key].splice(i, 1);
}
delete this.listeners[key];
}
}
}
/**
*
* whether the target presence of a listener with event type.
* @param type {string} event type.
* @returns {boolean} Returns a boolean.
*/
public containEventListener(type: string): boolean {
if (this.listeners[type] == null) return false;
return this.listeners[type].length > 0;
}
/**
*
* whether the target presence of a listener with event type. it associate more registration parameters.
* @param type {string} event name.
* @param callback {Function} callback function of event register.
* @param thisObject {any} The registered object.
* @returns {boolean} Returns a boolean.
*/
public hasEventListener(type: string | number, callback: Function = null, thisObject: any = null): boolean {
if (this.listeners[type] == null) return false;
if (thisObject && callback) {
for (var i: number = 0; i < this.listeners[type].length; i++) {
var listener: CEventListener = this.listeners[type][i];
if (listener.equalCurrentListener(type, callback, thisObject, listener.param)) {
return true;
}
}
}
return false;
}
}