-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathImageContext.js
96 lines (80 loc) · 2.37 KB
/
ImageContext.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
/**
* Copyright (C) 2022, BBC R&D
* This source code is licensed under the GPL license found in the LICENSE file in this repository.
*/
import ImageSourceNode from './ImageSourceNode';
class ImageContext {
constructor(updateCallback, audioContext) {
this._updateCallback = updateCallback;
this._nodes = new Set();
this._currentSource = null;
this._audioContext = audioContext;
this._timeoutLength = 100;
this._timeout = 0; // hold reference for each subsequent tick
this._nextNodeId = 0;
}
tick() {
clearTimeout(this._timeout);
// Find the currently active (started, and within duration) source node with highest priority.
// Set iteration is in insertion order, so we should always choose the oldest active node if
// there are multiple with the same priority.
const newSource = [...this._nodes]
.filter((node) => node.isActive())
.reduce((highestPriorityNode, node) => {
if (!highestPriorityNode || node.priority > highestPriorityNode.priority) {
return node;
}
return highestPriorityNode;
}, null);
let updateRequired = false;
if (newSource !== this._currentSource) {
this._currentSource = newSource;
updateRequired = true;
}
// Update with the currentSource's image, or null.
if (updateRequired) {
this._update();
}
// schedule the next update if there are any registered nodes
if (this._nodes.size > 0) {
this._scheduleNextTick();
}
}
_scheduleNextTick() {
clearTimeout(this._timeout);
this._timeout = setTimeout(() => this.tick(), this._timeoutLength);
}
_update() {
if (this._updateCallback) {
if (this._currentSource) {
this._updateCallback(this._currentSource.image);
} else {
this._updateCallback(null);
}
}
}
// eslint-disable-next-line no-unused-vars
connect(node, destination) {
this._nodes.add(node);
this._scheduleNextTick();
}
disconnect(node) {
this._nodes.delete(node);
}
pause() {
clearTimeout(this._timeout);
}
resume() {
this._scheduleNextTick();
}
createImageSource(...args) {
const source = new ImageSourceNode(this, ...args);
source.nodeId = this._nextNodeId;
this._nextNodeId += 1;
return source;
}
get currentTime() {
return this._audioContext.currentTime;
}
}
export default ImageContext;