@2112-lab/central-plant 0.1.86 → 0.1.87
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/dist/bundle/index.js +74 -37
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/managers/scene/componentTooltipManager.js +67 -36
- package/dist/cjs/src/managers/scene/sceneExportManager.js +6 -0
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/managers/scene/componentTooltipManager.js +67 -36
- package/dist/esm/src/managers/scene/sceneExportManager.js +6 -0
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -11375,6 +11375,12 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
11375
11375
|
// Computed from geometry - not in input format
|
|
11376
11376
|
'name',
|
|
11377
11377
|
// Redundant with GLB node names - not in input format
|
|
11378
|
+
'addedTimestamp',
|
|
11379
|
+
// Internal tracking - not needed in export
|
|
11380
|
+
'addedBy',
|
|
11381
|
+
// Internal tracking - not needed in export
|
|
11382
|
+
'initialPosition',
|
|
11383
|
+
// Internal tracking - not needed in export
|
|
11378
11384
|
// Exclude internal segment tracking properties
|
|
11379
11385
|
'segmentId',
|
|
11380
11386
|
// Internal tracking
|
|
@@ -33790,24 +33796,14 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
33790
33796
|
}, {
|
|
33791
33797
|
key: "toggleIODeviceBinaryState",
|
|
33792
33798
|
value: function toggleIODeviceBinaryState(ioDeviceObject) {
|
|
33793
|
-
var _this$sceneViewer;
|
|
33799
|
+
var _ref, _this$sceneViewer;
|
|
33794
33800
|
if (!ioDeviceObject || !this._stateAdapter) return;
|
|
33795
33801
|
var ud = ioDeviceObject.userData;
|
|
33796
33802
|
var attachmentId = ud === null || ud === void 0 ? void 0 : ud.attachmentId;
|
|
33797
33803
|
var dataPoints = (ud === null || ud === void 0 ? void 0 : ud.dataPoints) || [];
|
|
33798
33804
|
if (!attachmentId) return;
|
|
33799
33805
|
|
|
33800
|
-
//
|
|
33801
|
-
var binaryState = dataPoints.find(function (dp) {
|
|
33802
|
-
return dp.stateType === 'binary' || dp.type === 'binary';
|
|
33803
|
-
});
|
|
33804
|
-
if (!binaryState) return;
|
|
33805
|
-
var dpId = binaryState.id;
|
|
33806
|
-
var currentVal = this._stateAdapter.getState(attachmentId, dpId);
|
|
33807
|
-
var newVal = !Boolean(currentVal);
|
|
33808
|
-
this._stateAdapter.setState(attachmentId, dpId, newVal);
|
|
33809
|
-
|
|
33810
|
-
// Walk up to find parent component UUID for scoped behavior triggering
|
|
33806
|
+
// Walk up to find parent component UUID for scoped state/behavior handling
|
|
33811
33807
|
var parentUuid = null;
|
|
33812
33808
|
var obj = ioDeviceObject.parent;
|
|
33813
33809
|
while (obj) {
|
|
@@ -33818,8 +33814,24 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
33818
33814
|
}
|
|
33819
33815
|
obj = obj.parent;
|
|
33820
33816
|
}
|
|
33817
|
+
|
|
33818
|
+
// Create a scoped attachment key to prevent state sharing between instances
|
|
33819
|
+
// of the same smart component that share the same attachmentId
|
|
33820
|
+
var scopedAttachmentId = this._getScopedAttachmentKey(attachmentId, parentUuid);
|
|
33821
|
+
|
|
33822
|
+
// Find the first binary state
|
|
33823
|
+
var binaryState = dataPoints.find(function (dp) {
|
|
33824
|
+
return dp.stateType === 'binary' || dp.type === 'binary';
|
|
33825
|
+
});
|
|
33826
|
+
if (!binaryState) return;
|
|
33827
|
+
var dpId = binaryState.id;
|
|
33828
|
+
var storedVal = this._stateAdapter.getState(scopedAttachmentId, dpId);
|
|
33829
|
+
// Fall back to defaultValue when state is uninitialized (null/undefined)
|
|
33830
|
+
var currentVal = (_ref = storedVal !== null && storedVal !== void 0 ? storedVal : binaryState.defaultValue) !== null && _ref !== void 0 ? _ref : false;
|
|
33831
|
+
var newVal = !Boolean(currentVal);
|
|
33832
|
+
this._stateAdapter.setState(scopedAttachmentId, dpId, newVal);
|
|
33821
33833
|
(_this$sceneViewer = this.sceneViewer) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.managers) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.behaviorManager) === null || _this$sceneViewer === void 0 || _this$sceneViewer.triggerState(attachmentId, dpId, newVal, parentUuid);
|
|
33822
|
-
console.log("\uD83D\uDD04 [IODevice] Toggled ".concat(
|
|
33834
|
+
console.log("\uD83D\uDD04 [IODevice] Toggled ".concat(scopedAttachmentId, ".").concat(dpId, ": ").concat(currentVal, " \u2192 ").concat(newVal));
|
|
33823
33835
|
}
|
|
33824
33836
|
|
|
33825
33837
|
/**
|
|
@@ -33911,23 +33923,42 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
33911
33923
|
this._styleInjected = false;
|
|
33912
33924
|
}
|
|
33913
33925
|
|
|
33926
|
+
/**
|
|
33927
|
+
* Generate a scoped attachment key that includes the parent component UUID.
|
|
33928
|
+
* This ensures each instance of a smart component has isolated IO device state.
|
|
33929
|
+
* @param {string} attachmentId - The original attachment ID from the component data
|
|
33930
|
+
* @param {string|null} parentUuid - The UUID of the parent smart component instance
|
|
33931
|
+
* @returns {string} A scoped key in the format "parentUuid::attachmentId" or just attachmentId if no parent
|
|
33932
|
+
* @private
|
|
33933
|
+
*/
|
|
33934
|
+
}, {
|
|
33935
|
+
key: "_getScopedAttachmentKey",
|
|
33936
|
+
value: function _getScopedAttachmentKey(attachmentId, parentUuid) {
|
|
33937
|
+
if (!parentUuid) return attachmentId;
|
|
33938
|
+
return "".concat(parentUuid, "::").concat(attachmentId);
|
|
33939
|
+
}
|
|
33940
|
+
|
|
33914
33941
|
/**
|
|
33915
33942
|
* Gather I/O device children from a component's Three.js hierarchy.
|
|
33916
33943
|
* Returns richer data including attachmentId and data point definitions.
|
|
33917
|
-
* @param {THREE.Object3D} object
|
|
33918
|
-
* @returns {{ label: string, deviceId: string, attachmentId: string, dataPoints: Array }[]}
|
|
33944
|
+
* @param {THREE.Object3D} object - The parent component object
|
|
33945
|
+
* @returns {{ label: string, deviceId: string, attachmentId: string, scopedAttachmentId: string, dataPoints: Array }[]}
|
|
33919
33946
|
*/
|
|
33920
33947
|
}, {
|
|
33921
33948
|
key: "_getIODevices",
|
|
33922
33949
|
value: function _getIODevices(object) {
|
|
33950
|
+
var _this2 = this;
|
|
33923
33951
|
var devices = [];
|
|
33952
|
+
var parentUuid = object.uuid; // The component's own UUID
|
|
33924
33953
|
object.traverse(function (child) {
|
|
33925
33954
|
var _child$userData;
|
|
33926
33955
|
if (((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'io-device') {
|
|
33956
|
+
var attachmentId = child.userData.attachmentId || '';
|
|
33927
33957
|
devices.push({
|
|
33928
33958
|
label: child.userData.attachmentLabel || child.name || child.userData.deviceId || 'Unknown Device',
|
|
33929
33959
|
deviceId: child.userData.deviceId || '',
|
|
33930
|
-
attachmentId:
|
|
33960
|
+
attachmentId: attachmentId,
|
|
33961
|
+
scopedAttachmentId: _this2._getScopedAttachmentKey(attachmentId, parentUuid),
|
|
33931
33962
|
dataPoints: child.userData.dataPoints || [],
|
|
33932
33963
|
direction: child.userData.ioDirection || 'output'
|
|
33933
33964
|
});
|
|
@@ -33943,7 +33974,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
33943
33974
|
}, {
|
|
33944
33975
|
key: "_buildTooltip",
|
|
33945
33976
|
value: function _buildTooltip(object) {
|
|
33946
|
-
var
|
|
33977
|
+
var _this3 = this;
|
|
33947
33978
|
// Remove any existing tooltip first
|
|
33948
33979
|
this.hide();
|
|
33949
33980
|
// Re-assign selected object since hide() clears it
|
|
@@ -34011,9 +34042,10 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
34011
34042
|
list.appendChild(item);
|
|
34012
34043
|
|
|
34013
34044
|
// Data point rows (one per data point definition stored in userData)
|
|
34014
|
-
|
|
34045
|
+
// Use scopedAttachmentId to ensure state is isolated per component instance
|
|
34046
|
+
if (device.scopedAttachmentId && device.dataPoints.length > 0) {
|
|
34015
34047
|
device.dataPoints.forEach(function (dp) {
|
|
34016
|
-
var row =
|
|
34048
|
+
var row = _this3._buildDataPointRow(device.scopedAttachmentId, dp, device.direction, device.attachmentId);
|
|
34017
34049
|
list.appendChild(row);
|
|
34018
34050
|
});
|
|
34019
34051
|
}
|
|
@@ -34024,11 +34056,11 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
34024
34056
|
// Hover expand/collapse
|
|
34025
34057
|
trigger.addEventListener('mouseenter', function () {
|
|
34026
34058
|
ioSection.classList.add('expanded');
|
|
34027
|
-
|
|
34059
|
+
_this3._ioExpanded = true;
|
|
34028
34060
|
});
|
|
34029
34061
|
ioSection.addEventListener('mouseleave', function () {
|
|
34030
34062
|
ioSection.classList.remove('expanded');
|
|
34031
|
-
|
|
34063
|
+
_this3._ioExpanded = false;
|
|
34032
34064
|
});
|
|
34033
34065
|
card.appendChild(ioSection);
|
|
34034
34066
|
} else {
|
|
@@ -34127,18 +34159,19 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
34127
34159
|
* Output / read-only direction → shows a state badge (updated each frame).
|
|
34128
34160
|
* Input / bidirectional → shows an interactive control.
|
|
34129
34161
|
*
|
|
34130
|
-
* @param {string} attachmentId
|
|
34162
|
+
* @param {string} scopedAttachmentId - Scoped attachment ID (parentUuid::attachmentId) for state isolation
|
|
34131
34163
|
* @param {Object} dp - data point definition from ioConfig.dataPoints
|
|
34132
34164
|
* @param {string} [deviceDirection] - device-level direction ('input'|'output'), overrides dp.direction
|
|
34165
|
+
* @param {string} [originalAttachmentId] - Original attachment ID for behavior triggering
|
|
34133
34166
|
* @returns {HTMLElement}
|
|
34134
34167
|
*/
|
|
34135
34168
|
}, {
|
|
34136
34169
|
key: "_buildDataPointRow",
|
|
34137
|
-
value: function _buildDataPointRow(
|
|
34138
|
-
var
|
|
34170
|
+
value: function _buildDataPointRow(scopedAttachmentId, dp, deviceDirection, originalAttachmentId) {
|
|
34171
|
+
var _ref2,
|
|
34139
34172
|
_this$_stateAdapter$g,
|
|
34140
34173
|
_this$_stateAdapter,
|
|
34141
|
-
|
|
34174
|
+
_this4 = this;
|
|
34142
34175
|
var row = document.createElement('div');
|
|
34143
34176
|
row.className = 'cp-tooltip__dp-row';
|
|
34144
34177
|
var nameEl = document.createElement('span');
|
|
@@ -34146,20 +34179,21 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
34146
34179
|
nameEl.textContent = dp.name || dp.id || '?';
|
|
34147
34180
|
row.appendChild(nameEl);
|
|
34148
34181
|
var dpId = dp.id || dp.name;
|
|
34149
|
-
var key = "".concat(
|
|
34182
|
+
var key = "".concat(scopedAttachmentId, "::").concat(dpId);
|
|
34150
34183
|
// Device-level direction takes precedence; fall back to per-dp direction
|
|
34151
34184
|
var resolvedDirection = deviceDirection || dp.direction || 'output';
|
|
34152
34185
|
var isInput = resolvedDirection === 'input' || resolvedDirection === 'bidirectional';
|
|
34153
|
-
var currentVal = (
|
|
34186
|
+
var currentVal = (_ref2 = (_this$_stateAdapter$g = (_this$_stateAdapter = this._stateAdapter) === null || _this$_stateAdapter === void 0 ? void 0 : _this$_stateAdapter.getState(scopedAttachmentId, dpId)) !== null && _this$_stateAdapter$g !== void 0 ? _this$_stateAdapter$g : dp.defaultValue) !== null && _ref2 !== void 0 ? _ref2 : null;
|
|
34154
34187
|
if (isInput) {
|
|
34155
34188
|
var ctrl = this._buildInputControl(dp, currentVal, function (newVal) {
|
|
34156
|
-
var
|
|
34157
|
-
(
|
|
34189
|
+
var _this4$_stateAdapter, _this4$selectedObject, _this4$sceneViewer;
|
|
34190
|
+
(_this4$_stateAdapter = _this4._stateAdapter) === null || _this4$_stateAdapter === void 0 || _this4$_stateAdapter.setState(scopedAttachmentId, dpId, newVal);
|
|
34158
34191
|
// Also fire BehaviorManager so any wired behaviors react immediately.
|
|
34159
34192
|
// Pass the parent component UUID so behaviors scoped to a specific instance
|
|
34160
34193
|
// don't bleed across clones that share the same attachmentId.
|
|
34161
|
-
|
|
34162
|
-
|
|
34194
|
+
// Use originalAttachmentId for behavior triggering as behaviors are keyed by original ID
|
|
34195
|
+
var parentUuid = ((_this4$selectedObject = _this4.selectedObject) === null || _this4$selectedObject === void 0 ? void 0 : _this4$selectedObject.uuid) || null;
|
|
34196
|
+
(_this4$sceneViewer = _this4.sceneViewer) === null || _this4$sceneViewer === void 0 || (_this4$sceneViewer = _this4$sceneViewer.managers) === null || _this4$sceneViewer === void 0 || (_this4$sceneViewer = _this4$sceneViewer.behaviorManager) === null || _this4$sceneViewer === void 0 || _this4$sceneViewer.triggerState(originalAttachmentId || scopedAttachmentId, dpId, newVal, parentUuid);
|
|
34163
34197
|
});
|
|
34164
34198
|
row.appendChild(ctrl);
|
|
34165
34199
|
this._stateElements.set(key, {
|
|
@@ -34309,20 +34343,23 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
34309
34343
|
/**
|
|
34310
34344
|
* Re-read all tracked read-only badge values from the state adapter.
|
|
34311
34345
|
* Called each frame from update() — skips if no adapter is configured.
|
|
34346
|
+
* Key format is scopedAttachmentId::dataPointId where scopedAttachmentId
|
|
34347
|
+
* can be parentUuid::attachmentId, resulting in parentUuid::attachmentId::dataPointId
|
|
34312
34348
|
*/
|
|
34313
34349
|
}, {
|
|
34314
34350
|
key: "_refreshStateDisplays",
|
|
34315
34351
|
value: function _refreshStateDisplays() {
|
|
34316
|
-
var
|
|
34352
|
+
var _this5 = this;
|
|
34317
34353
|
if (!this._stateAdapter || !this._stateElements.size) return;
|
|
34318
34354
|
this._stateElements.forEach(function (entry, key) {
|
|
34319
34355
|
if (entry.isInput) return; // interactive controls are user-driven; don't overwrite
|
|
34320
|
-
|
|
34356
|
+
// Use lastIndexOf since scopedAttachmentId may contain '::' (parentUuid::attachmentId)
|
|
34357
|
+
var sepIdx = key.lastIndexOf('::');
|
|
34321
34358
|
if (sepIdx === -1) return;
|
|
34322
|
-
var
|
|
34359
|
+
var scopedAttachmentId = key.slice(0, sepIdx);
|
|
34323
34360
|
var dataPointId = key.slice(sepIdx + 2);
|
|
34324
|
-
var val =
|
|
34325
|
-
|
|
34361
|
+
var val = _this5._stateAdapter.getState(scopedAttachmentId, dataPointId);
|
|
34362
|
+
_this5._applyBadgeValue(entry.el, val, entry.dp);
|
|
34326
34363
|
});
|
|
34327
34364
|
}
|
|
34328
34365
|
}]);
|
|
@@ -36734,7 +36771,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
36734
36771
|
* Initialize the CentralPlant manager
|
|
36735
36772
|
*
|
|
36736
36773
|
* @constructor
|
|
36737
|
-
* @version 0.1.
|
|
36774
|
+
* @version 0.1.87
|
|
36738
36775
|
* @updated 2025-10-22
|
|
36739
36776
|
*
|
|
36740
36777
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -19,7 +19,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
19
19
|
* Initialize the CentralPlant manager
|
|
20
20
|
*
|
|
21
21
|
* @constructor
|
|
22
|
-
* @version 0.1.
|
|
22
|
+
* @version 0.1.87
|
|
23
23
|
* @updated 2025-10-22
|
|
24
24
|
*
|
|
25
25
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -129,24 +129,14 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
129
129
|
}, {
|
|
130
130
|
key: "toggleIODeviceBinaryState",
|
|
131
131
|
value: function toggleIODeviceBinaryState(ioDeviceObject) {
|
|
132
|
-
var _this$sceneViewer;
|
|
132
|
+
var _ref, _this$sceneViewer;
|
|
133
133
|
if (!ioDeviceObject || !this._stateAdapter) return;
|
|
134
134
|
var ud = ioDeviceObject.userData;
|
|
135
135
|
var attachmentId = ud === null || ud === void 0 ? void 0 : ud.attachmentId;
|
|
136
136
|
var dataPoints = (ud === null || ud === void 0 ? void 0 : ud.dataPoints) || [];
|
|
137
137
|
if (!attachmentId) return;
|
|
138
138
|
|
|
139
|
-
//
|
|
140
|
-
var binaryState = dataPoints.find(function (dp) {
|
|
141
|
-
return dp.stateType === 'binary' || dp.type === 'binary';
|
|
142
|
-
});
|
|
143
|
-
if (!binaryState) return;
|
|
144
|
-
var dpId = binaryState.id;
|
|
145
|
-
var currentVal = this._stateAdapter.getState(attachmentId, dpId);
|
|
146
|
-
var newVal = !Boolean(currentVal);
|
|
147
|
-
this._stateAdapter.setState(attachmentId, dpId, newVal);
|
|
148
|
-
|
|
149
|
-
// Walk up to find parent component UUID for scoped behavior triggering
|
|
139
|
+
// Walk up to find parent component UUID for scoped state/behavior handling
|
|
150
140
|
var parentUuid = null;
|
|
151
141
|
var obj = ioDeviceObject.parent;
|
|
152
142
|
while (obj) {
|
|
@@ -157,8 +147,24 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
157
147
|
}
|
|
158
148
|
obj = obj.parent;
|
|
159
149
|
}
|
|
150
|
+
|
|
151
|
+
// Create a scoped attachment key to prevent state sharing between instances
|
|
152
|
+
// of the same smart component that share the same attachmentId
|
|
153
|
+
var scopedAttachmentId = this._getScopedAttachmentKey(attachmentId, parentUuid);
|
|
154
|
+
|
|
155
|
+
// Find the first binary state
|
|
156
|
+
var binaryState = dataPoints.find(function (dp) {
|
|
157
|
+
return dp.stateType === 'binary' || dp.type === 'binary';
|
|
158
|
+
});
|
|
159
|
+
if (!binaryState) return;
|
|
160
|
+
var dpId = binaryState.id;
|
|
161
|
+
var storedVal = this._stateAdapter.getState(scopedAttachmentId, dpId);
|
|
162
|
+
// Fall back to defaultValue when state is uninitialized (null/undefined)
|
|
163
|
+
var currentVal = (_ref = storedVal !== null && storedVal !== void 0 ? storedVal : binaryState.defaultValue) !== null && _ref !== void 0 ? _ref : false;
|
|
164
|
+
var newVal = !Boolean(currentVal);
|
|
165
|
+
this._stateAdapter.setState(scopedAttachmentId, dpId, newVal);
|
|
160
166
|
(_this$sceneViewer = this.sceneViewer) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.managers) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.behaviorManager) === null || _this$sceneViewer === void 0 || _this$sceneViewer.triggerState(attachmentId, dpId, newVal, parentUuid);
|
|
161
|
-
console.log("\uD83D\uDD04 [IODevice] Toggled ".concat(
|
|
167
|
+
console.log("\uD83D\uDD04 [IODevice] Toggled ".concat(scopedAttachmentId, ".").concat(dpId, ": ").concat(currentVal, " \u2192 ").concat(newVal));
|
|
162
168
|
}
|
|
163
169
|
|
|
164
170
|
/**
|
|
@@ -250,23 +256,42 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
250
256
|
this._styleInjected = false;
|
|
251
257
|
}
|
|
252
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Generate a scoped attachment key that includes the parent component UUID.
|
|
261
|
+
* This ensures each instance of a smart component has isolated IO device state.
|
|
262
|
+
* @param {string} attachmentId - The original attachment ID from the component data
|
|
263
|
+
* @param {string|null} parentUuid - The UUID of the parent smart component instance
|
|
264
|
+
* @returns {string} A scoped key in the format "parentUuid::attachmentId" or just attachmentId if no parent
|
|
265
|
+
* @private
|
|
266
|
+
*/
|
|
267
|
+
}, {
|
|
268
|
+
key: "_getScopedAttachmentKey",
|
|
269
|
+
value: function _getScopedAttachmentKey(attachmentId, parentUuid) {
|
|
270
|
+
if (!parentUuid) return attachmentId;
|
|
271
|
+
return "".concat(parentUuid, "::").concat(attachmentId);
|
|
272
|
+
}
|
|
273
|
+
|
|
253
274
|
/**
|
|
254
275
|
* Gather I/O device children from a component's Three.js hierarchy.
|
|
255
276
|
* Returns richer data including attachmentId and data point definitions.
|
|
256
|
-
* @param {THREE.Object3D} object
|
|
257
|
-
* @returns {{ label: string, deviceId: string, attachmentId: string, dataPoints: Array }[]}
|
|
277
|
+
* @param {THREE.Object3D} object - The parent component object
|
|
278
|
+
* @returns {{ label: string, deviceId: string, attachmentId: string, scopedAttachmentId: string, dataPoints: Array }[]}
|
|
258
279
|
*/
|
|
259
280
|
}, {
|
|
260
281
|
key: "_getIODevices",
|
|
261
282
|
value: function _getIODevices(object) {
|
|
283
|
+
var _this2 = this;
|
|
262
284
|
var devices = [];
|
|
285
|
+
var parentUuid = object.uuid; // The component's own UUID
|
|
263
286
|
object.traverse(function (child) {
|
|
264
287
|
var _child$userData;
|
|
265
288
|
if (((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'io-device') {
|
|
289
|
+
var attachmentId = child.userData.attachmentId || '';
|
|
266
290
|
devices.push({
|
|
267
291
|
label: child.userData.attachmentLabel || child.name || child.userData.deviceId || 'Unknown Device',
|
|
268
292
|
deviceId: child.userData.deviceId || '',
|
|
269
|
-
attachmentId:
|
|
293
|
+
attachmentId: attachmentId,
|
|
294
|
+
scopedAttachmentId: _this2._getScopedAttachmentKey(attachmentId, parentUuid),
|
|
270
295
|
dataPoints: child.userData.dataPoints || [],
|
|
271
296
|
direction: child.userData.ioDirection || 'output'
|
|
272
297
|
});
|
|
@@ -282,7 +307,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
282
307
|
}, {
|
|
283
308
|
key: "_buildTooltip",
|
|
284
309
|
value: function _buildTooltip(object) {
|
|
285
|
-
var
|
|
310
|
+
var _this3 = this;
|
|
286
311
|
// Remove any existing tooltip first
|
|
287
312
|
this.hide();
|
|
288
313
|
// Re-assign selected object since hide() clears it
|
|
@@ -350,9 +375,10 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
350
375
|
list.appendChild(item);
|
|
351
376
|
|
|
352
377
|
// Data point rows (one per data point definition stored in userData)
|
|
353
|
-
|
|
378
|
+
// Use scopedAttachmentId to ensure state is isolated per component instance
|
|
379
|
+
if (device.scopedAttachmentId && device.dataPoints.length > 0) {
|
|
354
380
|
device.dataPoints.forEach(function (dp) {
|
|
355
|
-
var row =
|
|
381
|
+
var row = _this3._buildDataPointRow(device.scopedAttachmentId, dp, device.direction, device.attachmentId);
|
|
356
382
|
list.appendChild(row);
|
|
357
383
|
});
|
|
358
384
|
}
|
|
@@ -363,11 +389,11 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
363
389
|
// Hover expand/collapse
|
|
364
390
|
trigger.addEventListener('mouseenter', function () {
|
|
365
391
|
ioSection.classList.add('expanded');
|
|
366
|
-
|
|
392
|
+
_this3._ioExpanded = true;
|
|
367
393
|
});
|
|
368
394
|
ioSection.addEventListener('mouseleave', function () {
|
|
369
395
|
ioSection.classList.remove('expanded');
|
|
370
|
-
|
|
396
|
+
_this3._ioExpanded = false;
|
|
371
397
|
});
|
|
372
398
|
card.appendChild(ioSection);
|
|
373
399
|
} else {
|
|
@@ -466,18 +492,19 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
466
492
|
* Output / read-only direction → shows a state badge (updated each frame).
|
|
467
493
|
* Input / bidirectional → shows an interactive control.
|
|
468
494
|
*
|
|
469
|
-
* @param {string} attachmentId
|
|
495
|
+
* @param {string} scopedAttachmentId - Scoped attachment ID (parentUuid::attachmentId) for state isolation
|
|
470
496
|
* @param {Object} dp - data point definition from ioConfig.dataPoints
|
|
471
497
|
* @param {string} [deviceDirection] - device-level direction ('input'|'output'), overrides dp.direction
|
|
498
|
+
* @param {string} [originalAttachmentId] - Original attachment ID for behavior triggering
|
|
472
499
|
* @returns {HTMLElement}
|
|
473
500
|
*/
|
|
474
501
|
}, {
|
|
475
502
|
key: "_buildDataPointRow",
|
|
476
|
-
value: function _buildDataPointRow(
|
|
477
|
-
var
|
|
503
|
+
value: function _buildDataPointRow(scopedAttachmentId, dp, deviceDirection, originalAttachmentId) {
|
|
504
|
+
var _ref2,
|
|
478
505
|
_this$_stateAdapter$g,
|
|
479
506
|
_this$_stateAdapter,
|
|
480
|
-
|
|
507
|
+
_this4 = this;
|
|
481
508
|
var row = document.createElement('div');
|
|
482
509
|
row.className = 'cp-tooltip__dp-row';
|
|
483
510
|
var nameEl = document.createElement('span');
|
|
@@ -485,20 +512,21 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
485
512
|
nameEl.textContent = dp.name || dp.id || '?';
|
|
486
513
|
row.appendChild(nameEl);
|
|
487
514
|
var dpId = dp.id || dp.name;
|
|
488
|
-
var key = "".concat(
|
|
515
|
+
var key = "".concat(scopedAttachmentId, "::").concat(dpId);
|
|
489
516
|
// Device-level direction takes precedence; fall back to per-dp direction
|
|
490
517
|
var resolvedDirection = deviceDirection || dp.direction || 'output';
|
|
491
518
|
var isInput = resolvedDirection === 'input' || resolvedDirection === 'bidirectional';
|
|
492
|
-
var currentVal = (
|
|
519
|
+
var currentVal = (_ref2 = (_this$_stateAdapter$g = (_this$_stateAdapter = this._stateAdapter) === null || _this$_stateAdapter === void 0 ? void 0 : _this$_stateAdapter.getState(scopedAttachmentId, dpId)) !== null && _this$_stateAdapter$g !== void 0 ? _this$_stateAdapter$g : dp.defaultValue) !== null && _ref2 !== void 0 ? _ref2 : null;
|
|
493
520
|
if (isInput) {
|
|
494
521
|
var ctrl = this._buildInputControl(dp, currentVal, function (newVal) {
|
|
495
|
-
var
|
|
496
|
-
(
|
|
522
|
+
var _this4$_stateAdapter, _this4$selectedObject, _this4$sceneViewer;
|
|
523
|
+
(_this4$_stateAdapter = _this4._stateAdapter) === null || _this4$_stateAdapter === void 0 || _this4$_stateAdapter.setState(scopedAttachmentId, dpId, newVal);
|
|
497
524
|
// Also fire BehaviorManager so any wired behaviors react immediately.
|
|
498
525
|
// Pass the parent component UUID so behaviors scoped to a specific instance
|
|
499
526
|
// don't bleed across clones that share the same attachmentId.
|
|
500
|
-
|
|
501
|
-
|
|
527
|
+
// Use originalAttachmentId for behavior triggering as behaviors are keyed by original ID
|
|
528
|
+
var parentUuid = ((_this4$selectedObject = _this4.selectedObject) === null || _this4$selectedObject === void 0 ? void 0 : _this4$selectedObject.uuid) || null;
|
|
529
|
+
(_this4$sceneViewer = _this4.sceneViewer) === null || _this4$sceneViewer === void 0 || (_this4$sceneViewer = _this4$sceneViewer.managers) === null || _this4$sceneViewer === void 0 || (_this4$sceneViewer = _this4$sceneViewer.behaviorManager) === null || _this4$sceneViewer === void 0 || _this4$sceneViewer.triggerState(originalAttachmentId || scopedAttachmentId, dpId, newVal, parentUuid);
|
|
502
530
|
});
|
|
503
531
|
row.appendChild(ctrl);
|
|
504
532
|
this._stateElements.set(key, {
|
|
@@ -648,20 +676,23 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
648
676
|
/**
|
|
649
677
|
* Re-read all tracked read-only badge values from the state adapter.
|
|
650
678
|
* Called each frame from update() — skips if no adapter is configured.
|
|
679
|
+
* Key format is scopedAttachmentId::dataPointId where scopedAttachmentId
|
|
680
|
+
* can be parentUuid::attachmentId, resulting in parentUuid::attachmentId::dataPointId
|
|
651
681
|
*/
|
|
652
682
|
}, {
|
|
653
683
|
key: "_refreshStateDisplays",
|
|
654
684
|
value: function _refreshStateDisplays() {
|
|
655
|
-
var
|
|
685
|
+
var _this5 = this;
|
|
656
686
|
if (!this._stateAdapter || !this._stateElements.size) return;
|
|
657
687
|
this._stateElements.forEach(function (entry, key) {
|
|
658
688
|
if (entry.isInput) return; // interactive controls are user-driven; don't overwrite
|
|
659
|
-
|
|
689
|
+
// Use lastIndexOf since scopedAttachmentId may contain '::' (parentUuid::attachmentId)
|
|
690
|
+
var sepIdx = key.lastIndexOf('::');
|
|
660
691
|
if (sepIdx === -1) return;
|
|
661
|
-
var
|
|
692
|
+
var scopedAttachmentId = key.slice(0, sepIdx);
|
|
662
693
|
var dataPointId = key.slice(sepIdx + 2);
|
|
663
|
-
var val =
|
|
664
|
-
|
|
694
|
+
var val = _this5._stateAdapter.getState(scopedAttachmentId, dataPointId);
|
|
695
|
+
_this5._applyBadgeValue(entry.el, val, entry.dp);
|
|
665
696
|
});
|
|
666
697
|
}
|
|
667
698
|
}]);
|
|
@@ -160,6 +160,12 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
160
160
|
// Computed from geometry - not in input format
|
|
161
161
|
'name',
|
|
162
162
|
// Redundant with GLB node names - not in input format
|
|
163
|
+
'addedTimestamp',
|
|
164
|
+
// Internal tracking - not needed in export
|
|
165
|
+
'addedBy',
|
|
166
|
+
// Internal tracking - not needed in export
|
|
167
|
+
'initialPosition',
|
|
168
|
+
// Internal tracking - not needed in export
|
|
163
169
|
// Exclude internal segment tracking properties
|
|
164
170
|
'segmentId',
|
|
165
171
|
// Internal tracking
|
|
@@ -15,7 +15,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
15
15
|
* Initialize the CentralPlant manager
|
|
16
16
|
*
|
|
17
17
|
* @constructor
|
|
18
|
-
* @version 0.1.
|
|
18
|
+
* @version 0.1.87
|
|
19
19
|
* @updated 2025-10-22
|
|
20
20
|
*
|
|
21
21
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -105,24 +105,14 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
105
105
|
}, {
|
|
106
106
|
key: "toggleIODeviceBinaryState",
|
|
107
107
|
value: function toggleIODeviceBinaryState(ioDeviceObject) {
|
|
108
|
-
var _this$sceneViewer;
|
|
108
|
+
var _ref, _this$sceneViewer;
|
|
109
109
|
if (!ioDeviceObject || !this._stateAdapter) return;
|
|
110
110
|
var ud = ioDeviceObject.userData;
|
|
111
111
|
var attachmentId = ud === null || ud === void 0 ? void 0 : ud.attachmentId;
|
|
112
112
|
var dataPoints = (ud === null || ud === void 0 ? void 0 : ud.dataPoints) || [];
|
|
113
113
|
if (!attachmentId) return;
|
|
114
114
|
|
|
115
|
-
//
|
|
116
|
-
var binaryState = dataPoints.find(function (dp) {
|
|
117
|
-
return dp.stateType === 'binary' || dp.type === 'binary';
|
|
118
|
-
});
|
|
119
|
-
if (!binaryState) return;
|
|
120
|
-
var dpId = binaryState.id;
|
|
121
|
-
var currentVal = this._stateAdapter.getState(attachmentId, dpId);
|
|
122
|
-
var newVal = !Boolean(currentVal);
|
|
123
|
-
this._stateAdapter.setState(attachmentId, dpId, newVal);
|
|
124
|
-
|
|
125
|
-
// Walk up to find parent component UUID for scoped behavior triggering
|
|
115
|
+
// Walk up to find parent component UUID for scoped state/behavior handling
|
|
126
116
|
var parentUuid = null;
|
|
127
117
|
var obj = ioDeviceObject.parent;
|
|
128
118
|
while (obj) {
|
|
@@ -133,8 +123,24 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
133
123
|
}
|
|
134
124
|
obj = obj.parent;
|
|
135
125
|
}
|
|
126
|
+
|
|
127
|
+
// Create a scoped attachment key to prevent state sharing between instances
|
|
128
|
+
// of the same smart component that share the same attachmentId
|
|
129
|
+
var scopedAttachmentId = this._getScopedAttachmentKey(attachmentId, parentUuid);
|
|
130
|
+
|
|
131
|
+
// Find the first binary state
|
|
132
|
+
var binaryState = dataPoints.find(function (dp) {
|
|
133
|
+
return dp.stateType === 'binary' || dp.type === 'binary';
|
|
134
|
+
});
|
|
135
|
+
if (!binaryState) return;
|
|
136
|
+
var dpId = binaryState.id;
|
|
137
|
+
var storedVal = this._stateAdapter.getState(scopedAttachmentId, dpId);
|
|
138
|
+
// Fall back to defaultValue when state is uninitialized (null/undefined)
|
|
139
|
+
var currentVal = (_ref = storedVal !== null && storedVal !== void 0 ? storedVal : binaryState.defaultValue) !== null && _ref !== void 0 ? _ref : false;
|
|
140
|
+
var newVal = !Boolean(currentVal);
|
|
141
|
+
this._stateAdapter.setState(scopedAttachmentId, dpId, newVal);
|
|
136
142
|
(_this$sceneViewer = this.sceneViewer) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.managers) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.behaviorManager) === null || _this$sceneViewer === void 0 || _this$sceneViewer.triggerState(attachmentId, dpId, newVal, parentUuid);
|
|
137
|
-
console.log("\uD83D\uDD04 [IODevice] Toggled ".concat(
|
|
143
|
+
console.log("\uD83D\uDD04 [IODevice] Toggled ".concat(scopedAttachmentId, ".").concat(dpId, ": ").concat(currentVal, " \u2192 ").concat(newVal));
|
|
138
144
|
}
|
|
139
145
|
|
|
140
146
|
/**
|
|
@@ -226,23 +232,42 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
226
232
|
this._styleInjected = false;
|
|
227
233
|
}
|
|
228
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Generate a scoped attachment key that includes the parent component UUID.
|
|
237
|
+
* This ensures each instance of a smart component has isolated IO device state.
|
|
238
|
+
* @param {string} attachmentId - The original attachment ID from the component data
|
|
239
|
+
* @param {string|null} parentUuid - The UUID of the parent smart component instance
|
|
240
|
+
* @returns {string} A scoped key in the format "parentUuid::attachmentId" or just attachmentId if no parent
|
|
241
|
+
* @private
|
|
242
|
+
*/
|
|
243
|
+
}, {
|
|
244
|
+
key: "_getScopedAttachmentKey",
|
|
245
|
+
value: function _getScopedAttachmentKey(attachmentId, parentUuid) {
|
|
246
|
+
if (!parentUuid) return attachmentId;
|
|
247
|
+
return "".concat(parentUuid, "::").concat(attachmentId);
|
|
248
|
+
}
|
|
249
|
+
|
|
229
250
|
/**
|
|
230
251
|
* Gather I/O device children from a component's Three.js hierarchy.
|
|
231
252
|
* Returns richer data including attachmentId and data point definitions.
|
|
232
|
-
* @param {THREE.Object3D} object
|
|
233
|
-
* @returns {{ label: string, deviceId: string, attachmentId: string, dataPoints: Array }[]}
|
|
253
|
+
* @param {THREE.Object3D} object - The parent component object
|
|
254
|
+
* @returns {{ label: string, deviceId: string, attachmentId: string, scopedAttachmentId: string, dataPoints: Array }[]}
|
|
234
255
|
*/
|
|
235
256
|
}, {
|
|
236
257
|
key: "_getIODevices",
|
|
237
258
|
value: function _getIODevices(object) {
|
|
259
|
+
var _this2 = this;
|
|
238
260
|
var devices = [];
|
|
261
|
+
var parentUuid = object.uuid; // The component's own UUID
|
|
239
262
|
object.traverse(function (child) {
|
|
240
263
|
var _child$userData;
|
|
241
264
|
if (((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'io-device') {
|
|
265
|
+
var attachmentId = child.userData.attachmentId || '';
|
|
242
266
|
devices.push({
|
|
243
267
|
label: child.userData.attachmentLabel || child.name || child.userData.deviceId || 'Unknown Device',
|
|
244
268
|
deviceId: child.userData.deviceId || '',
|
|
245
|
-
attachmentId:
|
|
269
|
+
attachmentId: attachmentId,
|
|
270
|
+
scopedAttachmentId: _this2._getScopedAttachmentKey(attachmentId, parentUuid),
|
|
246
271
|
dataPoints: child.userData.dataPoints || [],
|
|
247
272
|
direction: child.userData.ioDirection || 'output'
|
|
248
273
|
});
|
|
@@ -258,7 +283,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
258
283
|
}, {
|
|
259
284
|
key: "_buildTooltip",
|
|
260
285
|
value: function _buildTooltip(object) {
|
|
261
|
-
var
|
|
286
|
+
var _this3 = this;
|
|
262
287
|
// Remove any existing tooltip first
|
|
263
288
|
this.hide();
|
|
264
289
|
// Re-assign selected object since hide() clears it
|
|
@@ -326,9 +351,10 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
326
351
|
list.appendChild(item);
|
|
327
352
|
|
|
328
353
|
// Data point rows (one per data point definition stored in userData)
|
|
329
|
-
|
|
354
|
+
// Use scopedAttachmentId to ensure state is isolated per component instance
|
|
355
|
+
if (device.scopedAttachmentId && device.dataPoints.length > 0) {
|
|
330
356
|
device.dataPoints.forEach(function (dp) {
|
|
331
|
-
var row =
|
|
357
|
+
var row = _this3._buildDataPointRow(device.scopedAttachmentId, dp, device.direction, device.attachmentId);
|
|
332
358
|
list.appendChild(row);
|
|
333
359
|
});
|
|
334
360
|
}
|
|
@@ -339,11 +365,11 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
339
365
|
// Hover expand/collapse
|
|
340
366
|
trigger.addEventListener('mouseenter', function () {
|
|
341
367
|
ioSection.classList.add('expanded');
|
|
342
|
-
|
|
368
|
+
_this3._ioExpanded = true;
|
|
343
369
|
});
|
|
344
370
|
ioSection.addEventListener('mouseleave', function () {
|
|
345
371
|
ioSection.classList.remove('expanded');
|
|
346
|
-
|
|
372
|
+
_this3._ioExpanded = false;
|
|
347
373
|
});
|
|
348
374
|
card.appendChild(ioSection);
|
|
349
375
|
} else {
|
|
@@ -442,18 +468,19 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
442
468
|
* Output / read-only direction → shows a state badge (updated each frame).
|
|
443
469
|
* Input / bidirectional → shows an interactive control.
|
|
444
470
|
*
|
|
445
|
-
* @param {string} attachmentId
|
|
471
|
+
* @param {string} scopedAttachmentId - Scoped attachment ID (parentUuid::attachmentId) for state isolation
|
|
446
472
|
* @param {Object} dp - data point definition from ioConfig.dataPoints
|
|
447
473
|
* @param {string} [deviceDirection] - device-level direction ('input'|'output'), overrides dp.direction
|
|
474
|
+
* @param {string} [originalAttachmentId] - Original attachment ID for behavior triggering
|
|
448
475
|
* @returns {HTMLElement}
|
|
449
476
|
*/
|
|
450
477
|
}, {
|
|
451
478
|
key: "_buildDataPointRow",
|
|
452
|
-
value: function _buildDataPointRow(
|
|
453
|
-
var
|
|
479
|
+
value: function _buildDataPointRow(scopedAttachmentId, dp, deviceDirection, originalAttachmentId) {
|
|
480
|
+
var _ref2,
|
|
454
481
|
_this$_stateAdapter$g,
|
|
455
482
|
_this$_stateAdapter,
|
|
456
|
-
|
|
483
|
+
_this4 = this;
|
|
457
484
|
var row = document.createElement('div');
|
|
458
485
|
row.className = 'cp-tooltip__dp-row';
|
|
459
486
|
var nameEl = document.createElement('span');
|
|
@@ -461,20 +488,21 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
461
488
|
nameEl.textContent = dp.name || dp.id || '?';
|
|
462
489
|
row.appendChild(nameEl);
|
|
463
490
|
var dpId = dp.id || dp.name;
|
|
464
|
-
var key = "".concat(
|
|
491
|
+
var key = "".concat(scopedAttachmentId, "::").concat(dpId);
|
|
465
492
|
// Device-level direction takes precedence; fall back to per-dp direction
|
|
466
493
|
var resolvedDirection = deviceDirection || dp.direction || 'output';
|
|
467
494
|
var isInput = resolvedDirection === 'input' || resolvedDirection === 'bidirectional';
|
|
468
|
-
var currentVal = (
|
|
495
|
+
var currentVal = (_ref2 = (_this$_stateAdapter$g = (_this$_stateAdapter = this._stateAdapter) === null || _this$_stateAdapter === void 0 ? void 0 : _this$_stateAdapter.getState(scopedAttachmentId, dpId)) !== null && _this$_stateAdapter$g !== void 0 ? _this$_stateAdapter$g : dp.defaultValue) !== null && _ref2 !== void 0 ? _ref2 : null;
|
|
469
496
|
if (isInput) {
|
|
470
497
|
var ctrl = this._buildInputControl(dp, currentVal, function (newVal) {
|
|
471
|
-
var
|
|
472
|
-
(
|
|
498
|
+
var _this4$_stateAdapter, _this4$selectedObject, _this4$sceneViewer;
|
|
499
|
+
(_this4$_stateAdapter = _this4._stateAdapter) === null || _this4$_stateAdapter === void 0 || _this4$_stateAdapter.setState(scopedAttachmentId, dpId, newVal);
|
|
473
500
|
// Also fire BehaviorManager so any wired behaviors react immediately.
|
|
474
501
|
// Pass the parent component UUID so behaviors scoped to a specific instance
|
|
475
502
|
// don't bleed across clones that share the same attachmentId.
|
|
476
|
-
|
|
477
|
-
|
|
503
|
+
// Use originalAttachmentId for behavior triggering as behaviors are keyed by original ID
|
|
504
|
+
var parentUuid = ((_this4$selectedObject = _this4.selectedObject) === null || _this4$selectedObject === void 0 ? void 0 : _this4$selectedObject.uuid) || null;
|
|
505
|
+
(_this4$sceneViewer = _this4.sceneViewer) === null || _this4$sceneViewer === void 0 || (_this4$sceneViewer = _this4$sceneViewer.managers) === null || _this4$sceneViewer === void 0 || (_this4$sceneViewer = _this4$sceneViewer.behaviorManager) === null || _this4$sceneViewer === void 0 || _this4$sceneViewer.triggerState(originalAttachmentId || scopedAttachmentId, dpId, newVal, parentUuid);
|
|
478
506
|
});
|
|
479
507
|
row.appendChild(ctrl);
|
|
480
508
|
this._stateElements.set(key, {
|
|
@@ -624,20 +652,23 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
624
652
|
/**
|
|
625
653
|
* Re-read all tracked read-only badge values from the state adapter.
|
|
626
654
|
* Called each frame from update() — skips if no adapter is configured.
|
|
655
|
+
* Key format is scopedAttachmentId::dataPointId where scopedAttachmentId
|
|
656
|
+
* can be parentUuid::attachmentId, resulting in parentUuid::attachmentId::dataPointId
|
|
627
657
|
*/
|
|
628
658
|
}, {
|
|
629
659
|
key: "_refreshStateDisplays",
|
|
630
660
|
value: function _refreshStateDisplays() {
|
|
631
|
-
var
|
|
661
|
+
var _this5 = this;
|
|
632
662
|
if (!this._stateAdapter || !this._stateElements.size) return;
|
|
633
663
|
this._stateElements.forEach(function (entry, key) {
|
|
634
664
|
if (entry.isInput) return; // interactive controls are user-driven; don't overwrite
|
|
635
|
-
|
|
665
|
+
// Use lastIndexOf since scopedAttachmentId may contain '::' (parentUuid::attachmentId)
|
|
666
|
+
var sepIdx = key.lastIndexOf('::');
|
|
636
667
|
if (sepIdx === -1) return;
|
|
637
|
-
var
|
|
668
|
+
var scopedAttachmentId = key.slice(0, sepIdx);
|
|
638
669
|
var dataPointId = key.slice(sepIdx + 2);
|
|
639
|
-
var val =
|
|
640
|
-
|
|
670
|
+
var val = _this5._stateAdapter.getState(scopedAttachmentId, dataPointId);
|
|
671
|
+
_this5._applyBadgeValue(entry.el, val, entry.dp);
|
|
641
672
|
});
|
|
642
673
|
}
|
|
643
674
|
}]);
|
|
@@ -138,6 +138,12 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
138
138
|
// Computed from geometry - not in input format
|
|
139
139
|
'name',
|
|
140
140
|
// Redundant with GLB node names - not in input format
|
|
141
|
+
'addedTimestamp',
|
|
142
|
+
// Internal tracking - not needed in export
|
|
143
|
+
'addedBy',
|
|
144
|
+
// Internal tracking - not needed in export
|
|
145
|
+
'initialPosition',
|
|
146
|
+
// Internal tracking - not needed in export
|
|
141
147
|
// Exclude internal segment tracking properties
|
|
142
148
|
'segmentId',
|
|
143
149
|
// Internal tracking
|