@woosh/meep-engine 2.48.11 → 2.48.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/core/collection/HashMap.js +2 -2
- package/src/core/collection/HashMap.spec.js +24 -1
- package/src/core/collection/queue/Deque.d.ts +9 -0
- package/src/core/collection/queue/Deque.js +3 -0
- package/src/core/collection/queue/Deque.spec.js +51 -0
- package/src/core/debug/matchers/matchers.js +10 -0
- package/src/core/math/noise/create_noise_2d.js +193 -0
- package/src/engine/Engine.js +9 -5
- package/src/engine/asset/AssetManager.d.ts +10 -5
- package/src/engine/asset/AssetManager.js +22 -9
- package/src/engine/asset/PendingAsset.js +6 -6
- package/src/engine/asset/loaders/AssetLoader.d.ts +7 -2
- package/src/engine/asset/loaders/AssetLoader.js +17 -15
- package/src/engine/asset/loaders/GLTFAssetLoader.js +1 -1
- package/src/engine/asset/loaders/SoundAssetLoader.js +3 -5
- package/src/engine/development/performance/MetricStatistics.js +7 -5
- package/src/engine/development/performance/RingBufferMetric.js +2 -2
- package/src/engine/ecs/foliage/ecs/InstancedMeshUtils.js +14 -1
- package/src/engine/ecs/gui/GUIElementSystem.d.ts +1 -1
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +3 -21
- package/src/engine/graphics/ecs/camera/pp/PerfectPanner.js +4 -2
- package/src/engine/graphics/texture/3d/SingleChannelSampler3D.js +146 -0
- package/src/engine/graphics/texture/3d/scs3d_read_2d_slice.js +26 -0
- package/src/engine/graphics/texture/sampler/Sampler2D.js +2 -2
- package/src/engine/physics/fluid/FluidField.js +153 -1
- package/src/engine/physics/fluid/prototype.js +201 -0
- package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.js +67 -0
- package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +17 -12
- package/src/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +14 -10
package/package.json
CHANGED
|
@@ -589,7 +589,7 @@ export class HashMap {
|
|
|
589
589
|
} else {
|
|
590
590
|
return {
|
|
591
591
|
done: false,
|
|
592
|
-
value: n.value[
|
|
592
|
+
value: n.value[1]
|
|
593
593
|
};
|
|
594
594
|
}
|
|
595
595
|
|
|
@@ -616,7 +616,7 @@ export class HashMap {
|
|
|
616
616
|
} else {
|
|
617
617
|
return {
|
|
618
618
|
done: false,
|
|
619
|
-
value: n.value[
|
|
619
|
+
value: n.value[0]
|
|
620
620
|
};
|
|
621
621
|
}
|
|
622
622
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HashMap } from "./HashMap.js";
|
|
2
|
-
import { passThrough, strictEquals } from "../function/Functions.js";
|
|
2
|
+
import { passThrough, returnOne, strictEquals } from "../function/Functions.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
*
|
|
@@ -74,3 +74,26 @@ test("retrieval works as intended after hash map grows", () => {
|
|
|
74
74
|
expect(m.get(-7)).toEqual("c");
|
|
75
75
|
|
|
76
76
|
});
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
test("key iterator", () => {
|
|
80
|
+
const map = new HashMap({
|
|
81
|
+
keyHashFunction: returnOne,
|
|
82
|
+
keyEqualityFunction: strictEquals
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
map.set(7, "hello");
|
|
86
|
+
|
|
87
|
+
expect(map.keys().next().value).toBe(7);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("value iterator", () => {
|
|
91
|
+
const map = new HashMap({
|
|
92
|
+
keyHashFunction: returnOne,
|
|
93
|
+
keyEqualityFunction: strictEquals
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
map.set(7, "hello");
|
|
97
|
+
|
|
98
|
+
expect(map.values().next().value).toBe("hello");
|
|
99
|
+
});
|
|
@@ -7,6 +7,8 @@ export class Deque<T> {
|
|
|
7
7
|
|
|
8
8
|
size(): number
|
|
9
9
|
|
|
10
|
+
isEmpty(): boolean
|
|
11
|
+
|
|
10
12
|
remove(e: T): boolean
|
|
11
13
|
|
|
12
14
|
has(e: T): boolean
|
|
@@ -17,4 +19,11 @@ export class Deque<T> {
|
|
|
17
19
|
|
|
18
20
|
add(e: T): void
|
|
19
21
|
|
|
22
|
+
addFirst(e: T): void
|
|
23
|
+
|
|
24
|
+
removeFirst(): T
|
|
25
|
+
|
|
26
|
+
addLast(e: T): void
|
|
27
|
+
|
|
28
|
+
removeLast(): T
|
|
20
29
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ceilPowerOfTwo } from "../../binary/operations/ceilPowerOfTwo.js";
|
|
2
2
|
import { max2 } from "../../math/max2.js";
|
|
3
3
|
import { array_copy } from "../array/copyArray.js";
|
|
4
|
+
import { assert } from "../../assert.js";
|
|
4
5
|
|
|
5
6
|
const DEFAULT_SIZE = 16;
|
|
6
7
|
|
|
@@ -18,6 +19,8 @@ export class Deque {
|
|
|
18
19
|
*/
|
|
19
20
|
constructor(minSize = DEFAULT_SIZE) {
|
|
20
21
|
|
|
22
|
+
assert.isNonNegativeInteger(minSize, 'minSize');
|
|
23
|
+
|
|
21
24
|
const size = ceilPowerOfTwo(max2(DEFAULT_SIZE, minSize));
|
|
22
25
|
|
|
23
26
|
/**
|
|
@@ -87,3 +87,54 @@ test('size', () => {
|
|
|
87
87
|
|
|
88
88
|
expect(deque.size()).toBe(0);
|
|
89
89
|
});
|
|
90
|
+
|
|
91
|
+
test("remove the only item", () => {
|
|
92
|
+
const deque = new Deque();
|
|
93
|
+
|
|
94
|
+
deque.add(7);
|
|
95
|
+
|
|
96
|
+
expect(deque.remove(7)).toBe(true);
|
|
97
|
+
|
|
98
|
+
expect(deque.size()).toBe(0);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test("remove first item", () => {
|
|
102
|
+
|
|
103
|
+
const deque = new Deque();
|
|
104
|
+
|
|
105
|
+
deque.add(7);
|
|
106
|
+
deque.add(13);
|
|
107
|
+
|
|
108
|
+
expect(deque.remove(7)).toBe(true);
|
|
109
|
+
expect(deque.size()).toBe(1);
|
|
110
|
+
|
|
111
|
+
expect(deque.pop()).toBe(13);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("remove last item", () => {
|
|
115
|
+
|
|
116
|
+
const deque = new Deque();
|
|
117
|
+
|
|
118
|
+
deque.add(7);
|
|
119
|
+
deque.add(13);
|
|
120
|
+
|
|
121
|
+
expect(deque.remove(13)).toBe(true);
|
|
122
|
+
expect(deque.size()).toBe(1);
|
|
123
|
+
|
|
124
|
+
expect(deque.pop()).toBe(7);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("remove middle item", () => {
|
|
128
|
+
|
|
129
|
+
const deque = new Deque();
|
|
130
|
+
|
|
131
|
+
deque.add(7);
|
|
132
|
+
deque.add(13);
|
|
133
|
+
deque.add(17);
|
|
134
|
+
|
|
135
|
+
expect(deque.remove(13)).toBe(true);
|
|
136
|
+
expect(deque.size()).toBe(2);
|
|
137
|
+
|
|
138
|
+
expect(deque.pop()).toBe(7);
|
|
139
|
+
expect(deque.pop()).toBe(17);
|
|
140
|
+
});
|
|
@@ -10,10 +10,20 @@ import { IsIn } from "./IsIn.js";
|
|
|
10
10
|
import { IsAnything } from "./IsAnything.js";
|
|
11
11
|
import { DescribeAs } from "./DescribeAs.js";
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* @template T
|
|
15
|
+
* @param {Matcher<T>} matchers
|
|
16
|
+
* @return {Matcher<T>}
|
|
17
|
+
*/
|
|
13
18
|
export function anyOf(...matchers) {
|
|
14
19
|
return new AnyOf(matchers);
|
|
15
20
|
}
|
|
16
21
|
|
|
22
|
+
/**
|
|
23
|
+
* @template T
|
|
24
|
+
* @param {Matcher<T>} matchers
|
|
25
|
+
* @return {Matcher<T>}
|
|
26
|
+
*/
|
|
17
27
|
export function allOf(...matchers) {
|
|
18
28
|
return new AllOf(matchers);
|
|
19
29
|
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/*
|
|
2
|
+
NOTE: this implementation is adapted from https://github.com/jwagner/simplex-noise.js
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// these #__PURE__ comments help uglifyjs with dead code removal
|
|
6
|
+
//
|
|
7
|
+
const F2 = /*#__PURE__*/ 0.5 * (Math.sqrt(3.0) - 1.0);
|
|
8
|
+
const G2 = /*#__PURE__*/ (3.0 - Math.sqrt(3.0)) / 6.0;
|
|
9
|
+
const F3 = 1.0 / 3.0;
|
|
10
|
+
const G3 = 1.0 / 6.0;
|
|
11
|
+
const F4 = /*#__PURE__*/ (Math.sqrt(5.0) - 1.0) / 4.0;
|
|
12
|
+
const G4 = /*#__PURE__*/ (5.0 - Math.sqrt(5.0)) / 20.0;
|
|
13
|
+
const grad2 = /*#__PURE__*/ new Int8Array([1, 1,
|
|
14
|
+
-1, 1,
|
|
15
|
+
1, -1,
|
|
16
|
+
|
|
17
|
+
-1, -1,
|
|
18
|
+
1, 0,
|
|
19
|
+
-1, 0,
|
|
20
|
+
|
|
21
|
+
1, 0,
|
|
22
|
+
-1, 0,
|
|
23
|
+
0, 1,
|
|
24
|
+
|
|
25
|
+
0, -1,
|
|
26
|
+
0, 1,
|
|
27
|
+
0, -1]);
|
|
28
|
+
|
|
29
|
+
// double seems to be faster than single or int's
|
|
30
|
+
// probably because most operations are in double precision
|
|
31
|
+
const grad3 = /*#__PURE__*/ new Float64Array([1, 1, 0,
|
|
32
|
+
-1, 1, 0,
|
|
33
|
+
1, -1, 0,
|
|
34
|
+
|
|
35
|
+
-1, -1, 0,
|
|
36
|
+
1, 0, 1,
|
|
37
|
+
-1, 0, 1,
|
|
38
|
+
|
|
39
|
+
1, 0, -1,
|
|
40
|
+
-1, 0, -1,
|
|
41
|
+
0, 1, 1,
|
|
42
|
+
|
|
43
|
+
0, -1, 1,
|
|
44
|
+
0, 1, -1,
|
|
45
|
+
0, -1, -1]);
|
|
46
|
+
|
|
47
|
+
// double is a bit quicker here as well
|
|
48
|
+
const grad4 = /*#__PURE__*/ new Float64Array([0, 1, 1, 1, 0, 1, 1, -1, 0, 1, -1, 1, 0, 1, -1, -1,
|
|
49
|
+
0, -1, 1, 1, 0, -1, 1, -1, 0, -1, -1, 1, 0, -1, -1, -1,
|
|
50
|
+
1, 0, 1, 1, 1, 0, 1, -1, 1, 0, -1, 1, 1, 0, -1, -1,
|
|
51
|
+
-1, 0, 1, 1, -1, 0, 1, -1, -1, 0, -1, 1, -1, 0, -1, -1,
|
|
52
|
+
1, 1, 0, 1, 1, 1, 0, -1, 1, -1, 0, 1, 1, -1, 0, -1,
|
|
53
|
+
-1, 1, 0, 1, -1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, -1,
|
|
54
|
+
1, 1, 1, 0, 1, 1, -1, 0, 1, -1, 1, 0, 1, -1, -1, 0,
|
|
55
|
+
-1, 1, 1, 0, -1, 1, -1, 0, -1, -1, 1, 0, -1, -1, -1, 0]);
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Creates a 2D noise function
|
|
60
|
+
* @param random the random function that will be used to build the permutation table
|
|
61
|
+
* @returns {function(x:number, y:number):number}
|
|
62
|
+
*/
|
|
63
|
+
export function createNoise2D(random = Math.random) {
|
|
64
|
+
// allocate continuous chunk of memory
|
|
65
|
+
const buffer = new ArrayBuffer(512 * 2);
|
|
66
|
+
|
|
67
|
+
const perm = new Uint8Array(buffer, 0, 512);
|
|
68
|
+
buildPermutationTable(random, perm);
|
|
69
|
+
|
|
70
|
+
const permMod12 = new Uint8Array(buffer, 512, 512);
|
|
71
|
+
|
|
72
|
+
for (let i = 0; i < 512; i++) {
|
|
73
|
+
permMod12[i] = (perm[i] % 12) * 2;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return function noise2D(x, y) {
|
|
77
|
+
// if(!isFinite(x) || !isFinite(y)) return 0;
|
|
78
|
+
let n0 = 0; // Noise contributions from the three corners
|
|
79
|
+
let n1 = 0;
|
|
80
|
+
let n2 = 0;
|
|
81
|
+
// Skew the input space to determine which simplex cell we're in
|
|
82
|
+
const s = (x + y) * F2; // Hairy factor for 2D
|
|
83
|
+
|
|
84
|
+
const i = (x + s) | 0;
|
|
85
|
+
const j = (y + s) | 0;
|
|
86
|
+
|
|
87
|
+
const t = (i + j) * G2;
|
|
88
|
+
const X0 = i - t; // Unskew the cell origin back to (x,y) space
|
|
89
|
+
const Y0 = j - t;
|
|
90
|
+
const x0 = x - X0; // The x,y distances from the cell origin
|
|
91
|
+
const y0 = y - Y0;
|
|
92
|
+
// For the 2D case, the simplex shape is an equilateral triangle.
|
|
93
|
+
// Determine which simplex we are in.
|
|
94
|
+
let i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
|
|
95
|
+
if (x0 > y0) {
|
|
96
|
+
i1 = 1;
|
|
97
|
+
j1 = 0;
|
|
98
|
+
} // lower triangle, XY order: (0,0)->(1,0)->(1,1)
|
|
99
|
+
else {
|
|
100
|
+
i1 = 0;
|
|
101
|
+
j1 = 1;
|
|
102
|
+
} // upper triangle, YX order: (0,0)->(0,1)->(1,1)
|
|
103
|
+
// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
|
|
104
|
+
// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
|
|
105
|
+
// c = (3-sqrt(3))/6
|
|
106
|
+
const x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
|
|
107
|
+
const y1 = y0 - j1 + G2;
|
|
108
|
+
const x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords
|
|
109
|
+
const y2 = y0 - 1.0 + 2.0 * G2;
|
|
110
|
+
// Work out the hashed gradient indices of the three simplex corners
|
|
111
|
+
const ii = i & 255;
|
|
112
|
+
const jj = j & 255;
|
|
113
|
+
// Calculate the contribution from the three corners
|
|
114
|
+
let t0 = 0.5 - x0 * x0 - y0 * y0;
|
|
115
|
+
|
|
116
|
+
if (t0 >= 0) {
|
|
117
|
+
const gi0 = ii + perm[jj];
|
|
118
|
+
const gi01 = permMod12[gi0];
|
|
119
|
+
|
|
120
|
+
const g0x = grad2[gi01];
|
|
121
|
+
const g0y = grad2[gi01 + 1];
|
|
122
|
+
|
|
123
|
+
t0 *= t0;
|
|
124
|
+
// n0 = t0 * t0 * (grad2[gi0] * x0 + grad2[gi0 + 1] * y0); // (x,y) of grad3 used for 2D gradient
|
|
125
|
+
n0 = t0 * t0 * (g0x * x0 + g0y * y0);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let t1 = 0.5 - x1 * x1 - y1 * y1;
|
|
129
|
+
|
|
130
|
+
if (t1 >= 0) {
|
|
131
|
+
const gi1 = ii + i1 + perm[jj + j1];
|
|
132
|
+
const gi11 = permMod12[gi1];
|
|
133
|
+
|
|
134
|
+
const g1x = grad2[gi11];
|
|
135
|
+
const g1y = grad2[gi11 + 1];
|
|
136
|
+
|
|
137
|
+
t1 *= t1;
|
|
138
|
+
// n1 = t1 * t1 * (grad2[gi1] * x1 + grad2[gi1 + 1] * y1);
|
|
139
|
+
n1 = t1 * t1 * (g1x * x1 + g1y * y1);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
let t2 = 0.5 - x2 * x2 - y2 * y2;
|
|
143
|
+
|
|
144
|
+
if (t2 >= 0) {
|
|
145
|
+
const gi2 = ii + 1 + perm[jj + 1];
|
|
146
|
+
|
|
147
|
+
const gi21 = permMod12[gi2];
|
|
148
|
+
|
|
149
|
+
const g2x = grad2[gi21];
|
|
150
|
+
const g2y = grad2[gi21 + 1];
|
|
151
|
+
|
|
152
|
+
t2 *= t2;
|
|
153
|
+
// n2 = t2 * t2 * (grad2[gi2] * x2 + grad2[gi2 + 1] * y2);
|
|
154
|
+
n2 = t2 * t2 * (g2x * x2 + g2y * y2);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Add contributions from each corner to get the final noise value.
|
|
158
|
+
// The result is scaled to return values in the interval [-1,1].
|
|
159
|
+
return 70.0 * (n0 + n1 + n2);
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Builds a random permutation table.
|
|
165
|
+
* This is exported only for (internal) testing purposes.
|
|
166
|
+
* Do not rely on this export.
|
|
167
|
+
* @param {function} random
|
|
168
|
+
* @param {Uint8Array} p
|
|
169
|
+
* @private
|
|
170
|
+
*/
|
|
171
|
+
export function buildPermutationTable(random, p) {
|
|
172
|
+
const table_size = 512;
|
|
173
|
+
|
|
174
|
+
const half_table_size = table_size >>> 1;
|
|
175
|
+
|
|
176
|
+
for (let i = 0; i < half_table_size; i++) {
|
|
177
|
+
p[i] = i;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
for (let i = 0; i < half_table_size - 1; i++) {
|
|
181
|
+
const r = i + ~~(random() * (256 - i));
|
|
182
|
+
const aux = p[i];
|
|
183
|
+
|
|
184
|
+
p[i] = p[r];
|
|
185
|
+
p[r] = aux;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
for (let i = 256; i < table_size; i++) {
|
|
189
|
+
p[i] = p[i - 256];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return p;
|
|
193
|
+
}
|
package/src/engine/Engine.js
CHANGED
|
@@ -100,6 +100,15 @@ class Engine {
|
|
|
100
100
|
*/
|
|
101
101
|
this.ticker = new Ticker();
|
|
102
102
|
|
|
103
|
+
/**
|
|
104
|
+
*
|
|
105
|
+
* @type {AssetManager<Engine>}
|
|
106
|
+
*/
|
|
107
|
+
this.assetManager = new AssetManager({
|
|
108
|
+
context:this,
|
|
109
|
+
executor: this.executor
|
|
110
|
+
});
|
|
111
|
+
|
|
103
112
|
this.__performacne_monitor = new PeriodicConsolePrinter(15, () => {
|
|
104
113
|
const metrics = this.performance;
|
|
105
114
|
const stats = new MetricStatistics();
|
|
@@ -198,11 +207,6 @@ class Engine {
|
|
|
198
207
|
*/
|
|
199
208
|
this.storage = this.platform.getStorage();
|
|
200
209
|
|
|
201
|
-
/**
|
|
202
|
-
*
|
|
203
|
-
* @type {AssetManager}
|
|
204
|
-
*/
|
|
205
|
-
this.assetManager = new AssetManager(this);
|
|
206
210
|
|
|
207
211
|
this.localization = new Localization();
|
|
208
212
|
this.localization.setAssetManager(this.assetManager);
|
|
@@ -2,14 +2,19 @@ import {AssetLoader} from "./loaders/AssetLoader";
|
|
|
2
2
|
import {Asset} from "./Asset";
|
|
3
3
|
import {CrossOriginConfig} from "./CORS/CrossOriginConfig";
|
|
4
4
|
import {AssetTransformer} from "./AssetTransformer";
|
|
5
|
-
import
|
|
5
|
+
import ConcurrentExecutor from "../../core/process/executor/ConcurrentExecutor";
|
|
6
6
|
|
|
7
7
|
interface PromiseOptions {
|
|
8
8
|
skip_queue: boolean
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
interface AssetManagerOptions<CTX> {
|
|
12
|
+
context: CTX,
|
|
13
|
+
executor?: ConcurrentExecutor
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class AssetManager<CTX> {
|
|
17
|
+
constructor(options?: AssetManagerOptions<CTX>)
|
|
13
18
|
|
|
14
19
|
public readonly crossOriginConfig: CrossOriginConfig
|
|
15
20
|
|
|
@@ -25,11 +30,11 @@ export class AssetManager {
|
|
|
25
30
|
|
|
26
31
|
clear(): void
|
|
27
32
|
|
|
28
|
-
registerLoader<T>(type: string, loader: AssetLoader<T>): Promise<AssetLoader<T>>
|
|
33
|
+
registerLoader<T>(type: string, loader: AssetLoader<T, CTX>): Promise<AssetLoader<T,CTX>>
|
|
29
34
|
|
|
30
35
|
unregisterLoader(type: string): Promise<void>
|
|
31
36
|
|
|
32
|
-
getLoaderByType<T>(type: string): AssetLoader<T> | undefined
|
|
37
|
+
getLoaderByType<T>(type: string): AssetLoader<T, CTX> | undefined
|
|
33
38
|
|
|
34
39
|
registerTransformer<T extends Asset<X>, X = any>(type: string, transformer: AssetTransformer<T>): void
|
|
35
40
|
|
|
@@ -19,6 +19,7 @@ import { AssetRequest, AssetRequestFlags } from "./AssetRequest.js";
|
|
|
19
19
|
import FastBinaryHeap from "../../core/collection/heap/FastBinaryHeap.js";
|
|
20
20
|
import { AssetLoadState } from "./AssetLoadState.js";
|
|
21
21
|
import { PendingAsset } from "./PendingAsset.js";
|
|
22
|
+
import ConcurrentExecutor from "../../core/process/executor/ConcurrentExecutor.js";
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
class Response {
|
|
@@ -45,6 +46,7 @@ function get_pending_asset_priority_score(pending_asset) {
|
|
|
45
46
|
|
|
46
47
|
/**
|
|
47
48
|
* Handles loading/generating assets
|
|
49
|
+
* @template CTX
|
|
48
50
|
* @class
|
|
49
51
|
*/
|
|
50
52
|
export class AssetManager {
|
|
@@ -164,19 +166,30 @@ export class AssetManager {
|
|
|
164
166
|
|
|
165
167
|
/**
|
|
166
168
|
*
|
|
167
|
-
* @type {
|
|
169
|
+
* @type {CTX|null}
|
|
168
170
|
* @private
|
|
169
171
|
*/
|
|
170
|
-
#
|
|
172
|
+
#context = null;
|
|
171
173
|
|
|
172
174
|
/**
|
|
173
175
|
*
|
|
174
|
-
* @
|
|
176
|
+
* @type {ConcurrentExecutor|null}
|
|
177
|
+
*/
|
|
178
|
+
#executor = null;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
*
|
|
182
|
+
* @param {CTX} context
|
|
183
|
+
* @param {ConcurrentExecutor} executor
|
|
175
184
|
* @constructor
|
|
176
185
|
*/
|
|
177
|
-
constructor(
|
|
186
|
+
constructor({
|
|
187
|
+
context,
|
|
188
|
+
executor = new ConcurrentExecutor()
|
|
189
|
+
} = {}) {
|
|
178
190
|
|
|
179
|
-
this.#
|
|
191
|
+
this.#context = context;
|
|
192
|
+
this.#executor = executor;
|
|
180
193
|
|
|
181
194
|
}
|
|
182
195
|
|
|
@@ -185,7 +198,7 @@ export class AssetManager {
|
|
|
185
198
|
return;
|
|
186
199
|
}
|
|
187
200
|
|
|
188
|
-
this.#
|
|
201
|
+
this.#executor.run(this.#response_processor);
|
|
189
202
|
|
|
190
203
|
this.#is_running = true;
|
|
191
204
|
}
|
|
@@ -205,7 +218,7 @@ export class AssetManager {
|
|
|
205
218
|
await Promise.allSettled([Task.promise(this.#response_processor)]);
|
|
206
219
|
}
|
|
207
220
|
|
|
208
|
-
this.#
|
|
221
|
+
this.#executor.removeTask(this.#response_processor);
|
|
209
222
|
|
|
210
223
|
this.#is_running = false;
|
|
211
224
|
}
|
|
@@ -260,7 +273,7 @@ export class AssetManager {
|
|
|
260
273
|
throw new Error("Path must be string. Path = " + JSON.stringify(path));
|
|
261
274
|
}
|
|
262
275
|
|
|
263
|
-
if(typeof type !== "string"){
|
|
276
|
+
if (typeof type !== "string") {
|
|
264
277
|
throw new TypeError(`type must be a string, instead was '${typeof type}'`);
|
|
265
278
|
}
|
|
266
279
|
|
|
@@ -696,7 +709,7 @@ export class AssetManager {
|
|
|
696
709
|
|
|
697
710
|
} else {
|
|
698
711
|
|
|
699
|
-
await loader.link(this, this.#
|
|
712
|
+
await loader.link(this, this.#context);
|
|
700
713
|
|
|
701
714
|
}
|
|
702
715
|
|
|
@@ -38,16 +38,16 @@ export class PendingAsset {
|
|
|
38
38
|
* @return {number}
|
|
39
39
|
*/
|
|
40
40
|
get priority() {
|
|
41
|
-
let max_priority = 0;
|
|
42
|
-
|
|
43
41
|
const requests = this.requests;
|
|
44
|
-
const
|
|
42
|
+
const request_count = requests.length;
|
|
45
43
|
|
|
46
|
-
if (
|
|
47
|
-
|
|
44
|
+
if (request_count === 0) {
|
|
45
|
+
return 0;
|
|
48
46
|
}
|
|
49
47
|
|
|
50
|
-
|
|
48
|
+
let max_priority = requests[0].priority;
|
|
49
|
+
|
|
50
|
+
for (let i = 1; i < request_count; i++) {
|
|
51
51
|
const request = requests[i];
|
|
52
52
|
const priority = request.priority;
|
|
53
53
|
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import {Asset} from "../Asset";
|
|
2
2
|
|
|
3
|
-
export class AssetLoader<T> {
|
|
4
|
-
public load(
|
|
3
|
+
export class AssetLoader<T,CTX> {
|
|
4
|
+
public load(
|
|
5
|
+
path: string,
|
|
6
|
+
success: (asset: Asset<T>) => void,
|
|
7
|
+
failure: (reason: any) => void,
|
|
8
|
+
progress: (current: number, total: number) => void
|
|
9
|
+
)
|
|
5
10
|
}
|
|
@@ -1,26 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @template CTX
|
|
3
|
+
* @template Asset
|
|
4
|
+
*/
|
|
1
5
|
export class AssetLoader {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
this.assetManager = null;
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @type {AssetManager}
|
|
9
|
+
*/
|
|
10
|
+
assetManager = null;
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @type {Engine}
|
|
15
|
+
*/
|
|
16
|
+
context = null;
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
*
|
|
18
20
|
* @param {AssetManager} assetManager
|
|
19
|
-
* @param {
|
|
21
|
+
* @param {CTX} context
|
|
20
22
|
*/
|
|
21
|
-
async link(assetManager,
|
|
23
|
+
async link(assetManager, context) {
|
|
22
24
|
this.assetManager = assetManager;
|
|
23
|
-
this.
|
|
25
|
+
this.context = context;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
/**
|
|
@@ -13,7 +13,7 @@ export class SoundAssetLoader extends AssetLoader {
|
|
|
13
13
|
*
|
|
14
14
|
* @type {AudioContext}
|
|
15
15
|
*/
|
|
16
|
-
this.
|
|
16
|
+
this.audioContext = context;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
load(path, success, failure, progress) {
|
|
@@ -24,16 +24,14 @@ export class SoundAssetLoader extends AssetLoader {
|
|
|
24
24
|
|
|
25
25
|
request.responseType = "arraybuffer";
|
|
26
26
|
|
|
27
|
-
const context = this.
|
|
27
|
+
const context = this.audioContext;
|
|
28
28
|
|
|
29
29
|
request.onload = function (e) {
|
|
30
30
|
//decode works asynchronously, this is important to prevent lag in main thread
|
|
31
31
|
context.decodeAudioData(request.response, function (buffer) {
|
|
32
32
|
const byteSize = e.total;
|
|
33
33
|
|
|
34
|
-
const asset = new Asset(
|
|
35
|
-
return buffer;
|
|
36
|
-
}, byteSize);
|
|
34
|
+
const asset = new Asset(() => buffer, byteSize);
|
|
37
35
|
|
|
38
36
|
success(asset);
|
|
39
37
|
}, failure);
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export class MetricStatistics {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
mean = 0;
|
|
3
|
+
median = 0;
|
|
4
|
+
max = 0;
|
|
5
|
+
min = 0;
|
|
6
|
+
|
|
7
|
+
toString() {
|
|
8
|
+
return `{min:${this.min}, max:${this.max}, mean:${this.mean}, median:${this.median}`;
|
|
7
9
|
}
|
|
8
10
|
}
|
|
@@ -49,7 +49,7 @@ export class RingBufferMetric extends AbstractMetric {
|
|
|
49
49
|
|
|
50
50
|
// no data
|
|
51
51
|
result.mean = 0;
|
|
52
|
-
result.
|
|
52
|
+
result.median = 0;
|
|
53
53
|
result.min = 0;
|
|
54
54
|
result.max = 0;
|
|
55
55
|
|
|
@@ -58,7 +58,7 @@ export class RingBufferMetric extends AbstractMetric {
|
|
|
58
58
|
} else {
|
|
59
59
|
|
|
60
60
|
result.mean = computeStatisticalMean(array, 0, data_count);
|
|
61
|
-
result.
|
|
61
|
+
result.median = computeStatisticalPartialMedian(array, 0, data_count);
|
|
62
62
|
result.max = computeArrayMax(array, 0, data_count);
|
|
63
63
|
result.min = computeArrayMin(array, 0, data_count);
|
|
64
64
|
|