@zcomponent/core 1.29.0 → 2.0.0-alpha.2

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 (168) hide show
  1. package/README.md +1 -0
  2. package/css/zcomponent.css +121 -122
  3. package/index.js +0 -3
  4. package/lib/actionbehavior.d.ts +3 -3
  5. package/lib/actionbehavior.js +20 -19
  6. package/lib/animation/animation.d.ts +13 -6
  7. package/lib/animation/animation.js +56 -43
  8. package/lib/animation/bezier.d.ts +6 -0
  9. package/lib/animation/bezier.js +8 -2
  10. package/lib/animation/clips/clip.d.ts +13 -1
  11. package/lib/animation/clips/clip.js +34 -14
  12. package/lib/animation/index.d.ts +4 -4
  13. package/lib/animation/index.js +4 -4
  14. package/lib/animation/layer.d.ts +9 -0
  15. package/lib/animation/layer.js +28 -12
  16. package/lib/animation/layerclip.d.ts +21 -0
  17. package/lib/animation/layerclip.js +82 -45
  18. package/lib/animation/tracks/cliptrack.d.ts +18 -0
  19. package/lib/animation/tracks/cliptrack.js +27 -6
  20. package/lib/animation/tracks/functiontrack.d.ts +9 -0
  21. package/lib/animation/tracks/functiontrack.js +16 -3
  22. package/lib/animation/tracks/propertytrack.d.ts +20 -1
  23. package/lib/animation/tracks/propertytrack.js +48 -11
  24. package/lib/animation/tracks/streamtrack.d.ts +18 -0
  25. package/lib/animation/tracks/streamtrack.js +32 -6
  26. package/lib/animation/tracks/track.d.ts +8 -2
  27. package/lib/animation/tracks/track.js +3 -2
  28. package/lib/behavior.js +13 -10
  29. package/lib/behaviors/ActivateState.d.ts +22 -24
  30. package/lib/behaviors/ActivateState.js +145 -35
  31. package/lib/behaviors/CallFunction.d.ts +2 -4
  32. package/lib/behaviors/CallFunction.js +69 -11
  33. package/lib/behaviors/ChangeRootScene.d.ts +35 -0
  34. package/lib/behaviors/ChangeRootScene.js +123 -0
  35. package/lib/behaviors/ConsoleLog.d.ts +6 -5
  36. package/lib/behaviors/ConsoleLog.js +95 -12
  37. package/lib/behaviors/DownloadSnapshot.d.ts +7 -12
  38. package/lib/behaviors/DownloadSnapshot.js +70 -19
  39. package/lib/behaviors/EmitComponentPropEvent.d.ts +1 -3
  40. package/lib/behaviors/EmitComponentPropEvent.js +80 -12
  41. package/lib/behaviors/LaunchURL.d.ts +5 -5
  42. package/lib/behaviors/LaunchURL.js +92 -10
  43. package/lib/behaviors/LogAnalyticsEvent.d.ts +10 -4
  44. package/lib/behaviors/LogAnalyticsEvent.js +88 -7
  45. package/lib/behaviors/PauseLayerClip.d.ts +7 -9
  46. package/lib/behaviors/PauseLayerClip.js +89 -21
  47. package/lib/behaviors/PlayLayerClip.d.ts +35 -32
  48. package/lib/behaviors/PlayLayerClip.js +202 -48
  49. package/lib/behaviors/PlaySound.d.ts +19 -25
  50. package/lib/behaviors/PlaySound.js +122 -28
  51. package/lib/behaviors/SetLayerOff.d.ts +7 -9
  52. package/lib/behaviors/SetLayerOff.js +88 -21
  53. package/lib/behaviors/ShareSnapshot.d.ts +5 -9
  54. package/lib/behaviors/ShareSnapshot.js +70 -17
  55. package/lib/behaviors/ShowTextAlert.d.ts +16 -29
  56. package/lib/behaviors/ShowTextAlert.js +116 -48
  57. package/lib/behaviors/TakeSnapshot.d.ts +22 -26
  58. package/lib/behaviors/TakeSnapshot.js +131 -56
  59. package/lib/behaviors/ToggleLayerClips.d.ts +45 -62
  60. package/lib/behaviors/ToggleLayerClips.js +233 -64
  61. package/lib/behaviors/stream/PauseStream.d.ts +5 -16
  62. package/lib/behaviors/stream/PauseStream.js +94 -34
  63. package/lib/behaviors/stream/PlayStream.d.ts +14 -27
  64. package/lib/behaviors/stream/PlayStream.js +123 -34
  65. package/lib/behaviors/stream/SeekStream.d.ts +8 -18
  66. package/lib/behaviors/stream/SeekStream.js +97 -31
  67. package/lib/behaviors/stream/StopStream.d.ts +6 -15
  68. package/lib/behaviors/stream/StopStream.js +89 -27
  69. package/lib/component.d.ts +36 -13
  70. package/lib/component.js +237 -151
  71. package/lib/components/AnimatedLoader.d.ts +51 -0
  72. package/lib/components/AnimatedLoader.js +159 -0
  73. package/lib/components/Audio.d.ts +35 -37
  74. package/lib/components/Audio.js +264 -151
  75. package/lib/components/AudioLayerSettings.d.ts +13 -11
  76. package/lib/components/AudioLayerSettings.js +76 -18
  77. package/lib/components/Children.d.ts +2 -1
  78. package/lib/components/Children.js +66 -13
  79. package/lib/components/ConditionalConstruct.d.ts +44 -0
  80. package/lib/components/ConditionalConstruct.js +142 -0
  81. package/lib/components/DefaultCookieConsent.d.ts +53 -73
  82. package/lib/components/DefaultCookieConsent.js +382 -264
  83. package/lib/components/DefaultLoader.d.ts +40 -28
  84. package/lib/components/DefaultLoader.js +198 -46
  85. package/lib/components/Gamepad.d.ts +5 -26
  86. package/lib/components/Gamepad.js +201 -65
  87. package/lib/components/LoaderScope.d.ts +15 -0
  88. package/lib/components/LoaderScope.js +71 -0
  89. package/lib/components/LongLoad.d.ts +11 -15
  90. package/lib/components/LongLoad.js +89 -34
  91. package/lib/components/SnapshotUI.d.ts +19 -24
  92. package/lib/components/SnapshotUI.js +202 -105
  93. package/lib/context.d.ts +23 -5
  94. package/lib/context.js +12 -6
  95. package/lib/contexts/analyticscontext.d.ts +12 -2
  96. package/lib/contexts/analyticscontext.js +68 -10
  97. package/lib/contexts/audiocontextcontext.d.ts +1 -1
  98. package/lib/contexts/audiocontextcontext.js +9 -8
  99. package/lib/contexts/canvascontext.d.ts +32 -18
  100. package/lib/contexts/canvascontext.js +195 -120
  101. package/lib/contexts/cookieconsentcontext.d.ts +38 -28
  102. package/lib/contexts/cookieconsentcontext.js +35 -32
  103. package/lib/contexts/documentflagmanager.js +15 -11
  104. package/lib/contexts/environmentcontext.d.ts +22 -6
  105. package/lib/contexts/environmentcontext.js +135 -21
  106. package/lib/contexts/gamepadcontext.d.ts +29 -26
  107. package/lib/contexts/gamepadcontext.js +46 -46
  108. package/lib/contexts/gesturecontext.d.ts +31 -6
  109. package/lib/contexts/gesturecontext.js +110 -85
  110. package/lib/contexts/globaltagcontext.d.ts +1 -1
  111. package/lib/contexts/globaltagcontext.js +8 -11
  112. package/lib/contexts/loadcontext.d.ts +45 -8
  113. package/lib/contexts/loadcontext.js +232 -82
  114. package/lib/contexts/orientationcontext.d.ts +13 -15
  115. package/lib/contexts/orientationcontext.js +150 -67
  116. package/lib/contexts/rootcomponentscontext.d.ts +16 -0
  117. package/lib/contexts/rootcomponentscontext.js +65 -0
  118. package/lib/contexts/snapshotContext.d.ts +0 -3
  119. package/lib/contexts/snapshotContext.js +78 -23
  120. package/lib/contexts/tagcontext.d.ts +5 -5
  121. package/lib/contexts/tagcontext.js +16 -16
  122. package/lib/contexts/textalertcontext.d.ts +1 -5
  123. package/lib/contexts/textalertcontext.js +1 -5
  124. package/lib/contexts/usereventcontext.d.ts +1 -1
  125. package/lib/contexts/usereventcontext.js +12 -12
  126. package/lib/data/animation.d.ts +10 -2
  127. package/lib/data/change.d.ts +1 -1
  128. package/lib/data/change.js +7 -0
  129. package/lib/data/core.d.ts +9 -1
  130. package/lib/data/index.d.ts +1 -1
  131. package/lib/data/index.js +1 -1
  132. package/lib/decorators.d.ts +348 -0
  133. package/lib/decorators.js +239 -0
  134. package/lib/decoratorutils.d.ts +3 -0
  135. package/lib/decoratorutils.js +8 -0
  136. package/lib/emitter.d.ts +15 -2
  137. package/lib/emitter.js +15 -6
  138. package/lib/entity.d.ts +43 -25
  139. package/lib/entity.js +104 -71
  140. package/lib/event.d.ts +2 -1
  141. package/lib/event.js +1 -4
  142. package/lib/groups.d.ts +18 -0
  143. package/lib/groups.js +19 -0
  144. package/lib/icons.d.ts +3372 -0
  145. package/lib/icons.js +1 -0
  146. package/lib/index.d.ts +18 -13
  147. package/lib/index.js +17 -13
  148. package/lib/inflate.d.ts +7 -7
  149. package/lib/inflate.js +5 -5
  150. package/lib/observable.d.ts +9 -2
  151. package/lib/observable.js +5 -4
  152. package/lib/observe.d.ts +18 -0
  153. package/lib/observe.js +177 -0
  154. package/lib/profile.d.ts +9 -5
  155. package/lib/profile.js +27 -17
  156. package/lib/selectors.d.ts +1 -1
  157. package/lib/selectors.js +5 -4
  158. package/lib/types.d.ts +161 -19
  159. package/lib/types.js +22 -1
  160. package/lib/values/values.d.ts +7 -8
  161. package/lib/values/values.js +1 -2
  162. package/lib/values/valuesmutator.d.ts +4 -1
  163. package/lib/values/valuesmutator.js +10 -8
  164. package/lib/zcomponent.d.ts +21 -10
  165. package/lib/zcomponent.js +717 -540
  166. package/package.json +22 -5
  167. package/lib/behaviors/ChangeCursor.d.ts +0 -39
  168. package/lib/behaviors/ChangeCursor.js +0 -44
package/lib/zcomponent.js CHANGED
@@ -1,3 +1,37 @@
1
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
2
+ var useValue = arguments.length > 2;
3
+ for (var i = 0; i < initializers.length; i++) {
4
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
5
+ }
6
+ return useValue ? value : void 0;
7
+ };
8
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
9
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
10
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
11
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
12
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
13
+ var _, done = false;
14
+ for (var i = decorators.length - 1; i >= 0; i--) {
15
+ var context = {};
16
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
17
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
18
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
19
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
20
+ if (kind === "accessor") {
21
+ if (result === void 0) continue;
22
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
23
+ if (_ = accept(result.get)) descriptor.get = _;
24
+ if (_ = accept(result.set)) descriptor.set = _;
25
+ if (_ = accept(result.init)) initializers.unshift(_);
26
+ }
27
+ else if (_ = accept(result)) {
28
+ if (kind === "field") initializers.unshift(_);
29
+ else descriptor[key] = _;
30
+ }
31
+ }
32
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
33
+ done = true;
34
+ };
1
35
  /* eslint-disable @typescript-eslint/no-this-alias */
2
36
  import { Animation } from './animation/index';
3
37
  import { Behavior, shouldBehaviorRunAtDesignTime } from './behavior';
@@ -6,15 +40,20 @@ import { Context } from './context';
6
40
  import { useOnBeforeRender } from './contexts/canvascontext';
7
41
  import { isDesignTime } from './contexts/environmentcontext';
8
42
  import { isStarted, started } from './contexts/loadcontext';
43
+ import { RootComponentsContext } from './contexts/rootcomponentscontext';
9
44
  import { TagContext } from './contexts/tagcontext';
10
45
  import { computeBehaviorHierarchy, computeNodeHierarchy } from './data';
46
+ import { EntityPropOverrideType, FunctionCallType } from './data/core';
47
+ import { zIgnore } from './decorators';
11
48
  import { Entity } from './entity';
49
+ import { Event } from './event';
12
50
  import { populateAnimationStructureFromData, populateAnimationTracksFromData, updateClipFromData } from './inflate';
13
- import { EntityPropOverrideType, FunctionCallType } from './data/core';
14
51
  import { Observable } from './observable';
52
+ import { reset as resetObservable } from './observe';
15
53
  import { setCurrentZComponentConstruction } from './zcomponentconstruction';
16
- import { Event } from './event';
17
54
  export class ZComponentContext extends Context {
55
+ zcomponent;
56
+ children;
18
57
  /**
19
58
  * Creates an instance of ZComponentContext.
20
59
  * @param contextManager - The current ContextManager
@@ -26,630 +65,768 @@ export class ZComponentContext extends Context {
26
65
  this.children = props.children;
27
66
  }
28
67
  }
29
- export class ZComponent extends Component {
30
- /**
31
- * Creates an instance of ZComponent.
32
- * @param contextManager - The current ContextManager
33
- * @param constructorProps - The constructor properties.
34
- * @param _opts - The options for the component.
35
- */
36
- constructor(contextManager, constructorProps, _opts) {
37
- super(contextManager, { ...constructorProps, children: [] });
38
- this.constructorProps = constructorProps;
39
- this._opts = _opts;
68
+ let ZComponent = (() => {
69
+ let _classSuper = Component;
70
+ let _instanceExtraInitializers = [];
71
+ let _animation_decorators;
72
+ let _animation_initializers = [];
73
+ let _animation_extraInitializers = [];
74
+ let _resolveNodeID_decorators;
75
+ let _resolveBehaviorID_decorators;
76
+ let _resolveEntityID_decorators;
77
+ let _notifyPropsChanged_decorators;
78
+ let _notifyClipsChanged_decorators;
79
+ let _resolveStreamID_decorators;
80
+ let _traverse_decorators;
81
+ return class ZComponent extends _classSuper {
82
+ static {
83
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
84
+ _animation_decorators = [zIgnore()];
85
+ _resolveNodeID_decorators = [zIgnore()];
86
+ _resolveBehaviorID_decorators = [zIgnore()];
87
+ _resolveEntityID_decorators = [zIgnore()];
88
+ _notifyPropsChanged_decorators = [zIgnore()];
89
+ _notifyClipsChanged_decorators = [zIgnore()];
90
+ _resolveStreamID_decorators = [zIgnore()];
91
+ _traverse_decorators = [zIgnore()];
92
+ __esDecorate(this, null, _resolveNodeID_decorators, { kind: "method", name: "resolveNodeID", static: false, private: false, access: { has: obj => "resolveNodeID" in obj, get: obj => obj.resolveNodeID }, metadata: _metadata }, null, _instanceExtraInitializers);
93
+ __esDecorate(this, null, _resolveBehaviorID_decorators, { kind: "method", name: "resolveBehaviorID", static: false, private: false, access: { has: obj => "resolveBehaviorID" in obj, get: obj => obj.resolveBehaviorID }, metadata: _metadata }, null, _instanceExtraInitializers);
94
+ __esDecorate(this, null, _resolveEntityID_decorators, { kind: "method", name: "resolveEntityID", static: false, private: false, access: { has: obj => "resolveEntityID" in obj, get: obj => obj.resolveEntityID }, metadata: _metadata }, null, _instanceExtraInitializers);
95
+ __esDecorate(this, null, _notifyPropsChanged_decorators, { kind: "method", name: "notifyPropsChanged", static: false, private: false, access: { has: obj => "notifyPropsChanged" in obj, get: obj => obj.notifyPropsChanged }, metadata: _metadata }, null, _instanceExtraInitializers);
96
+ __esDecorate(this, null, _notifyClipsChanged_decorators, { kind: "method", name: "notifyClipsChanged", static: false, private: false, access: { has: obj => "notifyClipsChanged" in obj, get: obj => obj.notifyClipsChanged }, metadata: _metadata }, null, _instanceExtraInitializers);
97
+ __esDecorate(this, null, _resolveStreamID_decorators, { kind: "method", name: "resolveStreamID", static: false, private: false, access: { has: obj => "resolveStreamID" in obj, get: obj => obj.resolveStreamID }, metadata: _metadata }, null, _instanceExtraInitializers);
98
+ __esDecorate(this, null, _traverse_decorators, { kind: "method", name: "traverse", static: false, private: false, access: { has: obj => "traverse" in obj, get: obj => obj.traverse }, metadata: _metadata }, null, _instanceExtraInitializers);
99
+ __esDecorate(null, null, _animation_decorators, { kind: "field", name: "animation", static: false, private: false, access: { has: obj => "animation" in obj, get: obj => obj.animation, set: (obj, value) => { obj.animation = value; } }, metadata: _metadata }, _animation_initializers, _animation_extraInitializers);
100
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
101
+ }
102
+ constructorProps = __runInitializers(this, _instanceExtraInitializers);
103
+ _opts;
104
+ /**
105
+ * The id of the component.
106
+ */
107
+ id;
40
108
  /**
41
109
  * A map of elements to node IDs.
42
110
  */
43
- this.idByElement = new Map();
111
+ idByElement = new Map();
44
112
  /**
45
113
  * Object that maps node script names to scripts.
114
+ * @default {}
46
115
  */
47
- this.nodes = {};
116
+ nodes = {};
48
117
  /**
49
118
  * Map of entites by ID.
50
119
  */
51
- this.entityByID = new Map();
120
+ entityByID = new Map();
52
121
  /**
53
122
  * A map of entity labels to components.
54
123
  */
55
- this.entityByLabel = new Map();
124
+ entityByLabel = new Map();
56
125
  /**
57
126
  * A map of node labels to components.
58
127
  */
59
- this.nodeByLabel = new Map();
128
+ nodeByLabel = new Map();
129
+ _constructedResolve;
60
130
  /**
61
131
  * A promise that is resolved once construction of this component is complete.
62
132
  */
63
- this.constructed = new Promise(resolve => (this._constructedResolve = resolve));
133
+ constructed = new Promise(resolve => {
134
+ this._constructedResolve = resolve;
135
+ });
136
+ /**
137
+ * @default false
138
+ */
139
+ _isConstructed = false;
64
140
  /**
65
141
  * A boolean indicating if construction of this component is complete.
66
142
  */
67
- this.isConstructed = false;
143
+ get isConstructed() {
144
+ return this._isConstructed;
145
+ }
68
146
  /**
69
147
  * The animation object for this component.
148
+ * @zignore
70
149
  */
71
- this.animation = new Animation(false);
150
+ animation = __runInitializers(this, _animation_initializers, new Animation(false));
72
151
  /**
73
152
  * @zstreams layerclipids
153
+ * @default {}
154
+ */
155
+ streams = (__runInitializers(this, _animation_extraInitializers), {});
156
+ _nodesById = new Map();
157
+ /**
158
+ * @default []
74
159
  */
75
- this.streams = {};
76
- this._nodesById = new Map();
77
- this._behaviorsToInitialize = [];
78
- this._constructorPropOverridesByEntityID = new Map();
79
- this._updateAnimationRegistrations = () => {
160
+ _behaviorsToInitialize = [];
161
+ _constructorPropOverridesByEntityID = new Map();
162
+ /**
163
+ * Creates an instance of ZComponent.
164
+ * @param contextManager - The current ContextManager
165
+ * @param constructorProps - The constructor properties.
166
+ * @param _opts - The options for the component.
167
+ */
168
+ constructor(contextManager, constructorProps, _opts) {
169
+ super(contextManager, { ...constructorProps, children: [] });
170
+ this.constructorProps = constructorProps;
171
+ this._opts = _opts;
172
+ const contextManagerForChildren = contextManager.forkMultiple([ZComponentContext, { zcomponent: this }], [TagContext, {}])[0];
173
+ this.id = this._opts.data.id;
174
+ this._initializeConstructorPropOverrides();
175
+ if (this._opts.data.animation)
176
+ populateAnimationStructureFromData(this, this.animation, this._opts.data.animation);
177
+ const rootConstructor = this._constructorForNode(this._opts.data.root);
178
+ if (rootConstructor) {
179
+ this.constructChildren([[rootConstructor, {}]], contextManagerForChildren);
180
+ }
181
+ this._constructTopLevelComponents();
182
+ this._inflateBehaviors();
183
+ this._initializeComponentProps();
184
+ this._initializeOverrides();
185
+ if (this._opts.data.animation)
186
+ populateAnimationTracksFromData(this, this.animation, this._opts.data.animation);
187
+ this.animation.initialize();
188
+ for (const layerClip of this.animation.layerClipByID.values()) {
189
+ if (layerClip.id)
190
+ this.streams[layerClip.id] = layerClip;
191
+ }
192
+ this._isConstructed = true;
193
+ this._constructedResolve();
194
+ started(contextManager).then(() => {
195
+ this._updateAnimationRegistrations();
196
+ if (!isDesignTime(contextManager))
197
+ this.animation.start();
198
+ });
199
+ this.register(this.animation.hasLayers, this._updateAnimationRegistrations, { bindWhenDisabled: true });
200
+ }
201
+ _updateAnimationRegistrations = () => {
80
202
  if (this.animation.hasLayers && isStarted(this.contextManager) && !this.disposed)
81
203
  this.register(useOnBeforeRender(this.contextManager), this._animationTick);
82
204
  else
83
205
  this.unregister(useOnBeforeRender(this.contextManager), this._animationTick);
84
206
  };
85
- this._animationTick = () => {
207
+ _animationTick = () => {
86
208
  this.animation.tick();
87
209
  };
88
- const contextManagerForChildren = contextManager.forkMultiple([ZComponentContext, { zcomponent: this }], [TagContext, {}])[0];
89
- this.id = this._opts.data.id;
90
- this._initializeConstructorPropOverrides();
91
- if (this._opts.data.animation)
92
- populateAnimationStructureFromData(this, this.animation, this._opts.data.animation);
93
- const rootConstructor = this._constructorForNode(this._opts.data.root);
94
- if (rootConstructor) {
95
- this.constructChildren([[rootConstructor, {}]], contextManagerForChildren);
96
- }
97
- this._inflateBehaviors();
98
- this._initializeComponentProps();
99
- this._initializeOverrides();
100
- if (this._opts.data.animation)
101
- populateAnimationTracksFromData(this, this.animation, this._opts.data.animation);
102
- this.animation.initialize();
103
- for (const layerClip of this.animation.layerClipByID.values()) {
104
- if (layerClip.id)
105
- this.streams[layerClip.id] = layerClip;
106
- }
107
- this.isConstructed = true;
108
- this._constructedResolve();
109
- started(contextManager).then(() => {
110
- this._updateAnimationRegistrations();
111
- if (!isDesignTime(contextManager))
112
- this.animation.start();
113
- });
114
- this.register(this.animation.hasLayers, this._updateAnimationRegistrations, { bindWhenDisabled: true });
115
- }
116
- _constructorForNode(nodeId) {
117
- const node = this._opts.data.nodes[nodeId];
118
- if (!node) {
119
- console.log('Warning - unable to find node with ID', nodeId);
120
- return;
121
- }
122
- const construct = this._opts.importMapping[node.type]?.();
123
- if (!construct) {
124
- console.log('Warning - unable to find constructor for type', node.type);
125
- return;
126
- }
127
- const that = this;
128
- return class extends construct {
129
- /**
130
- * Creates an instance of the component.
131
- * @param contextManager - The current ContextManager
132
- * @param constructorProps - The constructor properties.
133
- */
134
- constructor(contextManager, constructorProps) {
135
- that._opts.onConstructingNode?.(nodeId);
136
- const children = constructorProps.children ?? [];
137
- const childIDs = computeNodeHierarchy(that._opts.data.nodes)[nodeId] ?? [];
138
- for (const childID of childIDs) {
139
- const childInstance = that._constructorForNode(childID);
140
- if (childInstance)
141
- children.push([childInstance, {}]);
142
- }
143
- constructorProps = {
144
- ...constructorProps,
145
- ...(that._opts.data.entityConstructorProps?.[nodeId] ?? {}),
146
- ...(that._opts.constructorPropReplacement?.[nodeId] ?? {}),
147
- ...(that._constructorPropOverridesByEntityID.get(nodeId) ?? {}),
148
- children,
149
- };
150
- setCurrentZComponentConstruction(that);
151
- super(contextManager, constructorProps);
152
- this.locked = that._opts.data.nodes[nodeId]?.locked;
153
- that.entityByID.set(nodeId, this);
154
- if (node?.label) {
155
- that.entityByLabel.set(node.label, this);
156
- that.nodeByLabel.set(node.label, this);
157
- if (this.element)
158
- this.element['__zlabel'] = node.label;
159
- }
160
- that._nodesById.set(nodeId, this);
161
- for (const element of this.elementsResolved) {
162
- that.idByElement.set(element, nodeId);
163
- }
164
- if (node?.scriptName) {
165
- const entriesForScriptName = that._opts.data.entitiesByScriptName?.[node.scriptName] ?? {};
166
- let moreThanOne = false;
167
- for (const entry in entriesForScriptName) {
168
- if (entry !== node.id) {
169
- moreThanOne = true;
170
- break;
171
- }
210
+ _constructorForNode(nodeId) {
211
+ const node = this._opts.data.nodes[nodeId];
212
+ if (!node) {
213
+ console.log('Warning - unable to find node with ID', nodeId);
214
+ return;
215
+ }
216
+ if ((node.excludeDesignTime && isDesignTime(this.contextManager)) || (node.excludeRuntime && !isDesignTime(this.contextManager))) {
217
+ return;
218
+ }
219
+ const construct = this._opts.importMapping[node.type]?.();
220
+ if (!construct) {
221
+ console.log('Warning - unable to find constructor for type', node.type);
222
+ return;
223
+ }
224
+ const that = this;
225
+ return class extends construct {
226
+ /**
227
+ * Creates an instance of the component.
228
+ * @param contextManager - The current ContextManager
229
+ * @param constructorProps - The constructor properties.
230
+ */
231
+ constructor(contextManager, constructorProps) {
232
+ that._opts.onConstructingNode?.(nodeId);
233
+ const children = constructorProps.children ?? [];
234
+ const childIDs = computeNodeHierarchy(that._opts.data.nodes)[nodeId] ?? [];
235
+ for (const childID of childIDs) {
236
+ const childInstance = that._constructorForNode(childID);
237
+ if (childInstance)
238
+ children.push([childInstance, {}]);
172
239
  }
173
- if (moreThanOne) {
174
- const current = that.nodes[node.scriptName] ?? {};
175
- that.nodes[node.scriptName] = current;
176
- current[node.id] = this;
240
+ constructorProps = {
241
+ ...constructorProps,
242
+ ...(that._opts.data.entityConstructorProps?.[nodeId] ?? {}),
243
+ ...(that._opts.constructorPropReplacement?.[nodeId] ?? {}),
244
+ ...(that._constructorPropOverridesByEntityID.get(nodeId) ?? {}),
245
+ children,
246
+ };
247
+ setCurrentZComponentConstruction(that);
248
+ super(contextManager, constructorProps);
249
+ this.locked = that._opts.data.nodes[nodeId]?.locked;
250
+ that.entityByID.set(nodeId, this);
251
+ if (node?.label) {
252
+ that.entityByLabel.set(node.label, this);
253
+ that.nodeByLabel.set(node.label, this);
254
+ if (this.element)
255
+ this.element['__zlabel'] = node.label;
177
256
  }
178
- else {
179
- that.nodes[node.scriptName] = this;
257
+ that._nodesById.set(nodeId, this);
258
+ for (const element of this.elementsResolved) {
259
+ that.idByElement.set(element, nodeId);
180
260
  }
181
- }
182
- that._behaviorsToInitialize.push([nodeId, this, this.contextManager]);
183
- const props = {
184
- ...(that._opts.data.entityProps?.[nodeId] ?? {}),
185
- ...(that._opts.propReplacement?.[nodeId] ?? {}),
186
- // TOOD add forwarded props
187
- };
188
- for (const [key, val] of Object.entries(props)) {
189
- try {
190
- that._setEntityProp(this, key, val);
261
+ if (node?.scriptName) {
262
+ const entriesForScriptName = that._opts.data.entitiesByScriptName?.[node.scriptName] ?? {};
263
+ let moreThanOne = false;
264
+ for (const entry in entriesForScriptName) {
265
+ if (entry !== node.id) {
266
+ moreThanOne = true;
267
+ break;
268
+ }
269
+ }
270
+ if (moreThanOne) {
271
+ const current = that.nodes[node.scriptName] ?? {};
272
+ that.nodes[node.scriptName] = current;
273
+ current[node.id] = this;
274
+ }
275
+ else {
276
+ that.nodes[node.scriptName] = this;
277
+ }
191
278
  }
192
- catch (err) {
193
- console.log('Warning - unable to set entity prop', key, val);
279
+ that._behaviorsToInitialize.push([nodeId, this, this.contextManager]);
280
+ const props = {
281
+ ...(that._opts.data.entityProps?.[nodeId] ?? {}),
282
+ ...(that._opts.propReplacement?.[nodeId] ?? {}),
283
+ // TOOD add forwarded props
284
+ };
285
+ for (const [key, val] of Object.entries(props)) {
286
+ try {
287
+ that._setEntityProp(this, key, val);
288
+ }
289
+ catch (err) {
290
+ console.log('Warning - unable to set entity prop', key, val);
291
+ }
194
292
  }
293
+ that._opts.onConstructingNode?.(undefined);
294
+ if (that.isConstructed)
295
+ that._inflateBehaviors();
195
296
  }
196
- that._opts.onConstructingNode?.(undefined);
197
- if (that.isConstructed)
198
- that._inflateBehaviors();
199
- }
200
- dispose() {
201
- that.entityByID.delete(nodeId);
202
- if (node.label)
203
- that.entityByLabel.delete(node.label);
204
- that._nodesById.delete(nodeId);
205
- for (const element of this.elementsResolved) {
206
- that.idByElement.delete(element);
297
+ dispose() {
298
+ that.entityByID.delete(nodeId);
299
+ if (node.label)
300
+ that.entityByLabel.delete(node.label);
301
+ that._nodesById.delete(nodeId);
302
+ for (const element of this.elementsResolved) {
303
+ that.idByElement.delete(element);
304
+ }
305
+ return super.dispose();
207
306
  }
208
- return super.dispose();
209
- }
210
- };
211
- }
212
- _constructorForBehavior(behaviorId) {
213
- const node = this._opts.data.behaviors[behaviorId];
214
- if (!node) {
215
- console.log('Warning - unable to find behavior with ID', behaviorId);
216
- return;
217
- }
218
- const construct = this._opts.importMapping[node.type]?.();
219
- if (!construct) {
220
- console.log('Warning - unable to find constructor for type', node.type);
221
- return;
307
+ };
222
308
  }
223
- const designTime = isDesignTime(this.contextManager);
224
- if (designTime && !shouldBehaviorRunAtDesignTime(construct))
225
- return;
226
- const that = this;
227
- return class extends construct {
228
- /**
229
- * Creates an instance of the behavior.
230
- * @param contextManager - The current ContextManager
231
- * @param instance - The instance of the component that this behavior is attached to
232
- * @param constructorProps - The constructor properties.
233
- */
234
- constructor(contextManager, instance, constructorProps) {
235
- constructorProps = {
236
- ...constructorProps,
237
- ...(that._opts.data.entityConstructorProps?.[behaviorId] ?? {}),
238
- ...(that._opts.constructorPropReplacement?.[behaviorId] ?? {}),
239
- ...(that._constructorPropOverridesByEntityID.get(behaviorId) ?? {}),
240
- };
241
- for (const key in constructorProps) {
242
- const val = constructorProps[key];
243
- if (val !== undefined && val !== null && val['_zfn'] === true)
244
- constructorProps[key] = that._wrapFunctionCall(val);
245
- }
246
- setCurrentZComponentConstruction(that);
247
- super(contextManager, instance, constructorProps);
248
- that.entityByID.set(behaviorId, this);
249
- if (node?.parent?.scriptName)
250
- instance.behaviors[node.parent.scriptName] = this;
251
- const props = {
252
- ...(that._opts.data.entityProps?.[behaviorId] ?? {}),
253
- ...(that._opts.propReplacement?.[behaviorId] ?? {}),
254
- // TOOD add forwarded props
255
- };
256
- for (const [key, val] of Object.entries(props)) {
257
- try {
258
- that._setEntityProp(this, key, val);
309
+ _constructorForBehavior(behaviorId) {
310
+ const node = this._opts.data.behaviors[behaviorId];
311
+ if (!node) {
312
+ console.log('Warning - unable to find behavior with ID', behaviorId);
313
+ return;
314
+ }
315
+ const construct = this._opts.importMapping[node.type]?.();
316
+ if (!construct) {
317
+ console.log('Warning - unable to find constructor for type', node.type);
318
+ return;
319
+ }
320
+ const designTime = isDesignTime(this.contextManager);
321
+ if (designTime && !shouldBehaviorRunAtDesignTime(construct))
322
+ return;
323
+ const that = this;
324
+ return class extends construct {
325
+ /**
326
+ * Creates an instance of the behavior.
327
+ * @param contextManager - The current ContextManager
328
+ * @param instance - The instance of the component that this behavior is attached to
329
+ * @param constructorProps - The constructor properties.
330
+ */
331
+ constructor(contextManager, instance, constructorProps) {
332
+ constructorProps = {
333
+ ...constructorProps,
334
+ ...(that._opts.data.entityConstructorProps?.[behaviorId] ?? {}),
335
+ ...(that._opts.constructorPropReplacement?.[behaviorId] ?? {}),
336
+ ...(that._constructorPropOverridesByEntityID.get(behaviorId) ?? {}),
337
+ };
338
+ for (const key in constructorProps) {
339
+ const val = constructorProps[key];
340
+ if (val !== undefined && val !== null && val['_zfn'] === true)
341
+ constructorProps[key] = that._wrapFunctionCall(val);
259
342
  }
260
- catch (err) {
261
- console.log('Warning - unable to set entity prop', key, val);
343
+ setCurrentZComponentConstruction(that);
344
+ super(contextManager, instance, constructorProps);
345
+ that.entityByID.set(behaviorId, this);
346
+ if (node?.parent?.scriptName)
347
+ instance.behaviors[node.parent.scriptName] = this;
348
+ const props = {
349
+ ...(that._opts.data.entityProps?.[behaviorId] ?? {}),
350
+ ...(that._opts.propReplacement?.[behaviorId] ?? {}),
351
+ // TOOD add forwarded props
352
+ };
353
+ for (const [key, val] of Object.entries(props)) {
354
+ try {
355
+ that._setEntityProp(this, key, val);
356
+ }
357
+ catch (err) {
358
+ console.log('Warning - unable to set entity prop', key, val);
359
+ }
262
360
  }
263
361
  }
362
+ dispose() {
363
+ that.entityByID.delete(behaviorId);
364
+ if (node?.parent?.scriptName)
365
+ delete this.instance.behaviors[node.parent.scriptName];
366
+ return super.dispose();
367
+ }
368
+ };
369
+ }
370
+ /**
371
+ * This function returns the component with the given ID. If the component is not found, it will return undefined.
372
+ * This function is used to get a component from a node ID, which is a string representation of a node.
373
+ * The node ID is used to identify a node in the graph.
374
+ * If a component constructor is passed as `type`, this function will ensure that the node that's returned
375
+ * is an instance of that component, or return undefined if it is not.
376
+ */
377
+ resolveNodeID(id, type) {
378
+ const entity = this.entityByID.get(id);
379
+ try {
380
+ if (!entity)
381
+ return this.getZComponentInstance()?.resolveNodeID(id, type);
264
382
  }
265
- dispose() {
266
- that.entityByID.delete(behaviorId);
267
- if (node?.parent?.scriptName)
268
- delete this.instance.behaviors[node.parent.scriptName];
269
- return super.dispose();
383
+ catch (err) {
384
+ return undefined;
270
385
  }
271
- };
272
- }
273
- /**
274
- * This function returns the component with the given ID. If the component is not found, it will return undefined.
275
- * This function is used to get a component from a node ID, which is a string representation of a node.
276
- * The node ID is used to identify a node in the graph.
277
- * If a component constructor is passed as `type`, this function will ensure that the node that's returned
278
- * is an instance of that component, or return undefined if it is not.
279
- */
280
- resolveNodeID(id, type) {
281
- const entity = this.entityByID.get(id);
282
- try {
283
- if (!entity)
284
- return this.getZComponentInstance()?.resolveNodeID(id, type);
285
- }
286
- catch (err) {
287
- return undefined;
288
- }
289
- if (!(entity instanceof Component))
290
- return undefined;
291
- if (!type)
292
- return entity;
293
- if (entity instanceof type)
294
- return entity;
295
- return undefined;
296
- }
297
- /**
298
- * This function returns the behavior with the given ID. If the behavior is not found, it will return undefined.
299
- * This function is used to get a behavior from a behavior ID, which is a string representation of a behavior.
300
- */
301
- resolveBehaviorID(id, type) {
302
- const entity = this.entityByID.get(id);
303
- try {
304
- if (!entity)
305
- return this.getZComponentInstance()?.resolveBehaviorID(id, type);
306
- }
307
- catch (err) {
308
- return undefined;
309
- }
310
- if (!(entity instanceof Behavior))
311
- return undefined;
312
- if (!type)
313
- return entity;
314
- if (entity instanceof type)
315
- return entity;
316
- return undefined;
317
- }
318
- /**
319
- * Resolves an entity ID to an entity instance.
320
- *
321
- * @param id - The ID of the entity to resolve.
322
- * @returns The resolved entity as an instance of T (which extends Entity), or undefined if the entity could not be resolved.
323
- * @template T The entity type.
324
- */
325
- resolveEntityID(id) {
326
- const entity = this.entityByID.get(id);
327
- try {
328
- if (!entity)
329
- return this.getZComponentInstance()?.resolveEntityID(id);
330
- }
331
- catch (err) {
386
+ if (!(entity instanceof Component))
387
+ return undefined;
388
+ if (!type)
389
+ return entity;
390
+ if (entity instanceof type)
391
+ return entity;
332
392
  return undefined;
333
393
  }
334
- if (!(entity instanceof Entity))
394
+ /**
395
+ * This function returns the behavior with the given ID. If the behavior is not found, it will return undefined.
396
+ * This function is used to get a behavior from a behavior ID, which is a string representation of a behavior.
397
+ */
398
+ resolveBehaviorID(id, type) {
399
+ const entity = this.entityByID.get(id);
400
+ try {
401
+ if (!entity)
402
+ return this.getZComponentInstance()?.resolveBehaviorID(id, type);
403
+ }
404
+ catch (err) {
405
+ return undefined;
406
+ }
407
+ if (!(entity instanceof Behavior))
408
+ return undefined;
409
+ if (!type)
410
+ return entity;
411
+ if (entity instanceof type)
412
+ return entity;
335
413
  return undefined;
336
- return entity;
337
- }
338
- _inflateBehaviors() {
339
- for (const [nodeID, impl, ctx] of this._behaviorsToInitialize) {
340
- this._wrapBehaviors(nodeID, impl, ctx);
341
414
  }
342
- this._behaviorsToInitialize = [];
343
- }
344
- _wrapBehaviors(nodeID, impl, ctx) {
345
- const behaviors = computeBehaviorHierarchy(this._opts.data.behaviors)[nodeID] ?? [];
346
- for (const behaviorID of behaviors) {
415
+ /**
416
+ * Resolves an entity ID to an entity instance.
417
+ *
418
+ * @param id - The ID of the entity to resolve.
419
+ * @returns The resolved entity as an instance of T (which extends Entity), or undefined if the entity could not be resolved.
420
+ * @template T The entity type.
421
+ */
422
+ resolveEntityID(id) {
423
+ const entity = this.entityByID.get(id);
347
424
  try {
348
- const constructor = this._constructorForBehavior(behaviorID);
349
- if (constructor)
350
- new constructor(ctx, impl);
425
+ if (!entity)
426
+ return this.getZComponentInstance()?.resolveEntityID(id);
351
427
  }
352
428
  catch (err) {
353
- const nodeName = this._opts.data.nodes[nodeID]?.label ?? 'Unknown node';
354
- const behaviorType = this._opts.data.behaviors[behaviorID]?.type;
355
- console.log('An error occurred when constructing behavior of type:', behaviorType, 'for node:', nodeName, err);
429
+ return undefined;
356
430
  }
431
+ if (!(entity instanceof Entity))
432
+ return undefined;
433
+ return entity;
357
434
  }
358
- }
359
- _wrapFunctionCall(c) {
360
- switch (c.t) {
361
- case FunctionCallType.Context:
362
- return () => {
363
- try {
364
- if (typeof c.imp !== 'string' || typeof c.fn !== 'string' || typeof c.args !== 'object')
365
- throw new Error('Invalid function call data');
366
- const contextConstructor = c.resolved;
367
- if (!contextConstructor)
368
- throw new Error('Unable to find context');
369
- const context = this.contextManager.get(contextConstructor);
370
- if (!context)
371
- throw new Error('Unable to get context');
372
- const func = context[c.fn];
373
- if (!func || typeof func !== 'function')
374
- throw new Error('Unable to find function on enttiy');
375
- const tf = func;
376
- const converted = [];
377
- for (const key in c.args)
378
- converted[key] = c.args[key];
379
- return tf.call(context, ...converted);
380
- }
381
- catch (err) {
382
- console.error('Unable to call context function', err);
383
- }
384
- };
385
- case FunctionCallType.Entity:
386
- return () => {
387
- try {
388
- if (typeof c.entityID !== 'string' || typeof c.fn !== 'string' || typeof c.args !== 'object')
389
- throw new Error('Invalid function call data');
390
- const entity = this.resolveEntityID(c.entityID);
391
- if (!entity)
392
- throw new Error('Unable to find entity');
393
- const func = entity[c.fn];
394
- if (!func || typeof func !== 'function')
395
- throw new Error('Unable to find function on enttiy');
396
- const tf = func;
397
- const converted = [];
398
- for (const key in c.args)
399
- converted[key] = c.args[key];
400
- return tf.call(entity, ...converted);
401
- }
402
- catch (err) {
403
- console.error('Unable to call entity function', err);
404
- }
405
- };
406
- case FunctionCallType.EmitComponentEvent:
407
- return () => {
408
- try {
409
- if (typeof c.prop !== 'string' || typeof c.args !== 'object')
410
- throw new Error('Invalid function call data');
411
- const evt = this[c.prop];
412
- if (!evt)
413
- throw new Error('Unable to find component event');
414
- if (!(evt instanceof Event))
415
- throw new Error('Component property is not an event');
416
- const converted = [];
417
- for (const key in c.args)
418
- converted[key] = c.args[key];
419
- evt.emit.call(evt, ...converted);
420
- }
421
- catch (err) {
422
- console.error('Unable to emit component event', err);
423
- }
424
- };
435
+ _inflateBehaviors() {
436
+ for (const [nodeID, impl, ctx] of this._behaviorsToInitialize) {
437
+ this._wrapBehaviors(nodeID, impl, ctx);
438
+ }
439
+ this._behaviorsToInitialize = [];
425
440
  }
426
- }
427
- /**
428
- * Notifies the component that the properties of certain entities have changed.
429
- *
430
- * @param entries - A map where the keys are entity IDs and the values are sets of property names.
431
- */
432
- notifyPropsChanged(entries) {
433
- for (const [entityID, propSet] of entries.entries()) {
434
- const entity = this.entityByID.get(entityID);
435
- if (!entity)
436
- continue;
437
- for (const prop of propSet.values()) {
441
+ _wrapBehaviors(nodeID, impl, ctx) {
442
+ const behaviors = computeBehaviorHierarchy(this._opts.data.behaviors)[nodeID] ?? [];
443
+ for (const behaviorID of behaviors) {
438
444
  try {
439
- this._setEntityProp(entity, prop, this._opts.data.entityProps[entityID]?.[prop]);
440
- this.animation.clearCachedDefault(entityID, prop);
445
+ const _constructor = this._constructorForBehavior(behaviorID);
446
+ if (_constructor)
447
+ new _constructor(ctx, impl);
441
448
  }
442
449
  catch (err) {
443
- console.log('Warning - unable to set prop', entityID, prop);
450
+ const nodeName = this._opts.data.nodes[nodeID]?.label ?? 'Unknown node';
451
+ const behaviorType = this._opts.data.behaviors[behaviorID]?.type;
452
+ console.log('An error occurred when constructing behavior of type:', behaviorType, 'for node:', nodeName, err);
444
453
  }
445
454
  }
446
455
  }
447
- }
448
- /**
449
- * The animation editor will call this function when the user changes
450
- * the list of clips in the animation. We need to update the clip
451
- * data for each clip that was changed.
452
- */
453
- notifyClipsChanged(clips) {
454
- for (const clipId of clips.values()) {
455
- const clip = this.animation.clipByID.get(clipId);
456
- const clipData = this._opts.data.animation?.clips?.[clipId];
457
- if (!clip || !clipData)
458
- continue;
459
- updateClipFromData(this, clip, clipData);
456
+ _wrapFunctionCall(c) {
457
+ switch (c.t) {
458
+ case FunctionCallType.Context:
459
+ return () => {
460
+ try {
461
+ if (typeof c.imp !== 'string' || typeof c.fn !== 'string' || typeof c.args !== 'object')
462
+ throw new Error('Invalid function call data');
463
+ const contextConstructor = c.resolved;
464
+ if (!contextConstructor)
465
+ throw new Error('Unable to find context');
466
+ const context = this.contextManager.get(contextConstructor);
467
+ if (!context)
468
+ throw new Error('Unable to get context');
469
+ const func = context[c.fn];
470
+ if (!func || typeof func !== 'function')
471
+ throw new Error('Unable to find function on enttiy');
472
+ const tf = func;
473
+ const converted = [];
474
+ for (const key in c.args)
475
+ converted[key] = c.args[key];
476
+ return tf.call(context, ...converted);
477
+ }
478
+ catch (err) {
479
+ console.error('Unable to call context function', err);
480
+ }
481
+ };
482
+ case FunctionCallType.Entity:
483
+ return () => {
484
+ try {
485
+ if (typeof c.entityID !== 'string' || typeof c.fn !== 'string' || typeof c.args !== 'object')
486
+ throw new Error('Invalid function call data');
487
+ const entity = this.resolveEntityID(c.entityID);
488
+ if (!entity)
489
+ throw new Error('Unable to find entity');
490
+ const func = entity[c.fn];
491
+ if (!func || typeof func !== 'function')
492
+ throw new Error('Unable to find function on enttiy');
493
+ const tf = func;
494
+ const converted = [];
495
+ for (const key in c.args)
496
+ converted[key] = c.args[key];
497
+ return tf.call(entity, ...converted);
498
+ }
499
+ catch (err) {
500
+ console.error('Unable to call entity function', err);
501
+ }
502
+ };
503
+ case FunctionCallType.EmitComponentEvent:
504
+ return () => {
505
+ try {
506
+ if (typeof c.prop !== 'string' || typeof c.args !== 'object')
507
+ throw new Error('Invalid function call data');
508
+ const evt = this[c.prop];
509
+ if (!evt)
510
+ throw new Error('Unable to find component event');
511
+ if (!(evt instanceof Event))
512
+ throw new Error('Component property is not an event');
513
+ const converted = [];
514
+ for (const key in c.args)
515
+ converted[key] = c.args[key];
516
+ evt.emit.call(evt, ...converted);
517
+ }
518
+ catch (err) {
519
+ console.error('Unable to emit component event', err);
520
+ }
521
+ };
522
+ }
460
523
  }
461
- }
462
- _initializeOverrides() {
463
- const overrides = this._opts.data.entityPropOverrides ?? {};
464
- for (const override of Object.values(overrides)) {
465
- const entity = this.entityByID.get(override.entityID);
466
- if (!entity)
467
- continue;
468
- try {
469
- switch (override.type) {
470
- case EntityPropOverrideType.Import: {
471
- const v = this._opts.importMapping[override.imp]?.();
472
- if (!v)
473
- continue;
474
- if (v instanceof Observable)
475
- this.register(v, val => this._setEntityPropPath(entity, override.entityPropPath, val), { bindWhenDisabled: true });
476
- else
477
- this._setEntityPropPath(entity, override.entityPropPath, v);
478
- break;
524
+ /**
525
+ * Notifies the component that the properties of certain entities have changed.
526
+ *
527
+ * @param entries - A map where the keys are entity IDs and the values are sets of property names.
528
+ */
529
+ notifyPropsChanged(entries) {
530
+ for (const [entityID, propSet] of entries.entries()) {
531
+ const entity = this.entityByID.get(entityID);
532
+ if (!entity)
533
+ continue;
534
+ for (const prop of propSet.values()) {
535
+ try {
536
+ this._setEntityProp(entity, prop, this._opts.data.entityProps[entityID]?.[prop]);
537
+ this.animation.clearCachedDefault(entityID, prop);
479
538
  }
480
- case EntityPropOverrideType.ContextValue: {
481
- const ctx = this._opts.importMapping[override.imp]?.();
482
- const ctxInstance = entity.contextManager.getOrThrow(ctx);
483
- const v = ctxInstance[override.val];
484
- if (!v)
485
- continue;
486
- if (v instanceof Observable)
487
- this.register(v, val => this._setEntityPropPath(entity, override.entityPropPath, val), { bindWhenDisabled: true });
488
- else
489
- this._setEntityPropPath(entity, override.entityPropPath, v);
490
- break;
539
+ catch (err) {
540
+ console.log('Warning - unable to set prop', entityID, prop);
491
541
  }
492
- case EntityPropOverrideType.ComponentProp: {
493
- if (override.isConstructorProp) {
494
- const prop = this._opts.data.constructorProps?.[override.propName];
495
- if (!prop)
542
+ }
543
+ }
544
+ }
545
+ /**
546
+ * The animation editor will call this function when the user changes
547
+ * the list of clips in the animation. We need to update the clip
548
+ * data for each clip that was changed.
549
+ */
550
+ notifyClipsChanged(clips) {
551
+ for (const clipId of clips.values()) {
552
+ const clip = this.animation.clipByID.get(clipId);
553
+ const clipData = this._opts.data.animation?.clips?.[clipId];
554
+ if (!clip || !clipData)
555
+ continue;
556
+ updateClipFromData(this, clip, clipData);
557
+ }
558
+ }
559
+ _initializeOverrides() {
560
+ const overrides = this._opts.data.entityPropOverrides ?? {};
561
+ for (const override of Object.values(overrides)) {
562
+ const entity = this.entityByID.get(override.entityID);
563
+ if (!entity)
564
+ continue;
565
+ try {
566
+ switch (override.type) {
567
+ case EntityPropOverrideType.Import: {
568
+ const v = this._opts.importMapping[override.imp]?.();
569
+ if (!v)
570
+ continue;
571
+ if (v instanceof Observable)
572
+ this.register(v, val => this._setEntityPropPath(entity, override.entityPropPath, val), { bindWhenDisabled: true });
573
+ else
574
+ this._setEntityPropPath(entity, override.entityPropPath, v);
575
+ break;
576
+ }
577
+ case EntityPropOverrideType.ContextValue: {
578
+ const ctx = this._opts.importMapping[override.imp]?.();
579
+ const ctxInstance = entity.contextManager.getOrThrow(ctx);
580
+ const v = ctxInstance[override.val];
581
+ if (!v)
582
+ continue;
583
+ if (v instanceof Observable)
584
+ this.register(v, val => this._setEntityPropPath(entity, override.entityPropPath, val), { bindWhenDisabled: true });
585
+ else
586
+ this._setEntityPropPath(entity, override.entityPropPath, v);
587
+ break;
588
+ }
589
+ case EntityPropOverrideType.ComponentProp: {
590
+ if (override.isConstructorProp) {
591
+ const prop = this._opts.data.constructorProps?.[override.propName];
592
+ if (!prop)
593
+ break;
594
+ const val = this.constructorProps[override.propName] ?? prop.default;
595
+ if (val !== undefined)
596
+ this._setEntityPropPath(entity, override.entityPropPath, val);
496
597
  break;
497
- const val = this.constructorProps[override.propName] ?? prop.default;
498
- if (val !== undefined)
499
- this._setEntityPropPath(entity, override.entityPropPath, val);
598
+ }
599
+ const v = this[override.propName];
600
+ if (!v)
601
+ continue;
602
+ if (v instanceof Observable)
603
+ this.register(v, val => this._setEntityPropPath(entity, override.entityPropPath, val), { bindWhenDisabled: true });
604
+ else
605
+ this._setEntityPropPath(entity, override.entityPropPath, v);
500
606
  break;
501
607
  }
502
- const v = this[override.propName];
503
- if (!v)
504
- continue;
505
- if (v instanceof Observable)
506
- this.register(v, val => this._setEntityPropPath(entity, override.entityPropPath, val), { bindWhenDisabled: true });
507
- else
508
- this._setEntityPropPath(entity, override.entityPropPath, v);
509
- break;
510
608
  }
511
609
  }
610
+ catch (err) {
611
+ console.log('Unable to set entity prop override', err);
612
+ }
512
613
  }
513
- catch (err) {
514
- console.log('Unable to set entity prop override', err);
614
+ }
615
+ _initializeConstructorPropOverrides() {
616
+ for (const entry of Object.values(this._opts.data.entityPropOverrides ?? {})) {
617
+ if (entry.type !== EntityPropOverrideType.ComponentProp)
618
+ continue;
619
+ if (!entry.isConstructorProp)
620
+ continue;
621
+ if (entry.entityPropPath.length !== 1)
622
+ continue;
623
+ const obj = this._constructorPropOverridesByEntityID.get(entry.entityID) ?? Object.create(null);
624
+ this._constructorPropOverridesByEntityID.set(entry.entityID, obj);
625
+ const prop = this._opts.data.constructorProps?.[entry.propName];
626
+ if (!prop)
627
+ continue;
628
+ const val = this.constructorProps[entry.propName] ?? prop.default;
629
+ if (val !== undefined)
630
+ obj[entry.entityPropPath[0]] = val;
515
631
  }
516
632
  }
517
- }
518
- _initializeConstructorPropOverrides() {
519
- for (const entry of Object.values(this._opts.data.entityPropOverrides ?? {})) {
520
- if (entry.type !== EntityPropOverrideType.ComponentProp)
521
- continue;
522
- if (!entry.isConstructorProp)
523
- continue;
524
- if (entry.entityPropPath.length !== 1)
525
- continue;
526
- const obj = this._constructorPropOverridesByEntityID.get(entry.entityID) ?? Object.create(null);
527
- this._constructorPropOverridesByEntityID.set(entry.entityID, obj);
528
- const prop = this._opts.data.constructorProps?.[entry.propName];
529
- if (!prop)
530
- continue;
531
- const val = this.constructorProps[entry.propName] ?? prop.default;
532
- if (val !== undefined)
533
- obj[entry.entityPropPath[0]] = val;
633
+ _initializeComponentProps() {
634
+ const componentProps = this._opts.data.props ?? {};
635
+ for (const prop of Object.values(componentProps)) {
636
+ if (prop.type.name === 'event')
637
+ this[prop.name] = new Event();
638
+ else
639
+ this[prop.name] = new Observable(prop.default);
640
+ }
534
641
  }
535
- }
536
- _initializeComponentProps() {
537
- const componentProps = this._opts.data.props ?? {};
538
- for (const prop of Object.values(componentProps)) {
539
- if (prop.type.name === 'event')
540
- this[prop.name] = new Event();
642
+ _setEntityProp(entity, prop, v) {
643
+ if (v !== undefined && v !== null && v['_zfn'] === true)
644
+ v = this._wrapFunctionCall(v);
645
+ if (v === undefined && resetObservable(entity, prop))
646
+ return;
647
+ if (entity[prop] instanceof Observable)
648
+ entity[prop].value = v;
541
649
  else
542
- this[prop.name] = new Observable(prop.default);
650
+ entity[prop] = v;
543
651
  }
544
- }
545
- _setEntityProp(entity, prop, v) {
546
- if (v !== undefined && v !== null && v['_zfn'] === true)
547
- v = this._wrapFunctionCall(v);
548
- if (entity[prop] instanceof Observable)
549
- entity[prop].value = v;
550
- else
551
- entity[prop] = v;
552
- }
553
- _setEntityPropPath(entity, propPath, v) {
554
- if (propPath.length < 1)
555
- return;
556
- const prop = propPath[0];
557
- let parent = entity;
558
- let currentKey = prop;
559
- if (entity[prop] instanceof Observable) {
560
- parent = entity[prop];
561
- currentKey = 'value';
652
+ _setEntityPropPath(entity, propPath, v) {
653
+ if (propPath.length < 1)
654
+ return;
655
+ const prop = propPath[0];
656
+ let parent = entity;
657
+ let currentKey = prop;
658
+ if (entity[prop] instanceof Observable) {
659
+ parent = entity[prop];
660
+ currentKey = 'value';
661
+ }
662
+ for (let i = 1; i < propPath.length; i++) {
663
+ parent = parent[currentKey];
664
+ currentKey = propPath[i];
665
+ }
666
+ if (v !== undefined && v !== null && v['_zfn'] === true)
667
+ v = this._wrapFunctionCall(v);
668
+ parent[currentKey] = v;
562
669
  }
563
- for (let i = 1; i < propPath.length; i++) {
564
- parent = parent[currentKey];
565
- currentKey = propPath[i];
670
+ /**
671
+ * Returns the node with the specified ID.
672
+ */
673
+ _getNodeById(id) {
674
+ return this._nodesById.get(id);
566
675
  }
567
- if (v !== undefined && v !== null && v['_zfn'] === true)
568
- v = this._wrapFunctionCall(v);
569
- parent[currentKey] = v;
570
- }
571
- /**
572
- * Returns the node with the specified ID.
573
- */
574
- _getNodeById(id) {
575
- return this._nodesById.get(id);
576
- }
577
- /**
578
- * Rsolves a stream ID to a stream object. The stream ID is a string that
579
- * is constructed from the entity ID of the stream's parent entity, followed by a
580
- * period, followed by the name of the stream. This function splits the string into
581
- * parts, and then uses the parts to traverse the entity tree until it finds the
582
- * named stream.
583
- */
584
- resolveStreamID(id) {
585
- const parts = id.split('.');
586
- let obj = this.entityByID.get(parts[0]);
587
- if (!obj)
588
- return undefined;
589
- for (let i = 1; i < parts.length; i++) {
676
+ /**
677
+ * Rsolves a stream ID to a stream object. The stream ID is a string that
678
+ * is constructed from the entity ID of the stream's parent entity, followed by a
679
+ * period, followed by the name of the stream. This function splits the string into
680
+ * parts, and then uses the parts to traverse the entity tree until it finds the
681
+ * named stream.
682
+ */
683
+ resolveStreamID(id) {
684
+ const parts = id.split('.');
685
+ let obj = this.entityByID.get(parts[0]);
590
686
  if (!obj)
591
687
  return undefined;
592
- obj = obj[parts[i]];
593
- }
594
- return obj;
595
- }
596
- /**
597
- * Traverses the component tree starting from the current component,
598
- * moving down the tree using either Breadth-First Search (BFS) or Depth-First Search (DFS),
599
- * and invokes the given callback function on each component.
600
- *
601
- * Breadth-first chosen for traversal can be specifying `true` for the second parameter
602
- *
603
- * Example usage:
604
- * ```
605
- * component.traverse((comp) => {
606
- * // Your logic here, e.g.
607
- * console.log(comp.name);
608
- * }, true);
609
- * ```
610
- *
611
- * @param callback A function that will be called for each component in the traversal. The current component is passed as a parameter to the callback.
612
- * @param breadthFirst If traversal should be breadth-first. Defaults to `false` (depth-first).
613
- */
614
- traverse(callback, breadthFirst = false) {
615
- if (breadthFirst) {
616
- this._traverseBFS(callback);
617
- }
618
- else {
619
- this._traverseDFS(callback);
688
+ for (let i = 1; i < parts.length; i++) {
689
+ if (!obj)
690
+ return undefined;
691
+ obj = obj[parts[i]];
692
+ }
693
+ return obj;
620
694
  }
621
- }
622
- _traverseBFS(callback) {
623
- const queue = [this];
624
- while (queue.length > 0) {
625
- const currentComponent = queue.shift();
626
- if (currentComponent) {
627
- callback(currentComponent);
628
- queue.push(...currentComponent.children);
695
+ /**
696
+ * Traverses the component tree starting from the current component,
697
+ * moving down the tree using either Breadth-First Search (BFS) or Depth-First Search (DFS),
698
+ * and invokes the given callback function on each component.
699
+ *
700
+ * Breadth-first chosen for traversal can be specifying `true` for the second parameter
701
+ *
702
+ * Example usage:
703
+ * ```
704
+ * component.traverse((comp) => {
705
+ * // Your logic here, e.g.
706
+ * console.log(comp.name);
707
+ * }, true);
708
+ * ```
709
+ *
710
+ * @param callback A function that will be called for each component in the traversal. The current component is passed as a parameter to the callback.
711
+ * @param breadthFirst If traversal should be breadth-first. Defaults to `false` (depth-first).
712
+ */
713
+ traverse(callback, breadthFirst = false) {
714
+ if (breadthFirst) {
715
+ this._traverseBFS(callback);
716
+ }
717
+ else {
718
+ this._traverseDFS(callback);
629
719
  }
630
720
  }
631
- }
632
- _traverseDFS(callback) {
633
- const dfs = (comp) => {
634
- if (comp) {
635
- callback(comp);
636
- comp.children.forEach(dfs);
721
+ _traverseBFS(callback) {
722
+ const queue = [this];
723
+ while (queue.length > 0) {
724
+ const currentComponent = queue.shift();
725
+ if (currentComponent) {
726
+ callback(currentComponent);
727
+ queue.push(...currentComponent.children);
728
+ }
637
729
  }
638
- };
639
- dfs(this);
640
- }
641
- dispose() {
642
- this.animation.dispose();
643
- for (const entity of this.entityByID.values()) {
644
- if (entity && typeof entity.dispose === 'function') {
645
- try {
646
- entity.dispose();
730
+ }
731
+ _traverseDFS(callback) {
732
+ const dfs = (comp) => {
733
+ if (comp) {
734
+ callback(comp);
735
+ comp.children.forEach(dfs);
647
736
  }
648
- catch (err) {
649
- // Ignore
737
+ };
738
+ dfs(this);
739
+ }
740
+ _constructTopLevelComponents() {
741
+ if (!this._opts.data.topLevelComponents)
742
+ return;
743
+ for (const nodeId of Object.keys(this._opts.data.topLevelComponents)) {
744
+ const node = this._opts.data.nodes[nodeId];
745
+ if (!node) {
746
+ console.log('Warning - unable to find node with ID', nodeId);
747
+ return;
748
+ }
749
+ if ((node.excludeDesignTime && isDesignTime(this.contextManager)) || (node.excludeRuntime && !isDesignTime(this.contextManager))) {
750
+ return;
751
+ }
752
+ const construct = this._opts.importMapping[node.type]?.();
753
+ if (!construct) {
754
+ console.log('Warning - unable to find constructor for type', node.type);
755
+ return;
756
+ }
757
+ const instance = this.contextManager.get(RootComponentsContext).lockTopLevelComponent(construct, {
758
+ ...(this._opts.data.entityConstructorProps?.[nodeId] ?? {}),
759
+ ...(this._opts.constructorPropReplacement?.[nodeId] ?? {}),
760
+ children: [],
761
+ }, this);
762
+ this.entityByID.set(nodeId, instance);
763
+ if (node?.label) {
764
+ this.entityByLabel.set(node.label, instance);
765
+ this.nodeByLabel.set(node.label, instance);
766
+ }
767
+ this._nodesById.set(nodeId, instance);
768
+ for (const element of instance.elementsResolved) {
769
+ this.idByElement.set(element, nodeId);
770
+ }
771
+ if (node?.scriptName) {
772
+ const entriesForScriptName = this._opts.data.entitiesByScriptName?.[node.scriptName] ?? {};
773
+ let moreThanOne = false;
774
+ for (const entry in entriesForScriptName) {
775
+ if (entry !== node.id) {
776
+ moreThanOne = true;
777
+ break;
778
+ }
779
+ }
780
+ if (moreThanOne) {
781
+ const current = this.nodes[node.scriptName] ?? {};
782
+ this.nodes[node.scriptName] = current;
783
+ current[node.id] = instance;
784
+ }
785
+ else {
786
+ this.nodes[node.scriptName] = instance;
787
+ }
788
+ }
789
+ this._behaviorsToInitialize.push([nodeId, instance, this.contextManager]);
790
+ const props = {
791
+ ...(this._opts.data.entityProps?.[nodeId] ?? {}),
792
+ ...(this._opts.propReplacement?.[nodeId] ?? {}),
793
+ };
794
+ for (const [key, val] of Object.entries(props)) {
795
+ try {
796
+ this._setEntityProp(instance, key, val);
797
+ }
798
+ catch (err) {
799
+ console.log('Warning - unable to set entity prop', key, val);
800
+ }
650
801
  }
651
802
  }
652
803
  }
653
- return super.dispose();
654
- }
655
- }
804
+ dispose() {
805
+ this.animation.dispose();
806
+ for (const [id, entity] of this.entityByID.entries()) {
807
+ if (this._opts.data.topLevelComponents?.[id])
808
+ continue;
809
+ if (entity && typeof entity.dispose === 'function') {
810
+ try {
811
+ entity.dispose();
812
+ }
813
+ catch (err) {
814
+ // Ignore
815
+ }
816
+ }
817
+ }
818
+ // Unlock top-level components
819
+ for (const nodeId of Object.keys(this._opts.data.topLevelComponents ?? {})) {
820
+ const node = this._opts.data.nodes[nodeId];
821
+ if (!node)
822
+ continue;
823
+ const construct = this._opts.importMapping[node.type]?.();
824
+ if (!construct)
825
+ continue;
826
+ this.contextManager.get(RootComponentsContext).unlockTopLevelComponent(construct, this);
827
+ }
828
+ return super.dispose();
829
+ }
830
+ };
831
+ })();
832
+ export { ZComponent };