@woosh/meep-engine 2.49.2 → 2.49.4

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.
Files changed (60) hide show
  1. package/package.json +1 -1
  2. package/src/core/bvh2/binary/IndexedBinaryBVH.spec.js +20 -0
  3. package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.d.ts +4 -0
  4. package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.spec.js +30 -0
  5. package/src/core/bvh2/bvh3/ebvh_build_for_geometry_incremental.js +6 -1
  6. package/src/core/bvh2/bvh3/query/bvh_collect_user_data.js +5 -1
  7. package/src/core/cache/Cache.d.ts +2 -0
  8. package/src/core/cache/Cache.js +1 -1
  9. package/src/core/cache/Cache.spec.js +19 -0
  10. package/src/core/cache/LoadingCache.d.ts +18 -0
  11. package/src/core/cache/LoadingCache.js +115 -0
  12. package/src/core/codegen/LineBuilder.js +8 -1
  13. package/src/core/codegen/LineBuilder.spec.js +34 -0
  14. package/src/core/collection/array/arrayQuickSort.js +11 -2
  15. package/src/core/collection/array/array_contains_duplicates.js +6 -1
  16. package/src/core/collection/array/typed/is_typed_array_equals.js +13 -4
  17. package/src/core/collection/array/typed/is_typed_array_equals.spec.js +71 -0
  18. package/src/core/collection/table/RowFirstTable.js +1 -1
  19. package/src/core/collection/table/RowFirstTable.spec.js +36 -0
  20. package/src/core/collection/table/RowFirstTableSpec.js +3 -0
  21. package/src/core/color/hsv2rgb.js +8 -3
  22. package/src/core/color/hsv2rgb.spec.js +43 -0
  23. package/src/core/geom/3d/aabb/aabb3_array_intersects_ray_array.js +2 -1
  24. package/src/core/geom/3d/compute_triangle_normal.js +1 -51
  25. package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +2 -2
  26. package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.spec.js +27 -0
  27. package/src/core/geom/3d/triangle/computeTriangleRayIntersection.spec.js +25 -0
  28. package/src/core/geom/3d/v3_compute_triangle_normal.js +51 -0
  29. package/src/core/geom/3d/v3_compute_triangle_normal.spec.js +27 -0
  30. package/src/core/geom/packing/miniball/Miniball.spec.js +11 -0
  31. package/src/core/graph/SquareMatrix.js +1 -9
  32. package/src/core/graph/graph_k_means_cluster.spec.js +23 -0
  33. package/src/core/{land → lang}/reactive/compileReactiveExpression.spec.js +2 -2
  34. package/src/core/model/reactive/trigger/ReactiveTrigger.js +1 -1
  35. package/src/engine/ecs/dynamic_actions/actions/definition/SendRequestActionDescription.js +1 -1
  36. package/src/engine/ecs/dynamic_actions/actions/definition/WhiteToBlackboardActionDescription.js +1 -1
  37. package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescription.js +1 -1
  38. package/src/engine/ecs/fow/FogOfWarRevealer.js +0 -27
  39. package/src/engine/ecs/fow/serialization/FogOfWarRevealerSerializationAdapter.js +29 -0
  40. package/src/engine/ecs/transform/TransformSerializationAdapter.spec.js +28 -0
  41. package/src/engine/knowledge/database/StaticKnowledgeDataTable.spec.js +5 -0
  42. package/src/engine/options/Option.js +36 -14
  43. package/src/engine/options/Option.spec.js +69 -0
  44. package/src/engine/reference/v2/Reference.d.ts +2 -0
  45. package/src/engine/reference/v2/Reference.js +3 -0
  46. package/src/engine/reference/v2/Reference.spec.js +44 -0
  47. package/src/core/bvh2/bvh3/BVHNodeProxy.js +0 -53
  48. package/src/core/graph/GraphElement.js +0 -6
  49. package/src/core/graph/Node.js +0 -12
  50. package/src/generation/GridGeneratorConfigurator.js +0 -0
  51. /package/src/core/{land → lang}/reactive/AbstractCachingParser.js +0 -0
  52. /package/src/core/{land → lang}/reactive/ReactiveOperatorType.js +0 -0
  53. /package/src/core/{land → lang}/reactive/compileReactiveExpression.js +0 -0
  54. /package/src/core/{land → lang}/reactive/nearley/Reactive.ne +0 -0
  55. /package/src/core/{land → lang}/reactive/pegjs/Reactive.peg +0 -0
  56. /package/src/core/{land → lang}/reactive/pegjs/ReactivePegCompiler.js +0 -0
  57. /package/src/core/{land → lang}/reactive/pegjs/ReactivePegParser.js +0 -0
  58. /package/src/core/{land → lang}/reactive/pegjs/parser.js +0 -0
  59. /package/src/core/{land → lang}/reactive/validateReactiveExpression.js +0 -0
  60. /package/src/generation/rules/{CellMatcherContainsTag.spec.js → CellMatcherLayerBitMaskTest.spec.js} +0 -0
@@ -1,55 +1,5 @@
1
- import { v3_length_sqr } from "../v3_length_sqr.js";
2
1
  import { vec3 } from "gl-matrix";
3
-
4
- /**
5
- *
6
- * @param {number[]} result
7
- * @param {number} result_offset
8
- * @param {number} vAx
9
- * @param {number} vAy
10
- * @param {number} vAz
11
- * @param {number} vBx
12
- * @param {number} vBy
13
- * @param {number} vBz
14
- * @param {number} vCx
15
- * @param {number} vCy
16
- * @param {number} vCz
17
- */
18
- export function v3_compute_triangle_normal(result, result_offset, vAx, vAy, vAz, vBx, vBy, vBz, vCx, vCy, vCz) {
19
- //compute CB and AB vectors
20
- const vCBx = vCx - vBx;
21
- const vCBy = vCy - vBy;
22
- const vCBz = vCz - vBz;
23
-
24
- const vABx = vAx - vBx;
25
- const vABy = vAy - vBy;
26
- const vABz = vAz - vBz;
27
-
28
- //compute triangle normal
29
- const crossX = vCBy * vABz - vCBz * vABy;
30
- const crossY = vCBz * vABx - vCBx * vABz;
31
- const crossZ = vCBx * vABy - vCBy * vABx;
32
-
33
- const l_sqr = v3_length_sqr(crossX, crossY, crossZ);
34
-
35
- if (l_sqr === 0) {
36
- // degenerate triangle, provide arbitrary invalid result
37
- result[result_offset] = 0;
38
- result[result_offset + 1] = 1;
39
- result[result_offset + 2] = 0;
40
- return;
41
- }
42
-
43
- const l_inv = 1 / Math.sqrt(l_sqr);
44
-
45
- const x = crossX * l_inv;
46
- const y = crossY * l_inv;
47
- const z = crossZ * l_inv;
48
-
49
- result[result_offset] = x;
50
- result[result_offset + 1] = y;
51
- result[result_offset + 2] = z;
52
- }
2
+ import { v3_compute_triangle_normal } from "./v3_compute_triangle_normal.js";
53
3
 
54
4
  /**
55
5
  *
@@ -613,9 +613,9 @@ function windowSH(output, output_offset, input, input_offset, numBands, channel_
613
613
 
614
614
  /**
615
615
  *
616
- * @param {number[]} result
616
+ * @param {number[]|Float32Array} result
617
617
  * @param {number} result_offset
618
- * @param {number[]} harmonics
618
+ * @param {number[]|Float32Array} harmonics
619
619
  * @param {number} harmonics_offset
620
620
  * @param {number} dimension_count
621
621
  */
@@ -0,0 +1,27 @@
1
+ import { sh3_dering_optimize_positive } from "./sh3_dering_optimize_positive.js";
2
+
3
+ test("de-ringing produces plausible numeric values", () => {
4
+
5
+ const result = [];
6
+
7
+ const harmonics = new Float32Array(9);
8
+
9
+ harmonics.fill(1);
10
+
11
+ sh3_dering_optimize_positive(
12
+ result, 0,
13
+ harmonics,
14
+ 0,
15
+ 1
16
+ );
17
+
18
+ for (let i = 0; i < 9; i++) {
19
+
20
+ const element = result[i];
21
+
22
+ expect(element).not.toBeNaN();
23
+ expect(Number.isFinite(element)).toBe(true);
24
+
25
+ }
26
+
27
+ });
@@ -0,0 +1,25 @@
1
+ import { computeTriangleRayIntersection } from "./computeTriangleRayIntersection.js";
2
+ import { SurfacePoint3 } from "../SurfacePoint3.js";
3
+
4
+ test("simple axis aligned intersection", () => {
5
+ const sp = new SurfacePoint3();
6
+
7
+ expect(computeTriangleRayIntersection(
8
+ sp,
9
+ 0, 0, -1,
10
+ 0, 0, 1,
11
+ -1, -1, 0,
12
+ 1, -1, 0,
13
+ 0, 1, 0
14
+ )).toBe(true);
15
+
16
+ expect(computeTriangleRayIntersection(
17
+ sp,
18
+ 0, 0, -1,
19
+ 0, 0, -1,
20
+ -1, -1, 0,
21
+ 1, -1, 0,
22
+ 0, 1, 0
23
+ )).toBe(false);
24
+
25
+ });
@@ -0,0 +1,51 @@
1
+ import { v3_length_sqr } from "../v3_length_sqr.js";
2
+
3
+ /**
4
+ *
5
+ * @param {number[]} result
6
+ * @param {number} result_offset
7
+ * @param {number} vAx
8
+ * @param {number} vAy
9
+ * @param {number} vAz
10
+ * @param {number} vBx
11
+ * @param {number} vBy
12
+ * @param {number} vBz
13
+ * @param {number} vCx
14
+ * @param {number} vCy
15
+ * @param {number} vCz
16
+ */
17
+ export function v3_compute_triangle_normal(result, result_offset, vAx, vAy, vAz, vBx, vBy, vBz, vCx, vCy, vCz) {
18
+ //compute CB and AB vectors
19
+ const vCBx = vCx - vBx;
20
+ const vCBy = vCy - vBy;
21
+ const vCBz = vCz - vBz;
22
+
23
+ const vABx = vAx - vBx;
24
+ const vABy = vAy - vBy;
25
+ const vABz = vAz - vBz;
26
+
27
+ //compute triangle normal
28
+ const crossX = vCBy * vABz - vCBz * vABy;
29
+ const crossY = vCBz * vABx - vCBx * vABz;
30
+ const crossZ = vCBx * vABy - vCBy * vABx;
31
+
32
+ const l_sqr = v3_length_sqr(crossX, crossY, crossZ);
33
+
34
+ if (l_sqr === 0) {
35
+ // degenerate triangle, provide arbitrary invalid result
36
+ result[result_offset] = 0;
37
+ result[result_offset + 1] = 1;
38
+ result[result_offset + 2] = 0;
39
+ return;
40
+ }
41
+
42
+ const l_inv = 1 / Math.sqrt(l_sqr);
43
+
44
+ const x = crossX * l_inv;
45
+ const y = crossY * l_inv;
46
+ const z = crossZ * l_inv;
47
+
48
+ result[result_offset] = x;
49
+ result[result_offset + 1] = y;
50
+ result[result_offset + 2] = z;
51
+ }
@@ -0,0 +1,27 @@
1
+ import { v3_compute_triangle_normal } from "./v3_compute_triangle_normal.js";
2
+
3
+ test("axis aligned triangles on +X plane", () => {
4
+ const result = [];
5
+
6
+ v3_compute_triangle_normal(
7
+ result, 0,
8
+ 0, -1, -1,
9
+ 0, 1, -1,
10
+ 0, 0, 1,
11
+ );
12
+
13
+ expect(result).toEqual([+1, 0, 0]);
14
+ });
15
+
16
+ test("axis aligned triangles on -X plane", () => {
17
+ const result = [];
18
+
19
+ v3_compute_triangle_normal(
20
+ result, 0,
21
+ 0, 0, 1,
22
+ 0, 1, -1,
23
+ 0, -1, -1,
24
+ );
25
+
26
+ expect(result).toEqual([-1, 0, 0]);
27
+ });
@@ -0,0 +1,11 @@
1
+ import { Miniball } from "./Miniball.js";
2
+ import { PointSet } from "./PointSet.js";
3
+
4
+ test("single point in 1d", () => {
5
+
6
+ const miniball = new Miniball(new PointSet(1, 1, [7]));
7
+
8
+ expect(miniball.center()).toEqual([7]);
9
+ expect(miniball.radius()).toEqual(0);
10
+
11
+ });
@@ -53,15 +53,7 @@ export class SquareMatrix {
53
53
  * @param {SquareMatrix} other
54
54
  */
55
55
  subtract(other) {
56
- const size = this.size;
57
- const data_length = size * size;
58
-
59
- const this_data = this.data;
60
- const other_data = other.data;
61
-
62
- for (let i = 0; i < data_length; i++) {
63
- this_data[i] -= other_data[i];
64
- }
56
+ this.subtractMatrices(this,other);
65
57
  }
66
58
 
67
59
  /**
@@ -0,0 +1,23 @@
1
+ import { graph_k_means_cluster } from "./graph_k_means_cluster.js";
2
+ import { Graph } from "./v2/Graph.js";
3
+
4
+ test("empty graph", () => {
5
+ const graph = new Graph();
6
+
7
+ const clusters = graph_k_means_cluster(graph, 0, 0);
8
+
9
+ expect(Array.isArray(clusters)).toBe(true);
10
+ expect(clusters.length).toBe(0);
11
+ });
12
+
13
+ test("2-node graph with k=1", () => {
14
+ const graph = new Graph();
15
+ graph.addNode(3);
16
+ graph.addNode(7);
17
+
18
+ const clusters = graph_k_means_cluster(graph, 1, 0);
19
+
20
+ expect(Array.isArray(clusters)).toBe(true);
21
+ expect(clusters.length).toBe(1);
22
+ expect(clusters.map(cluster => cluster.sort())).toEqual([[0, 1]]);
23
+ });
@@ -9,11 +9,11 @@ import { ReactiveGreaterThanOrEqual } from "../../model/reactive/model/comparati
9
9
  import { ReactiveLessThan } from "../../model/reactive/model/comparative/ReactiveLessThan.js";
10
10
  import { ReactiveLessThanOrEqual } from "../../model/reactive/model/comparative/ReactiveLessThanOrEqual.js";
11
11
  import { ReactiveNotEquals } from "../../model/reactive/model/comparative/ReactiveNotEquals.js";
12
- import { ReactiveAnd } from "../../model/reactive/model/logic/ReactiveAnd.d.ts";
12
+ import { ReactiveAnd } from "../../model/reactive/model/logic/ReactiveAnd.js";
13
13
  import { ReactiveNot } from "../../model/reactive/model/logic/ReactiveNot.js";
14
14
  import { ReactiveOr } from "../../model/reactive/model/logic/ReactiveOr.js";
15
15
  import { ReactiveLiteralNumber } from "../../model/reactive/model/terminal/ReactiveLiteralNumber.js";
16
- import { ReactiveReference } from "../../model/reactive/model/terminal/ReactiveReference.d.ts";
16
+ import { ReactiveReference } from "../../model/reactive/model/terminal/ReactiveReference.js";
17
17
  import { compileReactiveExpression } from "./compileReactiveExpression.js";
18
18
 
19
19
  test('compile: REFERENCE', () => {
@@ -1,5 +1,5 @@
1
1
  import { assert } from "../../../assert.js";
2
- import { compileReactiveExpression } from "../../../land/reactive/compileReactiveExpression.js";
2
+ import { compileReactiveExpression } from "../../../lang/reactive/compileReactiveExpression.js";
3
3
  import DataType from "../../../parser/simple/DataType.js";
4
4
  import { inferReactiveExpressionTypes } from "../transform/ReactiveTypeInferrence.js";
5
5
 
@@ -2,7 +2,7 @@ import { AbstractActionDescription } from "./AbstractActionDescription.js";
2
2
  import { assert } from "../../../../../core/assert.js";
3
3
  import { ActionBehavior } from "../../../../intelligence/behavior/primitive/ActionBehavior.js";
4
4
  import { Transform } from "../../../transform/Transform.js";
5
- import { compileReactiveExpression } from "../../../../../core/land/reactive/compileReactiveExpression.js";
5
+ import { compileReactiveExpression } from "../../../../../core/lang/reactive/compileReactiveExpression.js";
6
6
 
7
7
  export class SendRequestActionDescription extends AbstractActionDescription {
8
8
  constructor() {
@@ -1,7 +1,7 @@
1
1
  import { AbstractActionDescription } from "./AbstractActionDescription.js";
2
2
  import { ActionBehavior } from "../../../../intelligence/behavior/primitive/ActionBehavior.js";
3
3
  import { Blackboard } from "../../../../intelligence/blackboard/Blackboard.js";
4
- import { compileReactiveExpression } from "../../../../../core/land/reactive/compileReactiveExpression.js";
4
+ import { compileReactiveExpression } from "../../../../../core/lang/reactive/compileReactiveExpression.js";
5
5
  import { assert } from "../../../../../core/assert.js";
6
6
 
7
7
  export class WhiteToBlackboardActionDescription extends AbstractActionDescription {
@@ -2,7 +2,7 @@ import UUID from "../../../../core/UUID.js";
2
2
  import { assert } from "../../../../core/assert.js";
3
3
  import { inferReactiveExpressionTypes } from "../../../../core/model/reactive/transform/ReactiveTypeInferrence.js";
4
4
  import DataType from "../../../../core/parser/simple/DataType.js";
5
- import { compileReactiveExpression } from "../../../../core/land/reactive/compileReactiveExpression.js";
5
+ import { compileReactiveExpression } from "../../../../core/lang/reactive/compileReactiveExpression.js";
6
6
  import { deserializeActionFromJSON } from "../actions/definition/deserializeActionFromJSON.js";
7
7
  import { DynamicRuleCooldownDescription } from "./DynamicRuleCooldownDescription.js";
8
8
 
@@ -1,5 +1,4 @@
1
1
  import Vector1 from "../../../core/geom/Vector1.js";
2
- import { BinaryClassSerializationAdapter } from "../storage/binary/BinaryClassSerializationAdapter.js";
3
2
 
4
3
  export class FogOfWarRevealer {
5
4
  constructor() {
@@ -28,29 +27,3 @@ export class FogOfWarRevealer {
28
27
  FogOfWarRevealer.typeName = 'FogOfWarRevealer';
29
28
 
30
29
 
31
- export class FogOfWarRevealerSerializationAdapter extends BinaryClassSerializationAdapter {
32
- constructor() {
33
- super();
34
-
35
- this.klass = FogOfWarRevealer;
36
- this.version = 0;
37
- }
38
-
39
- /**
40
- *
41
- * @param {BinaryBuffer} buffer
42
- * @param {FogOfWarRevealer} value
43
- */
44
- serialize(buffer, value) {
45
- value.radius.toBinaryBuffer(buffer);
46
- }
47
-
48
- /**
49
- *
50
- * @param {BinaryBuffer} buffer
51
- * @param {FogOfWarRevealer} value
52
- */
53
- deserialize(buffer, value) {
54
- value.radius.fromBinaryBuffer(buffer);
55
- }
56
- }
@@ -0,0 +1,29 @@
1
+ import { BinaryClassSerializationAdapter } from "../../storage/binary/BinaryClassSerializationAdapter.js";
2
+ import { FogOfWarRevealer } from "../FogOfWarRevealer.js";
3
+
4
+ export class FogOfWarRevealerSerializationAdapter extends BinaryClassSerializationAdapter {
5
+ constructor() {
6
+ super();
7
+
8
+ this.klass = FogOfWarRevealer;
9
+ this.version = 0;
10
+ }
11
+
12
+ /**
13
+ *
14
+ * @param {BinaryBuffer} buffer
15
+ * @param {FogOfWarRevealer} value
16
+ */
17
+ serialize(buffer, value) {
18
+ value.radius.toBinaryBuffer(buffer);
19
+ }
20
+
21
+ /**
22
+ *
23
+ * @param {BinaryBuffer} buffer
24
+ * @param {FogOfWarRevealer} value
25
+ */
26
+ deserialize(buffer, value) {
27
+ value.radius.fromBinaryBuffer(buffer);
28
+ }
29
+ }
@@ -0,0 +1,28 @@
1
+ import { TransformSerializationAdapter } from "./TransformSerializationAdapter.js";
2
+ import { Transform } from "./Transform.js";
3
+ import { BinaryBuffer } from "../../../core/binary/BinaryBuffer.js";
4
+
5
+ test("to/from consistency", () => {
6
+ const adapter = new TransformSerializationAdapter();
7
+
8
+ const expected = new Transform();
9
+ expected.position.set(1, 3, -7.3);
10
+ expected.scale.set(-5, 7, -13.8);
11
+ expected.rotation.set(17, -27, 31, 37);
12
+
13
+ expected.rotation.normalize();
14
+
15
+ const buffer = new BinaryBuffer();
16
+
17
+ adapter.serialize(buffer, expected);
18
+
19
+ buffer.position = 0;
20
+
21
+ const actual = new Transform();
22
+
23
+ adapter.deserialize(buffer, actual);
24
+
25
+ expect(actual.position.roughlyEquals(expected.position)).toBe(true);
26
+ expect(actual.scale.roughlyEquals(expected.scale)).toBe(true);
27
+ expect(actual.rotation.roughlyEquals(expected.rotation, 0.001)).toBe(true);
28
+ });
@@ -0,0 +1,5 @@
1
+ import { StaticKnowledgeDataTable } from "./StaticKnowledgeDataTable.js";
2
+
3
+ test("constructor does not throw", () => {
4
+ expect(() => new StaticKnowledgeDataTable()).not.toThrow();
5
+ });
@@ -1,8 +1,16 @@
1
1
  import { noop } from "../../core/function/Functions.js";
2
2
  import Signal from "../../core/events/signal/Signal.js";
3
3
  import { OptionAbstract } from "./OptionAbstract.js";
4
+ import { assert } from "../../core/assert.js";
4
5
 
5
6
  export class Option extends OptionAbstract {
7
+
8
+ on = {
9
+ written: new Signal(),
10
+ writeFailed: new Signal(),
11
+ settingsUpdated: new Signal()
12
+ };
13
+
6
14
  /**
7
15
  *
8
16
  * @param {string} id
@@ -16,18 +24,32 @@ export class Option extends OptionAbstract {
16
24
  }) {
17
25
  super(id);
18
26
 
27
+ assert.isFunction(read, 'read');
28
+
19
29
  const self = this;
20
30
 
21
31
  function wrappedWrite(v) {
22
- const result = write(v);
23
-
24
- if (result !== undefined && typeof result.then === "function") {
25
- result.then(
26
- () => self.on.written.dispatch(v),
27
- (e) => self.on.writeFailed.dispatch(v, e)
28
- );
29
- } else {
30
- self.on.written.dispatch(v);
32
+ let result;
33
+
34
+ let exception_thrown = false;
35
+
36
+ try {
37
+ result = write(v);
38
+ } catch (e) {
39
+ exception_thrown = true;
40
+
41
+ self.on.writeFailed.send2(v, e);
42
+ }
43
+
44
+ if (!exception_thrown) {
45
+ if (result !== undefined && typeof result.then === "function") {
46
+ result.then(
47
+ () => self.on.written.send1(v),
48
+ (e) => self.on.writeFailed.send2(v, e)
49
+ );
50
+ } else {
51
+ self.on.written.send1(v);
52
+ }
31
53
  }
32
54
 
33
55
  return result;
@@ -43,13 +65,13 @@ export class Option extends OptionAbstract {
43
65
  */
44
66
  this.isTransient = (settings.transient === true);
45
67
 
46
- this.on = {
47
- written: new Signal(),
48
- writeFailed: new Signal(),
49
- settingsUpdated: new Signal()
50
- };
51
68
  }
52
69
 
70
+ /**
71
+ *
72
+ * @param {string} key
73
+ * @param {number|boolean|string} value
74
+ */
53
75
  setSetting(key, value) {
54
76
  this.settings[key] = value;
55
77
 
@@ -0,0 +1,69 @@
1
+ import { Option } from "./Option.js";
2
+ import { returnOne } from "../../core/function/Functions.js";
3
+
4
+ test("constructing a simple valid option", () => {
5
+ const option = new Option("x", returnOne);
6
+
7
+ expect(option.id).toEqual('x');
8
+ });
9
+
10
+ test("'written' signal is invoked after write succeeds", () => {
11
+
12
+ let value = 13;
13
+
14
+ const opt = new Option("x", () => value, v => value = v);
15
+
16
+ const callback = jest.fn();
17
+
18
+ opt.on.written.add(callback);
19
+
20
+ opt.write(7);
21
+
22
+ expect(callback).toHaveBeenCalledTimes(1);
23
+
24
+ });
25
+
26
+ test("'writeFailed' signal is invoked after write throws", () => {
27
+
28
+ let value = 13;
29
+
30
+ const opt = new Option("x", () => value, v => value = v);
31
+
32
+ const callback = jest.fn();
33
+
34
+ opt.on.written.add(callback);
35
+
36
+ opt.write(7);
37
+
38
+ expect(callback).toHaveBeenCalledTimes(1);
39
+ });
40
+
41
+ test("toJSON", () => {
42
+
43
+ let value = 13;
44
+
45
+ const opt = new Option("x", () => value, v => value = v);
46
+
47
+ expect(opt.toJSON()).toBe(13);
48
+
49
+ });
50
+
51
+ test("fromJSON", () => {
52
+
53
+ let value = 1;
54
+
55
+ const opt = new Option("x", () => value, v => value = v);
56
+
57
+ opt.fromJSON(17);
58
+
59
+ expect(value).toBe(17);
60
+
61
+
62
+ });
63
+
64
+ test("computePath on a detached option should be just the ID of that option", () => {
65
+ const op = new Option("x", returnOne);
66
+
67
+ expect(op.computePath()).toEqual(["x"]);
68
+ });
69
+
@@ -3,6 +3,8 @@ import Signal from "../../../core/events/signal/Signal";
3
3
  export class Reference<T> {
4
4
  readonly onReleased: Signal<Reference<T>, T>
5
5
 
6
+ readonly bound: boolean
7
+
6
8
  getValue(): T | null
7
9
 
8
10
  release(): void
@@ -27,6 +27,9 @@ export class Reference {
27
27
  */
28
28
  #is_bound = false;
29
29
 
30
+ get bound(){
31
+ return this.#is_bound;
32
+ }
30
33
 
31
34
  /**
32
35
  *
@@ -0,0 +1,44 @@
1
+ import { Reference } from "./Reference.js";
2
+
3
+ test("constructor does not throw", () => {
4
+ expect(() => new Reference()).not.toThrow();
5
+ });
6
+
7
+ test("newly created reference is unbound", () => {
8
+
9
+ const ref = new Reference();
10
+
11
+ expect(ref.bound).toBe(false);
12
+
13
+ });
14
+
15
+ test("bind sets value", () => {
16
+ const ref = new Reference();
17
+
18
+ ref.bind(7);
19
+
20
+ expect(ref.getValue()).toBe(7);
21
+ expect(ref.bound).toBe(true);
22
+ });
23
+
24
+ test("re-binding a live reference throws an exception", () => {
25
+
26
+ const ref = new Reference();
27
+
28
+ ref.bind(7);
29
+
30
+ expect(() => ref.bind(13)).toThrow();
31
+
32
+ });
33
+
34
+ test("release resets reference", () => {
35
+
36
+ const ref = new Reference();
37
+
38
+ ref.bind(7);
39
+
40
+ ref.release();
41
+
42
+ expect(ref.getValue()).toBeNull();
43
+ expect(ref.bound).toBe(false);
44
+ });
@@ -1,53 +0,0 @@
1
- export class BVHNodeProxy {
2
- constructor() {
3
- /**
4
- *
5
- * @type {number}
6
- * @private
7
- */
8
- this.__node = -1;
9
-
10
- /**
11
- *
12
- * @type {ExplicitBinaryBoundingVolumeHierarchy|null}
13
- * @private
14
- */
15
- this.__tree = null;
16
- }
17
-
18
- /**
19
- *
20
- * @param {number} node
21
- * @param {ExplicitBinaryBoundingVolumeHierarchy} tree
22
- */
23
- bind(node, tree) {
24
- this.__node = node;
25
- this.__tree = tree;
26
- }
27
-
28
- /**
29
- *
30
- * @param {number} x0
31
- * @param {number} y0
32
- * @param {number} z0
33
- * @param {number} x1
34
- * @param {number} y1
35
- * @param {number} z1
36
- */
37
- set_bounds(x0, y0, z0, x1, y1, z1) {
38
- this.__tree.node_set_aabb_primitive(this.__node,
39
- x0, y0, z0, x1, y1, z1
40
- );
41
- }
42
-
43
- disconnect() {
44
- this.__tree.remove_leaf(this.__node);
45
- }
46
-
47
- destroy() {
48
- this.__tree.release_node(this.__node);
49
-
50
- this.__tree = null;
51
- this.__node = -1;
52
- }
53
- }