@woosh/meep-engine 2.51.0 → 2.52.0
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/NumberFormat.js +0 -71
- package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +1 -0
- package/src/core/bvh2/bvh3/query/BVHQueryAny.js +16 -0
- package/src/core/bvh2/bvh3/query/bvh_collect_user_data.js +5 -5
- package/src/core/bvh2/bvh3/query/bvh_query_leaves_generic.js +2 -3
- package/src/core/bvh2/bvh3/query/bvh_query_leaves_generic.spec.js +22 -0
- package/src/core/bvh2/bvh3/query/bvh_query_leaves_ray.js +2 -2
- package/src/core/bvh2/bvh3/query/bvh_query_leaves_ray.spec.js +64 -0
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.js +2 -3
- package/src/core/geom/3d/aabb/aabb3_from_threejs_geometry.js +41 -0
- package/src/core/geom/3d/topology/struct/TopoMesh.js +3 -2
- package/src/core/geom/3d/topology/struct/prototypeBinaryTopology.js +4 -4
- package/src/core/geom/Vector2.d.ts +9 -0
- package/src/core/geom/Vector2.js +8 -22
- package/src/core/geom/Vector2.spec.js +153 -0
- package/src/core/model/ModuleRegistry.js +2 -4
- package/src/core/model/ModuleRegistry.spec.js +31 -0
- package/src/core/model/reactive/js/compileReactiveToJS.spec.js +14 -0
- package/src/core/model/reactive/model/logic/ReactiveAnd.spec.js +31 -1
- package/src/core/model/reactive/model/logic/ReactiveOr.spec.js +53 -0
- package/src/core/model/stat/LinearModifier.js +2 -2
- package/src/core/model/stat/LinearModifier.spec.js +62 -0
- package/src/core/model/stat/Stat.js +12 -0
- package/src/core/model/stat/Stat.spec.js +36 -0
- package/src/core/primitives/array/computeStridedIntegerArrayHash.spec.js +28 -0
- package/src/core/primitives/numbers/number_format_by_thousands.js +14 -0
- package/src/core/primitives/numbers/number_pretty_print.js +49 -0
- package/src/core/primitives/strings/computeStringHash.spec.js +12 -5
- package/src/core/process/BaseProcess.js +8 -8
- package/src/engine/Clock.js +30 -29
- package/src/engine/Clock.spec.js +26 -0
- package/src/engine/ecs/EntityBuilder.js +3 -1
- package/src/engine/ecs/EntityBuilder.spec.js +21 -0
- package/src/engine/ecs/gui/GUIElement.js +1 -1
- package/src/engine/ecs/gui/position/ViewportPosition.js +3 -3
- package/src/engine/ecs/terrain/ecs/TerrainClassifier.js +1 -1
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.js +1 -1
- package/src/engine/ecs/transform/Transform.js +1 -0
- package/src/engine/graphics/camera/testClippingPlaneComputation.js +0 -4
- package/src/engine/graphics/ecs/animation/animator/graph/AnimationGraph.spec.js +5 -0
- package/src/engine/graphics/ecs/animation/animator/graph/definition/AnimationGraphDefinition.js +24 -25
- package/src/engine/graphics/ecs/animation/animator/graph/definition/AnimationGraphDefinition.spec.js +5 -0
- package/src/engine/graphics/ecs/decal/DecalSystem.js +2 -20
- package/src/engine/graphics/ecs/decal/v2/Decal.js +32 -32
- package/src/engine/graphics/ecs/decal/v2/Decal.spec.js +5 -0
- package/src/engine/graphics/ecs/decal/v2/FPDecalSystem.js +4 -2
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +4 -33
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +8 -4
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMesh.spec.js +5 -0
- package/src/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +0 -12
- package/src/engine/graphics/ecs/path/testPathDisplaySystem.js +0 -2
- package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +0 -4
- package/src/engine/graphics/ecs/water2/shader/testWaterShader.js +0 -2
- package/src/engine/graphics/geometry/buffered/computeBufferAttributeHash.js +1 -1
- package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +0 -2
- package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +0 -4
- package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +0 -4
- package/src/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +2 -2
- package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +2 -6
- package/src/engine/graphics/sh3/path_tracer/GeometryBVHBatched.js +2 -1
- package/src/engine/graphics/sh3/path_tracer/PathTracer.js +6 -1
- package/src/engine/graphics/sh3/path_tracer/prototypePathTracer.js +2 -2
- package/src/engine/graphics/shadows/testShadowMapRendering.js +0 -2
- package/src/engine/graphics/texture/sampler/Sampler2D.js +1 -1
- package/src/engine/graphics/three/expand_aabb_by_transformed_three_object.js +3 -23
- package/src/engine/grid/components/GridObstacle.js +45 -25
- package/src/engine/grid/components/GridObstacle.spec.js +130 -1
- package/src/engine/grid/components/GridPosition.js +5 -17
- package/src/engine/grid/components/GridPosition2Transform.js +1 -70
- package/src/engine/grid/components/GridPosition2TransformSerializationAdapter.js +70 -0
- package/src/engine/plugin/EnginePlugin.js +12 -14
- package/src/engine/plugin/EnginePlugin.spec.js +5 -0
- package/src/engine/plugin/EnginePluginManager.js +18 -22
- package/src/engine/scene/transitionToScene.js +12 -1
- package/src/engine/simulation/Ticker.js +1 -1
- package/src/generation/theme/TerrainLayerDescription.js +1 -1
- package/src/view/common/LabelView.js +3 -3
- package/src/engine/ecs/components/AimController.js +0 -18
- package/src/engine/ecs/components/Attacker.js +0 -13
- package/src/engine/ecs/components/MeshCollider.js +0 -15
- package/src/engine/ecs/components/RangedAttack.js +0 -12
- package/src/engine/ecs/components/TargetAI.js +0 -11
- package/src/engine/ecs/components/ViewportMeshProjection.js +0 -18
- package/src/engine/ecs/systems/AimControllerSystem.js +0 -63
- package/src/engine/ecs/systems/AttackerSystem.js +0 -67
- package/src/engine/ecs/systems/MeshColliderSystem.js +0 -47
- package/src/engine/ecs/systems/MonsterAISystem.js +0 -163
- package/src/engine/ecs/systems/MortalitySystem.js +0 -46
- package/src/engine/ecs/systems/RangedAttackSystem.js +0 -132
- package/src/engine/ecs/systems/SerializationMetadataSystem.js +0 -10
- package/src/engine/ecs/systems/TargetAISystem.js +0 -107
- package/src/engine/ecs/systems/ViewportMeshProjectionSystem.js +0 -68
- package/src/engine/graphics/particles/ParticleEmitterLibrary.js +0 -87
- package/src/engine/grid/components/ViewportGridProjection.js +0 -20
- package/src/engine/grid/systems/GridObstacleSystem.js +0 -58
- package/src/engine/grid/systems/ViewportGridProjectionSystem.js +0 -105
- /package/src/{engine → core/primitives/array}/computeStridedIntegerArrayHash.js +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { compileReactiveToJS } from "./compileReactiveToJS.js";
|
|
2
|
+
import { ReactiveLiteralBoolean } from "../model/terminal/ReactiveLiteralBoolean.js";
|
|
3
|
+
import { ReactiveLiteralNumber } from "../model/terminal/ReactiveLiteralNumber.js";
|
|
4
|
+
import { ReactiveLiteralString } from "../model/terminal/ReactiveLiteralString.js";
|
|
5
|
+
|
|
6
|
+
test("literal expressions", () => {
|
|
7
|
+
|
|
8
|
+
expect(compileReactiveToJS(ReactiveLiteralBoolean.from(true))).toEqual("true");
|
|
9
|
+
|
|
10
|
+
expect(compileReactiveToJS(ReactiveLiteralNumber.from(13.1))).toEqual("13.1");
|
|
11
|
+
|
|
12
|
+
expect(compileReactiveToJS(ReactiveLiteralString.from("a"))).toEqual("'a'");
|
|
13
|
+
|
|
14
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReactiveLiteralBoolean } from "../terminal/ReactiveLiteralBoolean.js";
|
|
2
2
|
import { ReactiveAnd } from "./ReactiveAnd.js";
|
|
3
3
|
|
|
4
|
-
test('
|
|
4
|
+
test('copy method does not modify the sources', () => {
|
|
5
5
|
|
|
6
6
|
const b0 = ReactiveLiteralBoolean.from(false);
|
|
7
7
|
const b1 = ReactiveLiteralBoolean.from(true);
|
|
@@ -19,3 +19,33 @@ test('.copy method must not change the original', () => {
|
|
|
19
19
|
expect(b1.getValue()).toBe(true);
|
|
20
20
|
|
|
21
21
|
});
|
|
22
|
+
|
|
23
|
+
test("equals", () => {
|
|
24
|
+
|
|
25
|
+
const a = ReactiveAnd.from(ReactiveLiteralBoolean.from(true), ReactiveLiteralBoolean.from(true));
|
|
26
|
+
const b = ReactiveAnd.from(ReactiveLiteralBoolean.from(true), ReactiveLiteralBoolean.from(true));
|
|
27
|
+
const c = ReactiveAnd.from(ReactiveLiteralBoolean.from(true), ReactiveLiteralBoolean.from(false));
|
|
28
|
+
const d = ReactiveAnd.from(ReactiveLiteralBoolean.from(false), ReactiveLiteralBoolean.from(true));
|
|
29
|
+
|
|
30
|
+
expect(a.equals(b)).toBe(true);
|
|
31
|
+
expect(a.equals(c)).toBe(false);
|
|
32
|
+
expect(a.equals(d)).toBe(false);
|
|
33
|
+
|
|
34
|
+
expect(a.equals(ReactiveLiteralBoolean.from(true))).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("evaluate", () => {
|
|
38
|
+
const a = ReactiveAnd.from(ReactiveLiteralBoolean.from(true), ReactiveLiteralBoolean.from(true));
|
|
39
|
+
const b = ReactiveAnd.from(ReactiveLiteralBoolean.from(true), ReactiveLiteralBoolean.from(false));
|
|
40
|
+
|
|
41
|
+
expect(a.evaluate({})).toBe(true);
|
|
42
|
+
expect(b.evaluate({})).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("clone", () => {
|
|
46
|
+
const source = ReactiveAnd.from(ReactiveLiteralBoolean.from(true), ReactiveLiteralBoolean.from(false));
|
|
47
|
+
|
|
48
|
+
const clone = source.clone();
|
|
49
|
+
|
|
50
|
+
expect(clone.equals(source)).toBe(true);
|
|
51
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ReactiveLiteralBoolean } from "../terminal/ReactiveLiteralBoolean.js";
|
|
2
|
+
import { ReactiveOr } from "./ReactiveOr.js";
|
|
3
|
+
|
|
4
|
+
test('copy method does not modify the sources', () => {
|
|
5
|
+
|
|
6
|
+
const b0 = ReactiveLiteralBoolean.from(false);
|
|
7
|
+
const b1 = ReactiveLiteralBoolean.from(true);
|
|
8
|
+
|
|
9
|
+
const a = new ReactiveOr();
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
a.connect(b0, b1);
|
|
13
|
+
|
|
14
|
+
const b = new ReactiveOr();
|
|
15
|
+
|
|
16
|
+
b.copy(a);
|
|
17
|
+
|
|
18
|
+
expect(b0.getValue()).toBe(false);
|
|
19
|
+
expect(b1.getValue()).toBe(true);
|
|
20
|
+
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("equals", () => {
|
|
24
|
+
|
|
25
|
+
const a = ReactiveOr.from(ReactiveLiteralBoolean.from(true), ReactiveLiteralBoolean.from(true));
|
|
26
|
+
const b = ReactiveOr.from(ReactiveLiteralBoolean.from(true), ReactiveLiteralBoolean.from(true));
|
|
27
|
+
const c = ReactiveOr.from(ReactiveLiteralBoolean.from(true), ReactiveLiteralBoolean.from(false));
|
|
28
|
+
const d = ReactiveOr.from(ReactiveLiteralBoolean.from(false), ReactiveLiteralBoolean.from(true));
|
|
29
|
+
|
|
30
|
+
expect(a.equals(b)).toBe(true);
|
|
31
|
+
expect(a.equals(c)).toBe(false);
|
|
32
|
+
expect(a.equals(d)).toBe(false);
|
|
33
|
+
|
|
34
|
+
expect(a.equals(ReactiveLiteralBoolean.from(true))).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("evaluate", () => {
|
|
38
|
+
const a = ReactiveOr.from(ReactiveLiteralBoolean.from(true), ReactiveLiteralBoolean.from(true));
|
|
39
|
+
const b = ReactiveOr.from(ReactiveLiteralBoolean.from(true), ReactiveLiteralBoolean.from(false));
|
|
40
|
+
const c = ReactiveOr.from(ReactiveLiteralBoolean.from(false), ReactiveLiteralBoolean.from(false));
|
|
41
|
+
|
|
42
|
+
expect(a.evaluate({})).toBe(true);
|
|
43
|
+
expect(b.evaluate({})).toBe(true);
|
|
44
|
+
expect(c.evaluate({})).toBe(false);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("clone", () => {
|
|
48
|
+
const source = ReactiveOr.from(ReactiveLiteralBoolean.from(true), ReactiveLiteralBoolean.from(false));
|
|
49
|
+
|
|
50
|
+
const clone = source.clone();
|
|
51
|
+
|
|
52
|
+
expect(clone.equals(source)).toBe(true);
|
|
53
|
+
});
|
|
@@ -33,3 +33,65 @@ test("equals method", () => {
|
|
|
33
33
|
expect(a.equals(c)).toBe(false);
|
|
34
34
|
expect(a.equals(d)).toBe(false);
|
|
35
35
|
});
|
|
36
|
+
|
|
37
|
+
test("hash", () => {
|
|
38
|
+
const mod = new LinearModifier(3, -7);
|
|
39
|
+
|
|
40
|
+
const hash = mod.hash();
|
|
41
|
+
|
|
42
|
+
expect(mod.hash()).toEqual(hash); // idempotency
|
|
43
|
+
expect(typeof hash).toEqual("number");
|
|
44
|
+
expect(Number.isInteger(hash)).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("copy", () => {
|
|
48
|
+
|
|
49
|
+
const source = new LinearModifier(3, -7);
|
|
50
|
+
const target = new LinearModifier(1, 1);
|
|
51
|
+
|
|
52
|
+
target.copy(source);
|
|
53
|
+
|
|
54
|
+
expect(target.a).toBe(3);
|
|
55
|
+
expect(target.b).toBe(-7);
|
|
56
|
+
|
|
57
|
+
// check that original was not changed
|
|
58
|
+
|
|
59
|
+
expect(source.a).toBe(3);
|
|
60
|
+
expect(source.b).toBe(-7);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("clone", () => {
|
|
64
|
+
|
|
65
|
+
const source = new LinearModifier(3, -7);
|
|
66
|
+
|
|
67
|
+
const clone = source.clone();
|
|
68
|
+
|
|
69
|
+
expect(clone.equals(source)).toBe(true);
|
|
70
|
+
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("to/from JSON consistency", () => {
|
|
74
|
+
|
|
75
|
+
const source = new LinearModifier(3, -7);
|
|
76
|
+
const target = new LinearModifier(1, 1);
|
|
77
|
+
|
|
78
|
+
target.fromJSON(source.toJSON());
|
|
79
|
+
|
|
80
|
+
expect(target.a).toBe(3);
|
|
81
|
+
expect(target.b).toBe(-7);
|
|
82
|
+
|
|
83
|
+
// check that original was not changed
|
|
84
|
+
|
|
85
|
+
expect(source.a).toBe(3);
|
|
86
|
+
expect(source.b).toBe(-7);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("toString produces a valid string", () => {
|
|
90
|
+
|
|
91
|
+
const s = new LinearModifier(3, -7).toString();
|
|
92
|
+
|
|
93
|
+
expect(typeof s).toBe("string");
|
|
94
|
+
expect(s.trim().length).toBeGreaterThan(0);
|
|
95
|
+
|
|
96
|
+
});
|
|
97
|
+
|
|
@@ -140,6 +140,15 @@ class Stat extends Number {
|
|
|
140
140
|
this.updateValue();
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
/**
|
|
144
|
+
*
|
|
145
|
+
* @param {LinearModifier} mod
|
|
146
|
+
* @return {boolean}
|
|
147
|
+
*/
|
|
148
|
+
hasModifier(mod) {
|
|
149
|
+
return this.__modifiers.contains(mod);
|
|
150
|
+
}
|
|
151
|
+
|
|
143
152
|
/**
|
|
144
153
|
*
|
|
145
154
|
* @param {LinearModifier} mod
|
|
@@ -174,6 +183,8 @@ class Stat extends Number {
|
|
|
174
183
|
copy(other) {
|
|
175
184
|
this.base.copy(other.base);
|
|
176
185
|
this.__modifiers.copy(other.__modifiers);
|
|
186
|
+
|
|
187
|
+
this.updateValue();
|
|
177
188
|
}
|
|
178
189
|
|
|
179
190
|
/**
|
|
@@ -226,6 +237,7 @@ class Stat extends Number {
|
|
|
226
237
|
fromJSON(json) {
|
|
227
238
|
this.base.fromJSON(json.base);
|
|
228
239
|
this.__modifiers.fromJSON(json.modifiers, LinearModifier);
|
|
240
|
+
this.updateValue();
|
|
229
241
|
}
|
|
230
242
|
|
|
231
243
|
/**
|
|
@@ -73,3 +73,39 @@ test("order of modifiers doesn't matter", () => {
|
|
|
73
73
|
expect(s.getValue()).toEqual(-45);
|
|
74
74
|
}
|
|
75
75
|
});
|
|
76
|
+
|
|
77
|
+
test("toString produces a valid string", () => {
|
|
78
|
+
const stat = new Stat(1);
|
|
79
|
+
|
|
80
|
+
const s = stat.toString();
|
|
81
|
+
|
|
82
|
+
expect(typeof s).toBe("string");
|
|
83
|
+
expect(s.trim().length).toBeGreaterThan(0);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("copy", () => {
|
|
87
|
+
const source = new Stat(7);
|
|
88
|
+
|
|
89
|
+
source.addModifier(LinearModifier.CONSTANT_ONE);
|
|
90
|
+
|
|
91
|
+
const other = new Stat(1);
|
|
92
|
+
|
|
93
|
+
other.copy(source);
|
|
94
|
+
|
|
95
|
+
expect(other.getBaseValue()).toBe(7);
|
|
96
|
+
expect(other.hasModifier(LinearModifier.CONSTANT_ONE));
|
|
97
|
+
|
|
98
|
+
expect(other.equals(source)).toBe(true);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test("to/from JSON consistency", () => {
|
|
102
|
+
|
|
103
|
+
const source = new Stat(7);
|
|
104
|
+
source.addModifier(LinearModifier.CONSTANT_ONE);
|
|
105
|
+
|
|
106
|
+
const destination = new Stat(1);
|
|
107
|
+
|
|
108
|
+
destination.fromJSON(source.toJSON());
|
|
109
|
+
|
|
110
|
+
expect(destination.equals(source)).toBe(true);
|
|
111
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { computeStridedIntegerArrayHash } from "./computeStridedIntegerArrayHash.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {number[]} value
|
|
6
|
+
* @param {number} [stride]
|
|
7
|
+
*/
|
|
8
|
+
function check(value, stride = 1) {
|
|
9
|
+
const hash = computeStridedIntegerArrayHash(value, 0, value.length, 1);
|
|
10
|
+
|
|
11
|
+
expect(typeof hash).toBe('number');
|
|
12
|
+
expect(Number.isInteger(hash)).toBe(true);
|
|
13
|
+
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
test("sanity", () => {
|
|
17
|
+
|
|
18
|
+
check([], 1);
|
|
19
|
+
|
|
20
|
+
check([1], 1);
|
|
21
|
+
check([1], 3);
|
|
22
|
+
|
|
23
|
+
check([1, 3], 1);
|
|
24
|
+
check([1, 3], 3);
|
|
25
|
+
|
|
26
|
+
check([1, 3, 7], 3);
|
|
27
|
+
|
|
28
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { assert } from "../../assert.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {number} x
|
|
6
|
+
* @param {string} [separator=',']
|
|
7
|
+
* @returns {string}
|
|
8
|
+
*/
|
|
9
|
+
export function number_format_by_thousands(x, separator = ',') {
|
|
10
|
+
assert.isNumber(x, 'x');
|
|
11
|
+
assert.isString(separator, 'separator');
|
|
12
|
+
|
|
13
|
+
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, separator);
|
|
14
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { assert } from "../../assert.js";
|
|
2
|
+
import { number_format_by_thousands } from "./number_format_by_thousands.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {string} value
|
|
7
|
+
* @returns {number}
|
|
8
|
+
*/
|
|
9
|
+
function countDecimals(value) {
|
|
10
|
+
if (value % 1 === 0) {
|
|
11
|
+
//whole number
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
const s = value.toString();
|
|
15
|
+
const index = s.indexOf('.');
|
|
16
|
+
|
|
17
|
+
if (index === -1) {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//find last 0
|
|
22
|
+
let endIndex = s.length - 1;
|
|
23
|
+
for (; endIndex > index && s.charAt(endIndex) === "0"; endIndex--) {
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
return endIndex - index;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @param {number} value
|
|
32
|
+
* @returns {string|number}
|
|
33
|
+
*/
|
|
34
|
+
export function number_pretty_print(value) {
|
|
35
|
+
assert.isNumber(value, 'value');
|
|
36
|
+
|
|
37
|
+
const MAX_DECIMALS = 2;
|
|
38
|
+
|
|
39
|
+
const fraction = value % 1;
|
|
40
|
+
if (fraction !== 0 && Math.abs(value) < 100) {
|
|
41
|
+
const decimals = countDecimals(value.toFixed(MAX_DECIMALS));
|
|
42
|
+
const decimalsToPrint = Math.min(decimals, MAX_DECIMALS);
|
|
43
|
+
return value.toFixed(decimalsToPrint);
|
|
44
|
+
} else {
|
|
45
|
+
//no fraction
|
|
46
|
+
return number_format_by_thousands(value - fraction, ",");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
}
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import { computeStringHash } from "./computeStringHash.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
function check(value) {
|
|
4
4
|
// must produce a number
|
|
5
|
-
|
|
5
|
+
const hash = computeStringHash(value);
|
|
6
|
+
expect(typeof hash).toBe('number');
|
|
7
|
+
expect(Number.isInteger(hash)).toBe(true);
|
|
8
|
+
expect(computeStringHash(value)).toEqual(hash); // stability
|
|
9
|
+
}
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
expect(computeStringHash('')).toBe(computeStringHash(''));
|
|
11
|
+
test('hash', () => {
|
|
9
12
|
|
|
10
|
-
|
|
13
|
+
check('');
|
|
14
|
+
check('cat');
|
|
15
|
+
check('tomato');
|
|
16
|
+
check(null);
|
|
17
|
+
check(undefined);
|
|
11
18
|
|
|
12
19
|
expect(computeStringHash('tomato')).not.toBe(computeStringHash('potato'));
|
|
13
20
|
});
|
|
@@ -4,14 +4,14 @@ import ObservedEnum from "../model/ObservedEnum.js";
|
|
|
4
4
|
import { ProcessState } from "./ProcessState.js";
|
|
5
5
|
|
|
6
6
|
export class BaseProcess {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
|
|
8
|
+
id = "";
|
|
9
|
+
/**
|
|
10
|
+
* @readonly
|
|
11
|
+
* @type {ObservedEnum.<ProcessState>}
|
|
12
|
+
*/
|
|
13
|
+
__state = new ObservedEnum(ProcessState.New, ProcessState);
|
|
14
|
+
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* @returns {ObservedEnum<ProcessState>}
|
package/src/engine/Clock.js
CHANGED
|
@@ -5,16 +5,15 @@
|
|
|
5
5
|
|
|
6
6
|
import Stat from "../core/model/stat/Stat.js";
|
|
7
7
|
|
|
8
|
+
//Use highest available resolution time source
|
|
9
|
+
const source = typeof performance === "undefined" ? Date : performance;
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
*
|
|
11
13
|
* @returns {number}
|
|
12
14
|
*/
|
|
13
15
|
export function currentTimeInSeconds() {
|
|
14
|
-
|
|
15
|
-
const source = typeof performance === "undefined" ? Date : performance;
|
|
16
|
-
|
|
17
|
-
return source.now() / 1000;
|
|
16
|
+
return source.now() * 0.001;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
/**
|
|
@@ -29,35 +28,37 @@ function updateElapsedTime(clock) {
|
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
class Clock {
|
|
32
|
-
constructor() {
|
|
33
|
-
/**
|
|
34
|
-
*
|
|
35
|
-
* @type {number}
|
|
36
|
-
* @private
|
|
37
|
-
*/
|
|
38
|
-
this.__lastMeasurement = 0;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
*
|
|
42
|
-
* @type {number}
|
|
43
|
-
*/
|
|
44
|
-
this.elapsedTime = 0;
|
|
45
31
|
|
|
46
|
-
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @type {number}
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
__lastMeasurement = 0;
|
|
47
38
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
* @type {number}
|
|
42
|
+
*/
|
|
43
|
+
elapsedTime = 0;
|
|
44
|
+
|
|
45
|
+
timeAtDelta = 0;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
*
|
|
49
|
+
* @type {boolean}
|
|
50
|
+
* @private
|
|
51
|
+
*/
|
|
52
|
+
__isRunning = false;
|
|
54
53
|
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
/**
|
|
56
|
+
* how fast clock ticks in relation to real time
|
|
57
|
+
* @type {Stat}
|
|
58
|
+
*/
|
|
59
|
+
speed = new Stat(1);
|
|
60
|
+
|
|
61
|
+
constructor() {
|
|
61
62
|
this.speed.postprocess = Stat.Process.clampMin(0);
|
|
62
63
|
}
|
|
63
64
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Clock from "./Clock.js";
|
|
2
|
+
import { delay } from "../core/process/delay.js";
|
|
3
|
+
|
|
4
|
+
test("constructor does not throw", () => {
|
|
5
|
+
new Clock();
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
test("reset", () => {
|
|
9
|
+
const clock = new Clock();
|
|
10
|
+
clock.reset();
|
|
11
|
+
|
|
12
|
+
expect(clock.getElapsedTime()).toBe(0);
|
|
13
|
+
expect(clock.getDelta()).toBe(0);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test("getDelta", async () => {
|
|
17
|
+
const clock = new Clock();
|
|
18
|
+
|
|
19
|
+
clock.start();
|
|
20
|
+
|
|
21
|
+
await delay(30);
|
|
22
|
+
|
|
23
|
+
const delta = clock.getDelta();
|
|
24
|
+
|
|
25
|
+
expect(delta).toBeCloseTo(0.03, 0.01);
|
|
26
|
+
});
|
|
@@ -229,7 +229,7 @@ class EntityBuilder {
|
|
|
229
229
|
/**
|
|
230
230
|
*
|
|
231
231
|
* @param {string} eventName
|
|
232
|
-
* @param {*} event
|
|
232
|
+
* @param {*} [event]
|
|
233
233
|
*/
|
|
234
234
|
sendEvent(eventName, event) {
|
|
235
235
|
if (this.getFlag(EntityBuilderFlags.Built)) {
|
|
@@ -368,6 +368,8 @@ class EntityBuilder {
|
|
|
368
368
|
const subscription = listeners[i];
|
|
369
369
|
dataset.addEntityEventListener(entity, subscription.name, subscription.listener, subscription.context);
|
|
370
370
|
}
|
|
371
|
+
// reset listeners
|
|
372
|
+
this.deferredListeners.splice(0, listeners_count);
|
|
371
373
|
|
|
372
374
|
const element = this.element;
|
|
373
375
|
const element_count = element.length;
|
|
@@ -55,13 +55,18 @@ test("'Built' flag is reset when entity is removed without invoking 'destroy' me
|
|
|
55
55
|
|
|
56
56
|
const b = new EntityBuilder();
|
|
57
57
|
|
|
58
|
+
expect(b.getFlag(EntityBuilderFlags.Built)).toBe(false);
|
|
59
|
+
expect(b.isBuilt).toBe(false);
|
|
60
|
+
|
|
58
61
|
b.build(dataset);
|
|
59
62
|
|
|
60
63
|
expect(b.getFlag(EntityBuilderFlags.Built)).toBe(true);
|
|
64
|
+
expect(b.isBuilt).toBe(true);
|
|
61
65
|
|
|
62
66
|
dataset.removeEntity(b.entity);
|
|
63
67
|
|
|
64
68
|
expect(b.getFlag(EntityBuilderFlags.Built)).toBe(false);
|
|
69
|
+
expect(b.isBuilt).toBe(false);
|
|
65
70
|
});
|
|
66
71
|
|
|
67
72
|
test("removeAllComponents from empty", () => {
|
|
@@ -131,4 +136,20 @@ test("adding component to live entity results in component being added to the da
|
|
|
131
136
|
entity.add(component);
|
|
132
137
|
|
|
133
138
|
expect(ecd.getComponent(entity.entity, DummyComponent)).toBe(component);
|
|
139
|
+
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test("promiseEvent", async () => {
|
|
143
|
+
|
|
144
|
+
const entity = new EntityBuilder();
|
|
145
|
+
|
|
146
|
+
const ecd = sampleDataset();
|
|
147
|
+
|
|
148
|
+
entity.build(ecd)
|
|
149
|
+
|
|
150
|
+
const promise = entity.promiseEvent("x");
|
|
151
|
+
|
|
152
|
+
entity.sendEvent("x");
|
|
153
|
+
|
|
154
|
+
await promise;
|
|
134
155
|
});
|
|
@@ -97,9 +97,9 @@ class ViewportPosition {
|
|
|
97
97
|
|
|
98
98
|
hash() {
|
|
99
99
|
return computeHashIntegerArray(
|
|
100
|
-
this.position.
|
|
101
|
-
this.offset.
|
|
102
|
-
this.anchor.
|
|
100
|
+
this.position.hash(),
|
|
101
|
+
this.offset.hash(),
|
|
102
|
+
this.anchor.hash(),
|
|
103
103
|
this.resolveGuiCollisions ? 1 : 0,
|
|
104
104
|
computeHashFloat(this.screenEdgeWidth),
|
|
105
105
|
this.stickToScreenEdge ? 1 : 0,
|
|
@@ -26,7 +26,6 @@ import ViewportPositionSystem from "../../ecs/gui/position/ViewportPositionSyste
|
|
|
26
26
|
import { GridPosition2TransformSystem } from "../../grid/systems/GridPosition2TransformSystem.js";
|
|
27
27
|
import { Transform2GridPositionSystem } from "../../grid/transform2grid/Transform2GridPositionSystem.js";
|
|
28
28
|
import SynchronizePositionSystem from "../../ecs/systems/SynchronizePositionSystem.js";
|
|
29
|
-
import GridObstacleSystem from "../../grid/systems/GridObstacleSystem.js";
|
|
30
29
|
import GridPositionSystem from "../../grid/systems/GridPositionSystem.js";
|
|
31
30
|
import InputControllerSystem from "../../input/ecs/systems/InputControllerSystem.js";
|
|
32
31
|
import { InputSystem } from "../../input/ecs/systems/InputSystem.js";
|
|
@@ -37,7 +36,6 @@ import { AnimationGraphSystem } from "../ecs/animation/animator/AnimationGraphSy
|
|
|
37
36
|
import { FogOfWarSystem } from "../../ecs/fow/FogOfWarSystem.js";
|
|
38
37
|
import { FogOfWarRevealerSystem } from "../../ecs/fow/FogOfWarRevealerSystem.js";
|
|
39
38
|
import { BehaviorSystem } from "../../intelligence/behavior/ecs/BehaviorSystem.js";
|
|
40
|
-
import { SerializationMetadataSystem } from "../../ecs/systems/SerializationMetadataSystem.js";
|
|
41
39
|
import { InverseKinematicsSystem } from "../../ecs/ik/InverseKinematicsSystem.js";
|
|
42
40
|
import { PathDisplaySystem } from "../ecs/path/PathDisplaySystem.js";
|
|
43
41
|
import RenderSystem from "../../ecs/systems/RenderSystem.js";
|
|
@@ -105,7 +103,6 @@ function makeConfig(engine) {
|
|
|
105
103
|
new GridPosition2TransformSystem(),
|
|
106
104
|
new Transform2GridPositionSystem(),
|
|
107
105
|
new SynchronizePositionSystem(),
|
|
108
|
-
new GridObstacleSystem(),
|
|
109
106
|
new GridPositionSystem(),
|
|
110
107
|
new InputControllerSystem(devices),
|
|
111
108
|
new InputSystem(devices),
|
|
@@ -119,7 +116,6 @@ function makeConfig(engine) {
|
|
|
119
116
|
new FogOfWarSystem(graphics),
|
|
120
117
|
new FogOfWarRevealerSystem(0),
|
|
121
118
|
new BehaviorSystem(engine),
|
|
122
|
-
new SerializationMetadataSystem(),
|
|
123
119
|
new InverseKinematicsSystem(),
|
|
124
120
|
new PathDisplaySystem(engine),
|
|
125
121
|
);
|