@woosh/meep-engine 2.36.28 → 2.37.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.
Files changed (125) hide show
  1. package/core/bvh2/bvh3/{bvh_query_user_data_by_frustum.js → bvh_query_user_data_overlaps_frustum.js} +4 -5
  2. package/core/bvh2/traversal/ThreeClippingPlaneComputingBVHVisitor.js +1 -1
  3. package/core/color/Color.js +54 -3
  4. package/core/color/hsv2rgb.js +3 -3
  5. package/core/color/kelvin_to_rgb.js +51 -0
  6. package/core/color/kelvin_to_rgb.spec.js +61 -0
  7. package/core/color/linear_to_sRGB.js +17 -0
  8. package/core/color/prototype_kelvin_to_rgb.js +44 -0
  9. package/core/color/rgb_to_kelvin.js +34 -0
  10. package/core/color/rgb_to_kelvin.spec.js +15 -0
  11. package/core/color/sRGB_to_linear.js +16 -0
  12. package/core/geom/3d/frustum/read_frustum_planes_to_array.d.ts +3 -0
  13. package/{engine/graphics/render/forward_plus/cluster → core/geom/3d/frustum}/read_frustum_planes_to_array.js +1 -1
  14. package/core/geom/3d/line/line3_computeSegmentPointDistance_sqr.js +2 -2
  15. package/core/geom/LineSegment.js +2 -2
  16. package/core/geom/Vector3.js +14 -0
  17. package/core/math/DEG_TO_RAD.js +1 -0
  18. package/core/math/MathUtils.spec.js +0 -13
  19. package/core/math/RAD_TO_DEG.js +1 -0
  20. package/core/math/clamp01.js +15 -0
  21. package/core/math/fract.js +10 -0
  22. package/core/math/newton_solver_1d.js +21 -0
  23. package/core/math/smoothStep.js +3 -3
  24. package/core/math/solveQuadratic.js +32 -12
  25. package/core/math/solveQuadratic.spec.js +18 -0
  26. package/core/primitives/strings/StringUtils.js +10 -0
  27. package/core/process/task/TaskUtils.js +2 -2
  28. package/core/process/undo/Action.d.ts +2 -2
  29. package/core/process/undo/Action.js +4 -4
  30. package/core/process/undo/ActionGroup.js +4 -4
  31. package/core/process/undo/ActionProcessor.d.ts +6 -6
  32. package/core/process/undo/ActionProcessor.js +106 -16
  33. package/core/process/undo/ActionProcessor.spec.js +20 -15
  34. package/editor/actions/concrete/ComponentAddAction.js +2 -2
  35. package/editor/actions/concrete/ComponentRemoveAction.js +2 -2
  36. package/editor/actions/concrete/EntityCreateAction.js +2 -2
  37. package/editor/actions/concrete/EntityRemoveAction.js +2 -2
  38. package/editor/actions/concrete/PaintTerrainOverlayAction.js +2 -2
  39. package/editor/actions/concrete/PatchTerrainHeightAction.js +2 -2
  40. package/editor/actions/concrete/PatchTerrainTextureAction.js +2 -2
  41. package/editor/actions/concrete/SelectionAddAction.js +2 -2
  42. package/editor/actions/concrete/SelectionClearAction.js +2 -2
  43. package/editor/actions/concrete/SelectionRemoveAction.js +2 -2
  44. package/editor/actions/concrete/TransformModifyAction.js +2 -2
  45. package/editor/actions/concrete/WriteGridValueAction.js +2 -2
  46. package/editor/view/EditorView.js +11 -9
  47. package/editor/view/ecs/components/color/GaugeView.js +2 -2
  48. package/editor/view/ecs/components/particles/ColorParameterLUTController.js +5 -4
  49. package/editor/view/ecs/components/particles/ScalarParameterLUTController.js +5 -3
  50. package/engine/Clock.js +4 -0
  51. package/engine/UserController.js +2 -1
  52. package/engine/animation/behavior/animateProperty.js +6 -1
  53. package/engine/animation/keyed2/behavior/AnimationBehavior.js +0 -1
  54. package/engine/ecs/EntityBuilder.js +12 -1
  55. package/engine/ecs/animation/OneBoneSurfaceAlignmentSolver.js +2 -1
  56. package/engine/ecs/animation/TwoBoneInverseKinematicsSolver.js +2 -1
  57. package/engine/ecs/fow/shader/screenSpaceFogOfWarShader.js +14 -11
  58. package/engine/ecs/systems/AimControllerSystem.js +3 -2
  59. package/engine/ecs/systems/RangedAttackSystem.js +3 -2
  60. package/engine/ecs/systems/SteeringSystem.js +3 -3
  61. package/engine/ecs/terrain/ecs/ClingToTerrainSystem.js +2 -2
  62. package/engine/ecs/terrain/util/paintTerrainOverlayViaLookupTable.js +2 -2
  63. package/engine/graphics/GraphicsEngine.js +2 -1
  64. package/engine/graphics/camera/CameraShake.js +4 -4
  65. package/engine/graphics/ecs/animation/animator/graph/AnimationTransition.js +2 -2
  66. package/engine/graphics/ecs/camera/TiltCameraController.js +3 -2
  67. package/engine/graphics/ecs/compileAllMaterials.js +2 -2
  68. package/engine/graphics/ecs/highlight/renderer/OutlineRenderer.js +10 -11
  69. package/engine/graphics/ecs/mesh/createTaskWaitForMeshesToLoad.js +2 -2
  70. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.d.ts +6 -0
  71. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +19 -0
  72. package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +4 -2
  73. package/engine/graphics/ecs/mesh-v2/render/optimization/RuntimeDrawMethodOptimizer.js +6 -0
  74. package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +31 -0
  75. package/engine/graphics/micron/build/fill_patch_geometry_data.js +2 -2
  76. package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +5 -3
  77. package/engine/graphics/render/forward_plus/LightManager.js +1 -1
  78. package/engine/graphics/render/gizmo/Gizmo.js +3 -0
  79. package/engine/graphics/render/gizmo/GizmoRenderingPlugin.js +5 -0
  80. package/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +91 -0
  81. package/engine/graphics/render/view/CameraView.js +1 -1
  82. package/engine/graphics/texture/sampler/Sampler2D.js +110 -18
  83. package/engine/graphics/three/OrbitControls.js +3 -2
  84. package/engine/graphics/trail/x/simulator/RibbonXFixedPhysicsSimulator.js +2 -2
  85. package/engine/graphics/util/makeMeshPreviewScene.js +11 -3
  86. package/engine/intelligence/behavior/Behavior.js +36 -17
  87. package/engine/intelligence/behavior/SelectorBehavior.js +6 -5
  88. package/engine/intelligence/behavior/composite/ParallelBehavior.js +0 -66
  89. package/engine/intelligence/behavior/composite/ParallelBehaviorSerializationAdapter.js +63 -0
  90. package/engine/intelligence/behavior/composite/SequenceBehavior.js +36 -11
  91. package/engine/intelligence/behavior/decorator/AbstractDecoratorBehavior.js +0 -2
  92. package/engine/intelligence/behavior/decorator/IgnoreFailureBehavior.js +2 -4
  93. package/engine/intelligence/behavior/decorator/InverterBehavior.js +3 -3
  94. package/engine/intelligence/behavior/decorator/RepeatBehavior.js +0 -35
  95. package/engine/intelligence/behavior/decorator/RepeatBehavior.spec.js +0 -10
  96. package/engine/intelligence/behavior/decorator/RepeatBehaviorSerializationAdapter.js +37 -0
  97. package/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.js +0 -3
  98. package/engine/intelligence/behavior/decorator/RepeatUntilSuccessBehavior.js +5 -10
  99. package/engine/intelligence/behavior/ecs/BehaviorComponent.js +95 -7
  100. package/engine/intelligence/behavior/ecs/BehaviorComponentSerializationAdapter.js +15 -8
  101. package/engine/intelligence/behavior/ecs/BehaviorSystem.js +28 -37
  102. package/engine/intelligence/behavior/ecs/DieBehavior.js +2 -7
  103. package/engine/intelligence/behavior/ecs/WaitForEventBehavior.js +2 -29
  104. package/engine/intelligence/behavior/ecs/WaitForEventBehaviorSerializationAdapter.js +29 -0
  105. package/engine/intelligence/behavior/primitive/ActionBehavior.js +6 -13
  106. package/engine/intelligence/behavior/primitive/FailingBehavior.js +1 -29
  107. package/engine/intelligence/behavior/primitive/FailingBehaviorSerializationAdapter.js +29 -0
  108. package/engine/intelligence/behavior/primitive/PromiseBehavior.js +15 -3
  109. package/engine/intelligence/behavior/selector/WeightedRandomBehavior.js +1 -5
  110. package/engine/intelligence/behavior/util/ConditionBehavior.js +1 -3
  111. package/engine/intelligence/behavior/util/ConditionBehavior.spec.js +1 -7
  112. package/engine/intelligence/behavior/util/ConditionalBehavior.js +3 -6
  113. package/engine/intelligence/behavior/util/DelayBehavior.js +2 -4
  114. package/engine/intelligence/behavior/util/SelectorBehavior.js +13 -12
  115. package/engine/intelligence/blackboard/AbstractBlackboard.js +16 -2
  116. package/engine/plugin/EnginePluginManager.js +4 -14
  117. package/engine/sound/ecs/emitter/SoundEmitter.js +3 -0
  118. package/generation/filtering/numeric/math/CellFilterSaturate.js +2 -2
  119. package/generation/grid/generation/GridTaskDensityMarkerDistribution.js +3 -2
  120. package/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.spec.js +1 -1
  121. package/generation/rules/CellMatcherLayerBitMaskTest.js +3 -3
  122. package/package.json +1 -1
  123. package/view/elements/progress/SmoothProgressBar.js +2 -2
  124. package/view/elements/progress/segmented/SegmentedResourceBarView.js +3 -3
  125. package/view/elements/radial/RadialProgressView.js +2 -2
@@ -0,0 +1,63 @@
1
+ import {
2
+ ObjectBasedClassSerializationAdapter
3
+ } from "../../../ecs/storage/binary/object/ObjectBasedClassSerializationAdapter.js";
4
+ import { ParallelBehavior } from "./ParallelBehavior.js";
5
+
6
+ export class ParallelBehaviorSerializationAdapter extends ObjectBasedClassSerializationAdapter {
7
+ constructor() {
8
+ super();
9
+
10
+ this.klass = ParallelBehavior;
11
+ this.version = 0;
12
+ }
13
+
14
+ /**
15
+ *
16
+ * @param {BinaryBuffer} buffer
17
+ * @param {ParallelBehavior} value
18
+ */
19
+ serialize(buffer, value) {
20
+
21
+ buffer.writeUint8(value.getSuccessPolicy());
22
+ buffer.writeUint8(value.getFailurePolicy());
23
+
24
+ const children = value.getChildren();
25
+
26
+ const n = children.length;
27
+
28
+ buffer.writeUintVar(n);
29
+
30
+ for (let i = 0; i < n; i++) {
31
+ const behavior = children[i];
32
+
33
+ this.objectAdapter.serialize(buffer, behavior);
34
+ }
35
+ }
36
+
37
+ /**
38
+ *
39
+ * @param {BinaryBuffer} buffer
40
+ * @param {ParallelBehavior} value
41
+ */
42
+ deserialize(buffer, value) {
43
+ const successPolicy = buffer.readUint8();
44
+ const failurePolicy = buffer.readUint8();
45
+
46
+ const count = buffer.readUintVar();
47
+
48
+ value.clearChildren();
49
+
50
+ for (let i = 0; i < count; i++) {
51
+ /**
52
+ *
53
+ * @type {Behavior}
54
+ */
55
+ const child = this.objectAdapter.deserialize(buffer);
56
+
57
+ value.addChild(child);
58
+ }
59
+
60
+ value.setFailurePolicy(failurePolicy);
61
+ value.setSuccessPolicy(successPolicy);
62
+ }
63
+ }
@@ -1,7 +1,10 @@
1
1
  import { Behavior } from "../Behavior.js";
2
2
  import { CompositeBehavior } from "./CompositeBehavior.js";
3
3
  import { BehaviorStatus } from "../BehaviorStatus.js";
4
- import { ObjectBasedClassSerializationAdapter } from "../../../ecs/storage/binary/object/ObjectBasedClassSerializationAdapter.js";
4
+ import {
5
+ ObjectBasedClassSerializationAdapter
6
+ } from "../../../ecs/storage/binary/object/ObjectBasedClassSerializationAdapter.js";
7
+ import { assert } from "../../../../core/assert.js";
5
8
 
6
9
  export class SequenceBehavior extends CompositeBehavior {
7
10
  constructor() {
@@ -13,6 +16,12 @@ export class SequenceBehavior extends CompositeBehavior {
13
16
  * @protected
14
17
  */
15
18
  this.__currentBehaviourIndex = -1;
19
+ /**
20
+ *
21
+ * @type {BehaviorStatus|number}
22
+ * @private
23
+ */
24
+ this.__currentBehaviourState = BehaviorStatus.Initial;
16
25
 
17
26
  /**
18
27
  *
@@ -23,32 +32,41 @@ export class SequenceBehavior extends CompositeBehavior {
23
32
  }
24
33
 
25
34
  initialize(context) {
26
-
35
+ // console.log('+ SequenceBehavior');
27
36
  super.initialize(context);
28
37
 
29
38
  this.__currentBehaviourIndex = 0;
30
- this.__currentBehaviour = this.__children[this.__currentBehaviourIndex];
39
+ this.__currentBehaviour = this.__children[0];
31
40
 
32
41
  //initialize first behaviour
33
42
  this.__currentBehaviour.initialize(context);
34
43
 
44
+ this.__currentBehaviourState = BehaviorStatus.Running;
35
45
  }
36
46
 
47
+
37
48
  /**
38
49
  *
39
50
  * @param {number} timeDelta
40
51
  * @returns {BehaviorStatus}
41
52
  */
42
53
  tick(timeDelta) {
43
- const s = this.__currentBehaviour.tick(timeDelta);
54
+ assert.isNonNegativeInteger(this.__currentBehaviourIndex, 'child index');
55
+
56
+ const currentBehaviour = this.__currentBehaviour;
57
+
58
+ const s = currentBehaviour.tick(timeDelta);
59
+
60
+ this.__currentBehaviourState = s;
44
61
 
45
62
  if (s !== BehaviorStatus.Succeeded) {
46
63
  return s;
47
64
  }
48
65
 
49
66
  //current behaviour succeeded, move onto the next one
50
- this.__currentBehaviour.finalize();
67
+ currentBehaviour.finalize();
51
68
 
69
+ this.__currentBehaviourState = BehaviorStatus.Initial;
52
70
  this.__currentBehaviourIndex++;
53
71
 
54
72
  if (this.__currentBehaviourIndex < this.__children.length) {
@@ -56,24 +74,31 @@ export class SequenceBehavior extends CompositeBehavior {
56
74
 
57
75
  this.__currentBehaviour.initialize(this.context);
58
76
 
77
+ this.__currentBehaviourState = BehaviorStatus.Running;
78
+
59
79
  return BehaviorStatus.Running;
60
80
  } else {
61
- this.__status = BehaviorStatus.Succeeded;
62
-
63
81
  //all behaviours completed
64
- return this.__status;
82
+ return BehaviorStatus.Succeeded;
65
83
  }
66
84
  }
67
85
 
68
86
  finalize() {
69
- if (this.__currentBehaviourIndex !== this.__children.length) {
87
+
88
+ const child_count = this.__children.length;
89
+
90
+ if (this.__currentBehaviourIndex !== child_count) {
70
91
  //sequence has not been finished
71
92
 
72
- if (this.__currentBehaviour !== undefined && this.__currentBehaviour.getStatus() !== BehaviorStatus.Initial) {
93
+ if (this.__currentBehaviour !== undefined && this.__currentBehaviourState !== BehaviorStatus.Initial) {
73
94
  this.__currentBehaviour.finalize();
74
95
  }
75
96
  }
76
- this.__status = BehaviorStatus.Initial;
97
+
98
+ this.__currentBehaviour = undefined;
99
+ this.__currentBehaviourIndex = child_count;
100
+
101
+ // console.warn('- SequenceBehavior');
77
102
  }
78
103
 
79
104
  /**
@@ -36,8 +36,6 @@ export class AbstractDecoratorBehavior extends Behavior {
36
36
  initialize(context) {
37
37
  super.initialize(context);
38
38
  this.__source.initialize(context);
39
-
40
- this.__status = this.__source.getStatus();
41
39
  }
42
40
 
43
41
  finalize() {
@@ -19,11 +19,9 @@ export class IgnoreFailureBehavior extends AbstractDecoratorBehavior {
19
19
  const behaviorStatus = this.__source.tick(timeDelta);
20
20
 
21
21
  if (behaviorStatus === BehaviorStatus.Failed) {
22
- this.setStatus(BehaviorStatus.Succeeded);
23
- } else {
24
- this.setStatus(behaviorStatus);
22
+ return BehaviorStatus.Succeeded;
25
23
  }
26
24
 
27
- return this.getStatus();
25
+ return behaviorStatus;
28
26
  }
29
27
  }
@@ -1,6 +1,8 @@
1
1
  import { Behavior } from "../Behavior.js";
2
2
  import { BehaviorStatus } from "../BehaviorStatus.js";
3
- import { ObjectBasedClassSerializationAdapter } from "../../../ecs/storage/binary/object/ObjectBasedClassSerializationAdapter.js";
3
+ import {
4
+ ObjectBasedClassSerializationAdapter
5
+ } from "../../../ecs/storage/binary/object/ObjectBasedClassSerializationAdapter.js";
4
6
  import { AbstractDecoratorBehavior } from "./AbstractDecoratorBehavior.js";
5
7
 
6
8
  /**
@@ -37,8 +39,6 @@ export class InverterBehavior extends AbstractDecoratorBehavior {
37
39
  r = BehaviorStatus.Succeeded;
38
40
  }
39
41
 
40
- this.__status = r;
41
-
42
42
  return r;
43
43
  }
44
44
  }
@@ -1,6 +1,5 @@
1
1
  import { Behavior } from "../Behavior.js";
2
2
  import { BehaviorStatus } from "../BehaviorStatus.js";
3
- import { ObjectBasedClassSerializationAdapter } from "../../../ecs/storage/binary/object/ObjectBasedClassSerializationAdapter.js";
4
3
  import { AbstractDecoratorBehavior } from "./AbstractDecoratorBehavior.js";
5
4
  import { assert } from "../../../../core/assert.js";
6
5
 
@@ -65,7 +64,6 @@ export class RepeatBehavior extends AbstractDecoratorBehavior {
65
64
  assert.enum(s, BehaviorStatus, 'status');
66
65
 
67
66
  if (s !== BehaviorStatus.Succeeded && s !== BehaviorStatus.Failed) {
68
- this.__status = s;
69
67
  return s;
70
68
  }
71
69
 
@@ -73,7 +71,6 @@ export class RepeatBehavior extends AbstractDecoratorBehavior {
73
71
  this.__iterator++;
74
72
 
75
73
  if (this.__iterator >= this.__limit) {
76
- this.__status = BehaviorStatus.Succeeded;
77
74
 
78
75
  return BehaviorStatus.Succeeded;
79
76
  } else {
@@ -87,35 +84,3 @@ export class RepeatBehavior extends AbstractDecoratorBehavior {
87
84
 
88
85
  RepeatBehavior.typeName = "RepeatBehavior";
89
86
 
90
- export class RepeatBehaviorSerializationAdapter extends ObjectBasedClassSerializationAdapter {
91
- constructor() {
92
- super();
93
-
94
- this.klass = RepeatBehavior;
95
- this.version = 0;
96
- }
97
-
98
- /**
99
- *
100
- * @param {BinaryBuffer} buffer
101
- * @param {RepeatBehavior} value
102
- */
103
- serialize(buffer, value) {
104
- buffer.writeUintVar(value.getCount());
105
-
106
- this.objectAdapter.serialize(buffer, value.getSource());
107
- }
108
-
109
- /**
110
- *
111
- * @param {BinaryBuffer} buffer
112
- * @param {RepeatBehavior} value
113
- */
114
- deserialize(buffer, value) {
115
- const count = buffer.readUintVar();
116
- const source = this.objectAdapter.deserialize(buffer);
117
-
118
- value.setCount(count);
119
- value.setSource(source);
120
- }
121
- }
@@ -6,11 +6,7 @@ import { jest } from '@jest/globals';
6
6
  test("initialization", () => {
7
7
  const b = new RepeatBehavior(new SucceedingBehavior(), 1);
8
8
 
9
- expect(b.getStatus()).toBe(BehaviorStatus.Initial);
10
-
11
9
  b.initialize();
12
-
13
- expect(b.getStatus()).toBe(BehaviorStatus.Running);
14
10
  });
15
11
 
16
12
  test('2 successful repetitions', () => {
@@ -23,12 +19,8 @@ test('2 successful repetitions', () => {
23
19
 
24
20
  b.initialize();
25
21
 
26
- expect(b.getStatus()).toBe(BehaviorStatus.Running);
27
-
28
22
  expect(b.tick(3)).toBe(BehaviorStatus.Running);
29
23
 
30
- expect(b.getStatus()).toBe(BehaviorStatus.Running);
31
-
32
24
  expect(tickSpy).toHaveBeenCalledTimes(1);
33
25
  expect(tickSpy).toHaveBeenCalledWith(3);
34
26
 
@@ -37,6 +29,4 @@ test('2 successful repetitions', () => {
37
29
 
38
30
  expect(tickSpy).toHaveBeenCalledTimes(2);
39
31
  expect(tickSpy).toHaveBeenLastCalledWith(7);
40
-
41
- expect(b.getStatus()).toBe(BehaviorStatus.Succeeded);
42
32
  });
@@ -0,0 +1,37 @@
1
+ import {
2
+ ObjectBasedClassSerializationAdapter
3
+ } from "../../../ecs/storage/binary/object/ObjectBasedClassSerializationAdapter.js";
4
+ import { RepeatBehavior } from "./RepeatBehavior.js";
5
+
6
+ export class RepeatBehaviorSerializationAdapter extends ObjectBasedClassSerializationAdapter {
7
+ constructor() {
8
+ super();
9
+
10
+ this.klass = RepeatBehavior;
11
+ this.version = 0;
12
+ }
13
+
14
+ /**
15
+ *
16
+ * @param {BinaryBuffer} buffer
17
+ * @param {RepeatBehavior} value
18
+ */
19
+ serialize(buffer, value) {
20
+ buffer.writeUintVar(value.getCount());
21
+
22
+ this.objectAdapter.serialize(buffer, value.getSource());
23
+ }
24
+
25
+ /**
26
+ *
27
+ * @param {BinaryBuffer} buffer
28
+ * @param {RepeatBehavior} value
29
+ */
30
+ deserialize(buffer, value) {
31
+ const count = buffer.readUintVar();
32
+ const source = this.objectAdapter.deserialize(buffer);
33
+
34
+ value.setCount(count);
35
+ value.setSource(source);
36
+ }
37
+ }
@@ -51,8 +51,6 @@ export class RepeatUntilFailureBehavior extends AbstractDecoratorBehavior {
51
51
 
52
52
  if (s !== BehaviorStatus.Succeeded) {
53
53
 
54
- this.__status = s;
55
-
56
54
  return s;
57
55
 
58
56
  }
@@ -60,7 +58,6 @@ export class RepeatUntilFailureBehavior extends AbstractDecoratorBehavior {
60
58
  this.__iterator++;
61
59
 
62
60
  if (this.__iterator >= this.__limit) {
63
- this.__status = BehaviorStatus.Succeeded;
64
61
 
65
62
  return BehaviorStatus.Succeeded;
66
63
  } else {
@@ -40,10 +40,10 @@ export class RepeatUntilSuccessBehavior extends AbstractDecoratorBehavior {
40
40
  * @return {RepeatUntilSuccessBehavior}
41
41
  */
42
42
  static from(source, limit = Infinity) {
43
- const r = new RepeatUntilSuccessBehavior();
44
-
45
- r.setSource(source);
46
- r.__limit = limit;
43
+ const r = new RepeatUntilSuccessBehavior(
44
+ source,
45
+ limit
46
+ );
47
47
 
48
48
  return r;
49
49
  }
@@ -52,9 +52,6 @@ export class RepeatUntilSuccessBehavior extends AbstractDecoratorBehavior {
52
52
  const s = this.__source.tick(timeDelta);
53
53
 
54
54
  if (s === BehaviorStatus.Succeeded) {
55
-
56
- this.__status = s;
57
-
58
55
  return s;
59
56
 
60
57
  } else if (s === BehaviorStatus.Running) {
@@ -64,9 +61,7 @@ export class RepeatUntilSuccessBehavior extends AbstractDecoratorBehavior {
64
61
  this.__iterator++;
65
62
 
66
63
  if (this.__iterator >= this.__limit) {
67
- this.__status = BehaviorStatus.Failed;
68
-
69
- return this.__status;
64
+ return BehaviorStatus.Failed;
70
65
  } else {
71
66
  //re-initialize the source behavior
72
67
  this.__source.initialize(this.context);
@@ -2,18 +2,15 @@ import { assert } from "../../../../core/assert.js";
2
2
  import { ClockChannelType } from "./ClockChannelType.js";
3
3
  import { RepeatBehavior } from "../decorator/RepeatBehavior.js";
4
4
  import { ActionBehavior } from "../primitive/ActionBehavior.js";
5
+ import { SequenceBehavior } from "../composite/SequenceBehavior.js";
5
6
 
6
7
  export const BehaviorComponentFlag = {
7
- AllowSleep: 1
8
+ AllowSleep: 1,
9
+ Resolved: 2
8
10
  };
9
11
 
10
12
  export class BehaviorComponent {
11
13
  constructor() {
12
- /**
13
- *
14
- * @type {Behavior[]}
15
- */
16
- this.list = [];
17
14
 
18
15
  /**
19
16
  *
@@ -26,6 +23,97 @@ export class BehaviorComponent {
26
23
  * @type {number}
27
24
  */
28
25
  this.flags = 0;
26
+
27
+ /**
28
+ *
29
+ * @type {Behavior|null}
30
+ * @private
31
+ */
32
+ this.__behavior = null;
33
+ }
34
+
35
+ /**
36
+ *
37
+ * @param {number|BehaviorComponentFlag} flag
38
+ * @returns {void}
39
+ */
40
+ setFlag(flag) {
41
+ this.flags |= flag;
42
+ }
43
+
44
+ /**
45
+ *
46
+ * @param {number|BehaviorComponentFlag} flag
47
+ * @returns {void}
48
+ */
49
+ clearFlag(flag) {
50
+ this.flags &= ~flag;
51
+ }
52
+
53
+ /**
54
+ *
55
+ * @param {number|BehaviorComponentFlag} flag
56
+ * @param {boolean} value
57
+ */
58
+ writeFlag(flag, value) {
59
+ if (value) {
60
+ this.setFlag(flag);
61
+ } else {
62
+ this.clearFlag(flag);
63
+ }
64
+ }
65
+
66
+ /**
67
+ *
68
+ * @param {number|BehaviorComponentFlag} flag
69
+ * @returns {boolean}
70
+ */
71
+ getFlag(flag) {
72
+ return (this.flags & flag) === flag;
73
+ }
74
+
75
+ /**
76
+ *
77
+ * @returns {Behavior|null}
78
+ */
79
+ get behavior() {
80
+ return this.__behavior;
81
+ }
82
+
83
+ /**
84
+ *
85
+ * @param {Behavior} v
86
+ */
87
+ set behavior(v) {
88
+ this.__behavior = v;
89
+ }
90
+
91
+ /**
92
+ * @deprecated
93
+ * @returns {Readonly<Behavior[]>}
94
+ */
95
+ get list() {
96
+ if (this.__behavior !== null) {
97
+ return [this.__behavior];
98
+ } else {
99
+ return [];
100
+ }
101
+ }
102
+
103
+ /**
104
+ * @deprecated
105
+ * @param {Behavior[]} v
106
+ */
107
+ set list(v) {
108
+ console.warn('.list is deprecated, use SequenceBehavior instead');
109
+ if (v.length > 1) {
110
+ console.warn('.list is deprecated, converting to sequence instead');
111
+ this.__behavior = SequenceBehavior.from(v);
112
+ } else if (v.length === 1) {
113
+ this.__behavior = v[0];
114
+ } else {
115
+ this.__behavior = null;
116
+ }
29
117
  }
30
118
 
31
119
 
@@ -53,7 +141,7 @@ export class BehaviorComponent {
53
141
 
54
142
  const result = new BehaviorComponent();
55
143
 
56
- result.list.push(b);
144
+ result.__behavior = b;
57
145
 
58
146
  return result;
59
147
 
@@ -1,5 +1,7 @@
1
1
  import { BinaryClassSerializationAdapter } from "../../../ecs/storage/binary/BinaryClassSerializationAdapter.js";
2
2
  import { BehaviorComponent } from "./BehaviorComponent.js";
3
+ import { SequenceBehavior } from "../composite/SequenceBehavior.js";
4
+ import { SucceedingBehavior } from "../primitive/SucceedingBehavior.js";
3
5
 
4
6
  export class BehaviorComponentSerializationAdapter extends BinaryClassSerializationAdapter {
5
7
  constructor() {
@@ -33,15 +35,13 @@ export class BehaviorComponentSerializationAdapter extends BinaryClassSerializat
33
35
  buffer.writeUint8(value.clock);
34
36
  buffer.writeUint8(value.flags);
35
37
 
36
- const behaviors = value.list;
37
- const n = behaviors.length;
38
- buffer.writeUintVar(n);
39
-
40
- for (let i = 0; i < n; i++) {
41
- const behavior = behaviors[i];
38
+ if (value.behavior !== null) {
39
+ buffer.writeUintVar(1);
42
40
 
43
41
  //write single behavior
44
- this.objectAdapter.serialize(buffer, behavior);
42
+ this.objectAdapter.serialize(buffer, value.behavior);
43
+ } else {
44
+ buffer.writeUintVar(0);
45
45
  }
46
46
  }
47
47
 
@@ -71,6 +71,13 @@ export class BehaviorComponentSerializationAdapter extends BinaryClassSerializat
71
71
  //write object fields
72
72
  value.clock = clock;
73
73
  value.flags = flags;
74
- value.list = behaviors;
74
+
75
+ if (behaviors.length > 1) {
76
+ value.behavior = SequenceBehavior.from(behaviors);
77
+ } else if (behaviors.length === 1) {
78
+ value.behavior = behaviors[0];
79
+ } else {
80
+ value.behavior = SucceedingBehavior.from(0);
81
+ }
75
82
  }
76
83
  }
@@ -1,25 +1,25 @@
1
1
  import { System } from "../../../ecs/System.js";
2
- import { BehaviorComponent } from "./BehaviorComponent.js";
2
+ import { BehaviorComponent, BehaviorComponentFlag } from "./BehaviorComponent.js";
3
3
  import { BehaviorStatus } from "../BehaviorStatus.js";
4
4
  import Clock from "../../../Clock.js";
5
5
  import { ClockChannelType } from "./ClockChannelType.js";
6
6
 
7
7
  /**
8
8
  *
9
- * @param {BehaviorStatus} behavior
9
+ * @param {Behavior} behavior
10
10
  * @param {number} timeDelta
11
+ * @returns {BehaviorStatus}
11
12
  */
12
13
  function updateBehavior(behavior, timeDelta) {
13
14
 
14
15
  try {
15
- behavior.tick(timeDelta);
16
+ return behavior.tick(timeDelta);
16
17
  } catch (e) {
17
18
  console.error('Behavior threw an exception', e);
18
19
 
19
20
  // Transition behavior into failed state
20
- behavior.setStatus(BehaviorStatus.Failed);
21
+ return BehaviorStatus.Failed;
21
22
  }
22
-
23
23
  }
24
24
 
25
25
  export class BehaviorSystem extends System {
@@ -60,24 +60,18 @@ export class BehaviorSystem extends System {
60
60
  * @param {number} entity
61
61
  */
62
62
  link(component, entity) {
63
+ const behavior = component.behavior;
64
+ component.clearFlag(BehaviorComponentFlag.Resolved);
63
65
 
64
- const list = component.list;
65
- const l = list.length;
66
-
67
- for (let i = 0; i < l; i++) {
68
- const behavior = list[i];
69
-
70
- if (behavior.getStatus() === BehaviorStatus.Initial) {
71
- // initialize behavior
72
- const dataset = this.entityManager.dataset;
66
+ if (behavior !== null) {
73
67
 
74
- try {
75
- behavior.initialize({ entity, ecd: dataset, engine: this.engine });
76
- } catch (e) {
77
- console.warn('Behavior initialization failed:', e);
68
+ // initialize behavior
69
+ const dataset = this.entityManager.dataset;
78
70
 
79
- behavior.setStatus(BehaviorStatus.Failed);
80
- }
71
+ try {
72
+ behavior.initialize({ entity, ecd: dataset, engine: this.engine });
73
+ } catch (e) {
74
+ console.warn('Behavior initialization failed:', e);
81
75
  }
82
76
  }
83
77
  }
@@ -88,17 +82,12 @@ export class BehaviorSystem extends System {
88
82
  * @param {number} entity
89
83
  */
90
84
  unlink(component, entity) {
85
+ const behavior = component.behavior;
91
86
 
92
- const list = component.list;
93
- const l = list.length;
94
-
95
- for (let i = 0; i < l; i++) {
96
- const behavior = list[i];
87
+ if (behavior !== null) {
97
88
 
98
- if (behavior.getStatus() === BehaviorStatus.Running) {
99
- // finalize behavior
100
- behavior.finalize();
101
- }
89
+ // finalize behavior
90
+ behavior.finalize();
102
91
  }
103
92
  }
104
93
 
@@ -118,8 +107,9 @@ export class BehaviorSystem extends System {
118
107
  * @param {number} entity
119
108
  */
120
109
  function visitBehavior(b, entity) {
121
- const list = b.list;
122
- const l = list.length;
110
+ if (b.getFlag(BehaviorComponentFlag.Resolved)) {
111
+ return;
112
+ }
123
113
 
124
114
  let td;
125
115
 
@@ -131,15 +121,16 @@ export class BehaviorSystem extends System {
131
121
  td = systemDelta;
132
122
  }
133
123
 
134
- for (let i = 0; i < l; i++) {
135
- const behavior = list[i];
124
+ const behavior = b.behavior;
136
125
 
137
- if (behavior.getStatus() !== BehaviorStatus.Running) {
138
- continue;
139
- }
126
+ if (behavior !== null) {
127
+ const state = updateBehavior(behavior, td);
140
128
 
141
- updateBehavior(behavior, td);
129
+ if (state === BehaviorStatus.Failed || state === BehaviorStatus.Succeeded) {
130
+ b.setFlag(BehaviorComponentFlag.Resolved);
131
+ }
142
132
  }
133
+
143
134
  }
144
135
 
145
136
  dataset.traverseComponents(BehaviorComponent, visitBehavior);