-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
/
TickerListener.ts
142 lines (126 loc) · 3.54 KB
/
TickerListener.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
import { TickerCallback } from './Ticker';
/**
* Internal class for handling the priority sorting of ticker handlers.
*
* @private
* @class
* @memberof PIXI
*/
export class TickerListener<T = any>
{
/** The current priority. */
public priority: number;
/** The next item in chain. */
public next: TickerListener = null;
/** The previous item in chain. */
public previous: TickerListener = null;
/** The handler function to execute. */
private fn: TickerCallback<T>;
/** The calling to execute. */
private context: T;
/** If this should only execute once. */
private once: boolean;
/** `true` if this listener has been destroyed already. */
private _destroyed = false;
/**
* Constructor
* @private
* @param fn - The listener function to be added for one update
* @param context - The listener context
* @param priority - The priority for emitting
* @param once - If the handler should fire once
*/
constructor(fn: TickerCallback<T>, context: T = null, priority = 0, once = false)
{
this.fn = fn;
this.context = context;
this.priority = priority;
this.once = once;
}
/**
* Simple compare function to figure out if a function and context match.
* @private
* @param fn - The listener function to be added for one update
* @param context - The listener context
* @return `true` if the listener match the arguments
*/
match(fn: TickerCallback<T>, context: any = null): boolean
{
return this.fn === fn && this.context === context;
}
/**
* Emit by calling the current function.
* @private
* @param deltaTime - time since the last emit.
* @return Next ticker
*/
emit(deltaTime: number): TickerListener
{
if (this.fn)
{
if (this.context)
{
this.fn.call(this.context, deltaTime);
}
else
{
(this as TickerListener<any>).fn(deltaTime);
}
}
const redirect = this.next;
if (this.once)
{
this.destroy(true);
}
// Soft-destroying should remove
// the next reference
if (this._destroyed)
{
this.next = null;
}
return redirect;
}
/**
* Connect to the list.
* @private
* @param previous - Input node, previous listener
*/
connect(previous: TickerListener): void
{
this.previous = previous;
if (previous.next)
{
previous.next.previous = this;
}
this.next = previous.next;
previous.next = this;
}
/**
* Destroy and don't use after this.
* @private
* @param hard - `true` to remove the `next` reference, this
* is considered a hard destroy. Soft destroy maintains the next reference.
* @return The listener to redirect while emitting or removing.
*/
destroy(hard = false): TickerListener
{
this._destroyed = true;
this.fn = null;
this.context = null;
// Disconnect, hook up next and previous
if (this.previous)
{
this.previous.next = this.next;
}
if (this.next)
{
this.next.previous = this.previous;
}
// Redirect to the next item
const redirect = this.next;
// Remove references
this.next = hard ? null : redirect;
this.previous = null;
return redirect;
}
}