-
Notifications
You must be signed in to change notification settings - Fork 0
/
ticker.js
96 lines (89 loc) · 2.72 KB
/
ticker.js
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
export class Ticker {
/**
* @param {Iterable<(time: number) => void>} pipeline Iterável com a
* sequência de função/sistemas a serem executados em cada tick.
* @param { 'auto' | number } times Configura se a `pipeline` será
* executada a cada frame ou em um intervalo de tempo predeterminado.
* o valor `'auto'` configura para rodar a cada frame e se for passado
* um número, esse número indicara a quantidade de execuções por minuto
* esperadas.
*/
constructor(pipeline, times = 'auto') {
/**
* @private
* @type {boolean}
*/
this.running = false;
/**
* @private
* @type {number}
*/
this.lastTime = 0;
/**
* @private
* @type {number}
*/
this.tickerID = null;
/**
* @private
* @type {Iterable<(time: number) => void>}
*/
this.pipeline = pipeline;
/**
* @private
* @type {'auto' | number}
*/
this.times = (times === 'auto') ? 'auto' : 1000 / times;
/**
* @private
* @type {number}
*/
this.cumulatedTime = 0;
}
/**
* @private
* @param {number} [time] valor de tempo em milissegundos
*/
update(time = 0) {
const deltaTime = time - this.lastTime;
this.lastTime = time;
this.cumulatedTime += deltaTime;
try {
this.tickerID = requestAnimationFrame((timestamp) => this.update(timestamp));
if (this.times === 'auto' || this.cumulatedTime > this.times) {
for (const system of this.pipeline) {
system(this.times === 'auto' ? deltaTime : this.cumulatedTime);
}
this.cumulatedTime = 0;
}
} catch (ex) {
console.error(ex);
this.clear();
}
}
/**
* Método que para a execução do ticker
* @public
* @returns {void}
*/
clear() {
cancelAnimationFrame(this.tickerID);
}
/**
* Método que inicializa o ticker
* @todo João, talvez fosse interessant o método start não invocar o update
* logo de cara e sim registrar o callback para rodar no próximo frame.
* Talvez seria interessante ter outro método ou até mesmo um parâmetro
* no método atual para configurar esse comportamento.
* @todo João, se o framerate passado na função construtora for maior que o
* framerate do monitor essa classe utilitária não vai ter o comportamento
* correto.
* @public
* @returns {void}
*/
start() {
if (!this.running) {
this.update();
}
}
}