@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.
- package/README.md +1 -0
- package/css/zcomponent.css +121 -122
- package/index.js +0 -3
- package/lib/actionbehavior.d.ts +3 -3
- package/lib/actionbehavior.js +20 -19
- package/lib/animation/animation.d.ts +13 -6
- package/lib/animation/animation.js +56 -43
- package/lib/animation/bezier.d.ts +6 -0
- package/lib/animation/bezier.js +8 -2
- package/lib/animation/clips/clip.d.ts +13 -1
- package/lib/animation/clips/clip.js +34 -14
- package/lib/animation/index.d.ts +4 -4
- package/lib/animation/index.js +4 -4
- package/lib/animation/layer.d.ts +9 -0
- package/lib/animation/layer.js +28 -12
- package/lib/animation/layerclip.d.ts +21 -0
- package/lib/animation/layerclip.js +82 -45
- package/lib/animation/tracks/cliptrack.d.ts +18 -0
- package/lib/animation/tracks/cliptrack.js +27 -6
- package/lib/animation/tracks/functiontrack.d.ts +9 -0
- package/lib/animation/tracks/functiontrack.js +16 -3
- package/lib/animation/tracks/propertytrack.d.ts +20 -1
- package/lib/animation/tracks/propertytrack.js +48 -11
- package/lib/animation/tracks/streamtrack.d.ts +18 -0
- package/lib/animation/tracks/streamtrack.js +32 -6
- package/lib/animation/tracks/track.d.ts +8 -2
- package/lib/animation/tracks/track.js +3 -2
- package/lib/behavior.js +13 -10
- package/lib/behaviors/ActivateState.d.ts +22 -24
- package/lib/behaviors/ActivateState.js +145 -35
- package/lib/behaviors/CallFunction.d.ts +2 -4
- package/lib/behaviors/CallFunction.js +69 -11
- package/lib/behaviors/ChangeRootScene.d.ts +35 -0
- package/lib/behaviors/ChangeRootScene.js +123 -0
- package/lib/behaviors/ConsoleLog.d.ts +6 -5
- package/lib/behaviors/ConsoleLog.js +95 -12
- package/lib/behaviors/DownloadSnapshot.d.ts +7 -12
- package/lib/behaviors/DownloadSnapshot.js +70 -19
- package/lib/behaviors/EmitComponentPropEvent.d.ts +1 -3
- package/lib/behaviors/EmitComponentPropEvent.js +80 -12
- package/lib/behaviors/LaunchURL.d.ts +5 -5
- package/lib/behaviors/LaunchURL.js +92 -10
- package/lib/behaviors/LogAnalyticsEvent.d.ts +10 -4
- package/lib/behaviors/LogAnalyticsEvent.js +88 -7
- package/lib/behaviors/PauseLayerClip.d.ts +7 -9
- package/lib/behaviors/PauseLayerClip.js +89 -21
- package/lib/behaviors/PlayLayerClip.d.ts +35 -32
- package/lib/behaviors/PlayLayerClip.js +202 -48
- package/lib/behaviors/PlaySound.d.ts +19 -25
- package/lib/behaviors/PlaySound.js +122 -28
- package/lib/behaviors/SetLayerOff.d.ts +7 -9
- package/lib/behaviors/SetLayerOff.js +88 -21
- package/lib/behaviors/ShareSnapshot.d.ts +5 -9
- package/lib/behaviors/ShareSnapshot.js +70 -17
- package/lib/behaviors/ShowTextAlert.d.ts +16 -29
- package/lib/behaviors/ShowTextAlert.js +116 -48
- package/lib/behaviors/TakeSnapshot.d.ts +22 -26
- package/lib/behaviors/TakeSnapshot.js +131 -56
- package/lib/behaviors/ToggleLayerClips.d.ts +45 -62
- package/lib/behaviors/ToggleLayerClips.js +233 -64
- package/lib/behaviors/stream/PauseStream.d.ts +5 -16
- package/lib/behaviors/stream/PauseStream.js +94 -34
- package/lib/behaviors/stream/PlayStream.d.ts +14 -27
- package/lib/behaviors/stream/PlayStream.js +123 -34
- package/lib/behaviors/stream/SeekStream.d.ts +8 -18
- package/lib/behaviors/stream/SeekStream.js +97 -31
- package/lib/behaviors/stream/StopStream.d.ts +6 -15
- package/lib/behaviors/stream/StopStream.js +89 -27
- package/lib/component.d.ts +36 -13
- package/lib/component.js +237 -151
- package/lib/components/AnimatedLoader.d.ts +51 -0
- package/lib/components/AnimatedLoader.js +159 -0
- package/lib/components/Audio.d.ts +35 -37
- package/lib/components/Audio.js +264 -151
- package/lib/components/AudioLayerSettings.d.ts +13 -11
- package/lib/components/AudioLayerSettings.js +76 -18
- package/lib/components/Children.d.ts +2 -1
- package/lib/components/Children.js +66 -13
- package/lib/components/ConditionalConstruct.d.ts +44 -0
- package/lib/components/ConditionalConstruct.js +142 -0
- package/lib/components/DefaultCookieConsent.d.ts +53 -73
- package/lib/components/DefaultCookieConsent.js +382 -264
- package/lib/components/DefaultLoader.d.ts +40 -28
- package/lib/components/DefaultLoader.js +198 -46
- package/lib/components/Gamepad.d.ts +5 -26
- package/lib/components/Gamepad.js +201 -65
- package/lib/components/LoaderScope.d.ts +15 -0
- package/lib/components/LoaderScope.js +71 -0
- package/lib/components/LongLoad.d.ts +11 -15
- package/lib/components/LongLoad.js +89 -34
- package/lib/components/SnapshotUI.d.ts +19 -24
- package/lib/components/SnapshotUI.js +202 -105
- package/lib/context.d.ts +23 -5
- package/lib/context.js +12 -6
- package/lib/contexts/analyticscontext.d.ts +12 -2
- package/lib/contexts/analyticscontext.js +68 -10
- package/lib/contexts/audiocontextcontext.d.ts +1 -1
- package/lib/contexts/audiocontextcontext.js +9 -8
- package/lib/contexts/canvascontext.d.ts +32 -18
- package/lib/contexts/canvascontext.js +195 -120
- package/lib/contexts/cookieconsentcontext.d.ts +38 -28
- package/lib/contexts/cookieconsentcontext.js +35 -32
- package/lib/contexts/documentflagmanager.js +15 -11
- package/lib/contexts/environmentcontext.d.ts +22 -6
- package/lib/contexts/environmentcontext.js +135 -21
- package/lib/contexts/gamepadcontext.d.ts +29 -26
- package/lib/contexts/gamepadcontext.js +46 -46
- package/lib/contexts/gesturecontext.d.ts +31 -6
- package/lib/contexts/gesturecontext.js +110 -85
- package/lib/contexts/globaltagcontext.d.ts +1 -1
- package/lib/contexts/globaltagcontext.js +8 -11
- package/lib/contexts/loadcontext.d.ts +45 -8
- package/lib/contexts/loadcontext.js +232 -82
- package/lib/contexts/orientationcontext.d.ts +13 -15
- package/lib/contexts/orientationcontext.js +150 -67
- package/lib/contexts/rootcomponentscontext.d.ts +16 -0
- package/lib/contexts/rootcomponentscontext.js +65 -0
- package/lib/contexts/snapshotContext.d.ts +0 -3
- package/lib/contexts/snapshotContext.js +78 -23
- package/lib/contexts/tagcontext.d.ts +5 -5
- package/lib/contexts/tagcontext.js +16 -16
- package/lib/contexts/textalertcontext.d.ts +1 -5
- package/lib/contexts/textalertcontext.js +1 -5
- package/lib/contexts/usereventcontext.d.ts +1 -1
- package/lib/contexts/usereventcontext.js +12 -12
- package/lib/data/animation.d.ts +10 -2
- package/lib/data/change.d.ts +1 -1
- package/lib/data/change.js +7 -0
- package/lib/data/core.d.ts +9 -1
- package/lib/data/index.d.ts +1 -1
- package/lib/data/index.js +1 -1
- package/lib/decorators.d.ts +348 -0
- package/lib/decorators.js +239 -0
- package/lib/decoratorutils.d.ts +3 -0
- package/lib/decoratorutils.js +8 -0
- package/lib/emitter.d.ts +15 -2
- package/lib/emitter.js +15 -6
- package/lib/entity.d.ts +43 -25
- package/lib/entity.js +104 -71
- package/lib/event.d.ts +2 -1
- package/lib/event.js +1 -4
- package/lib/groups.d.ts +18 -0
- package/lib/groups.js +19 -0
- package/lib/icons.d.ts +3372 -0
- package/lib/icons.js +1 -0
- package/lib/index.d.ts +18 -13
- package/lib/index.js +17 -13
- package/lib/inflate.d.ts +7 -7
- package/lib/inflate.js +5 -5
- package/lib/observable.d.ts +9 -2
- package/lib/observable.js +5 -4
- package/lib/observe.d.ts +18 -0
- package/lib/observe.js +177 -0
- package/lib/profile.d.ts +9 -5
- package/lib/profile.js +27 -17
- package/lib/selectors.d.ts +1 -1
- package/lib/selectors.js +5 -4
- package/lib/types.d.ts +161 -19
- package/lib/types.js +22 -1
- package/lib/values/values.d.ts +7 -8
- package/lib/values/values.js +1 -2
- package/lib/values/valuesmutator.d.ts +4 -1
- package/lib/values/valuesmutator.js +10 -8
- package/lib/zcomponent.d.ts +21 -10
- package/lib/zcomponent.js +717 -540
- package/package.json +22 -5
- package/lib/behaviors/ChangeCursor.d.ts +0 -39
- 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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
111
|
+
idByElement = new Map();
|
|
44
112
|
/**
|
|
45
113
|
* Object that maps node script names to scripts.
|
|
114
|
+
* @default {}
|
|
46
115
|
*/
|
|
47
|
-
|
|
116
|
+
nodes = {};
|
|
48
117
|
/**
|
|
49
118
|
* Map of entites by ID.
|
|
50
119
|
*/
|
|
51
|
-
|
|
120
|
+
entityByID = new Map();
|
|
52
121
|
/**
|
|
53
122
|
* A map of entity labels to components.
|
|
54
123
|
*/
|
|
55
|
-
|
|
124
|
+
entityByLabel = new Map();
|
|
56
125
|
/**
|
|
57
126
|
* A map of node labels to components.
|
|
58
127
|
*/
|
|
59
|
-
|
|
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
|
-
|
|
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
|
-
|
|
143
|
+
get isConstructed() {
|
|
144
|
+
return this._isConstructed;
|
|
145
|
+
}
|
|
68
146
|
/**
|
|
69
147
|
* The animation object for this component.
|
|
148
|
+
* @zignore
|
|
70
149
|
*/
|
|
71
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
207
|
+
_animationTick = () => {
|
|
86
208
|
this.animation.tick();
|
|
87
209
|
};
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
that.
|
|
176
|
-
|
|
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
|
-
|
|
179
|
-
|
|
257
|
+
that._nodesById.set(nodeId, this);
|
|
258
|
+
for (const element of this.elementsResolved) {
|
|
259
|
+
that.idByElement.set(element, nodeId);
|
|
180
260
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
|
|
193
|
-
|
|
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
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
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
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
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
|
-
|
|
261
|
-
|
|
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
|
-
|
|
266
|
-
|
|
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
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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
|
-
|
|
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
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
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
|
-
|
|
349
|
-
|
|
350
|
-
new constructor(ctx, impl);
|
|
425
|
+
if (!entity)
|
|
426
|
+
return this.getZComponentInstance()?.resolveEntityID(id);
|
|
351
427
|
}
|
|
352
428
|
catch (err) {
|
|
353
|
-
|
|
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
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
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
|
-
|
|
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
|
-
|
|
440
|
-
|
|
445
|
+
const _constructor = this._constructorForBehavior(behaviorID);
|
|
446
|
+
if (_constructor)
|
|
447
|
+
new _constructor(ctx, impl);
|
|
441
448
|
}
|
|
442
449
|
catch (err) {
|
|
443
|
-
|
|
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
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
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
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
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
|
-
|
|
481
|
-
|
|
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
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
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
|
-
|
|
498
|
-
|
|
499
|
-
|
|
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
|
-
|
|
514
|
-
|
|
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
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
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
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
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
|
-
|
|
650
|
+
entity[prop] = v;
|
|
543
651
|
}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
parent =
|
|
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
|
-
|
|
564
|
-
|
|
565
|
-
|
|
670
|
+
/**
|
|
671
|
+
* Returns the node with the specified ID.
|
|
672
|
+
*/
|
|
673
|
+
_getNodeById(id) {
|
|
674
|
+
return this._nodesById.get(id);
|
|
566
675
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
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
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
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
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
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
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
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
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
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
|
-
|
|
649
|
-
|
|
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
|
-
|
|
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 };
|