@2112-lab/central-plant 0.3.38 → 0.3.41
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 +1096 -562
- package/dist/cjs/src/core/centralPlant.js +115 -68
- package/dist/cjs/src/core/centralPlantInternals.js +20 -36
- package/dist/cjs/src/index.js +23 -0
- package/dist/cjs/src/managers/behaviors/IoBehaviorManager.js +175 -234
- package/dist/cjs/src/managers/components/componentDataManager.js +63 -11
- package/dist/cjs/src/managers/scene/componentTooltipManager.js +95 -65
- package/dist/cjs/src/managers/scene/modelManager.js +93 -145
- package/dist/cjs/src/managers/scene/sceneOperationsManager.js +8 -3
- package/dist/cjs/src/utils/animationTransformUtils.js +82 -0
- package/dist/cjs/src/utils/behaviorDispatch.js +62 -0
- package/dist/cjs/src/utils/behaviorRegistration.js +76 -0
- package/dist/cjs/src/utils/behaviorSceneUtils.js +155 -0
- package/dist/cjs/src/utils/behaviorSchema.js +209 -0
- package/dist/esm/src/core/centralPlant.js +115 -68
- package/dist/esm/src/core/centralPlantInternals.js +21 -37
- package/dist/esm/src/index.js +5 -0
- package/dist/esm/src/managers/behaviors/IoBehaviorManager.js +176 -235
- package/dist/esm/src/managers/components/componentDataManager.js +63 -11
- package/dist/esm/src/managers/scene/componentTooltipManager.js +95 -65
- package/dist/esm/src/managers/scene/modelManager.js +94 -146
- package/dist/esm/src/managers/scene/sceneOperationsManager.js +8 -3
- package/dist/esm/src/utils/animationTransformUtils.js +56 -0
- package/dist/esm/src/utils/behaviorDispatch.js +56 -0
- package/dist/esm/src/utils/behaviorRegistration.js +71 -0
- package/dist/esm/src/utils/behaviorSceneUtils.js +147 -0
- package/dist/esm/src/utils/behaviorSchema.js +201 -0
- package/dist/index.d.ts +186 -1
- package/package.json +1 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Register mesh animations and intra-component state links when a smart
|
|
5
|
+
* component is placed or imported into the scene.
|
|
6
|
+
*
|
|
7
|
+
* @param {import('../managers/behaviors/IoBehaviorManager.js').IoBehaviorManager} ioBehavMgr
|
|
8
|
+
* @param {string} componentUuid - Instance UUID of the parent component
|
|
9
|
+
* @param {Object} componentData - Smart component dictionary entry
|
|
10
|
+
* @param {Object} componentModel - Root THREE.Object3D of the placed component
|
|
11
|
+
* @param {Object} componentDictionary - modelPreloader.componentDictionary
|
|
12
|
+
*/
|
|
13
|
+
function registerBehaviorsForComponent(ioBehavMgr, componentUuid, componentData, componentModel, componentDictionary) {
|
|
14
|
+
var _componentData$behavi;
|
|
15
|
+
if (!ioBehavMgr || !componentData || !componentModel) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (componentData.isSmart && componentData.attachedDevices) {
|
|
19
|
+
var _loop = function _loop() {
|
|
20
|
+
var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
|
|
21
|
+
attachmentId = _Object$entries$_i[0],
|
|
22
|
+
attachment = _Object$entries$_i[1];
|
|
23
|
+
var deviceData = componentDictionary === null || componentDictionary === void 0 ? void 0 : componentDictionary[attachment.deviceId];
|
|
24
|
+
if (!(deviceData !== null && deviceData !== void 0 && deviceData.behaviorConfig)) return 1; // continue
|
|
25
|
+
var deviceRoot = null;
|
|
26
|
+
componentModel.traverse(function (obj) {
|
|
27
|
+
var _obj$userData;
|
|
28
|
+
if (!deviceRoot && ((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.attachmentId) === attachmentId) deviceRoot = obj;
|
|
29
|
+
});
|
|
30
|
+
if (deviceRoot) {
|
|
31
|
+
ioBehavMgr.loadBehaviors(attachmentId, deviceData.behaviorConfig, deviceRoot, componentUuid);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
for (var _i = 0, _Object$entries = Object.entries(componentData.attachedDevices); _i < _Object$entries.length; _i++) {
|
|
35
|
+
if (_loop()) continue;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (((_componentData$behavi = componentData.behaviors) === null || _componentData$behavi === void 0 ? void 0 : _componentData$behavi.length) > 0) {
|
|
39
|
+
ioBehavMgr.registerComponentBehaviors(componentUuid, componentData.behaviors);
|
|
40
|
+
} else if (componentData.isSmart) {
|
|
41
|
+
ioBehavMgr.registerComponentBehaviors(componentUuid, []);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Reload mesh behaviorConfig for every placed instance of an I/O device asset.
|
|
47
|
+
* Call after the animation wizard saves updated behaviorConfig to the dictionary.
|
|
48
|
+
*
|
|
49
|
+
* @param {import('../managers/behaviors/IoBehaviorManager.js').IoBehaviorManager} ioBehavMgr
|
|
50
|
+
* @param {string} deviceAssetId - Dictionary / asset id of the I/O device
|
|
51
|
+
* @param {Object} componentDictionary
|
|
52
|
+
* @param {Object} centralPlant
|
|
53
|
+
*/
|
|
54
|
+
function reloadBehaviorsForDeviceAsset(ioBehavMgr, deviceAssetId, componentDictionary, centralPlant) {
|
|
55
|
+
var _centralPlant$sceneVi;
|
|
56
|
+
var scene = centralPlant === null || centralPlant === void 0 || (_centralPlant$sceneVi = centralPlant.sceneViewer) === null || _centralPlant$sceneVi === void 0 ? void 0 : _centralPlant$sceneVi.scene;
|
|
57
|
+
var deviceData = componentDictionary === null || componentDictionary === void 0 ? void 0 : componentDictionary[deviceAssetId];
|
|
58
|
+
if (!ioBehavMgr || !scene || !(deviceData !== null && deviceData !== void 0 && deviceData.behaviorConfig)) return;
|
|
59
|
+
scene.traverse(function (obj) {
|
|
60
|
+
var _obj$userData2, _obj$userData3, _obj$parent;
|
|
61
|
+
if (((_obj$userData2 = obj.userData) === null || _obj$userData2 === void 0 ? void 0 : _obj$userData2.objectType) !== 'io-device') return;
|
|
62
|
+
if (((_obj$userData3 = obj.userData) === null || _obj$userData3 === void 0 ? void 0 : _obj$userData3.deviceId) !== deviceAssetId) return;
|
|
63
|
+
var parentUuid = obj.userData.parentComponentId || ((_obj$parent = obj.parent) === null || _obj$parent === void 0 ? void 0 : _obj$parent.uuid);
|
|
64
|
+
var attachmentId = obj.userData.attachmentId;
|
|
65
|
+
if (!parentUuid || !attachmentId) return;
|
|
66
|
+
ioBehavMgr.unloadForAttachment(parentUuid, attachmentId);
|
|
67
|
+
ioBehavMgr.loadBehaviors(attachmentId, deviceData.behaviorConfig, obj, parentUuid);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { registerBehaviorsForComponent, reloadBehaviorsForDeviceAsset };
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { registerBehaviorsForComponent } from './behaviorRegistration.js';
|
|
2
|
+
import { getScopedAttachmentKey, getIoBehaviorManager } from './behaviorDispatch.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Scene-level behavior helpers: scan endpoints, register behaviors, cross-component links.
|
|
6
|
+
*/
|
|
7
|
+
function getComponentDictionary(centralPlant) {
|
|
8
|
+
var _centralPlant$getUtil, _centralPlant$manager;
|
|
9
|
+
return (centralPlant === null || centralPlant === void 0 || (_centralPlant$getUtil = centralPlant.getUtility) === null || _centralPlant$getUtil === void 0 || (_centralPlant$getUtil = _centralPlant$getUtil.call(centralPlant, 'modelPreloader')) === null || _centralPlant$getUtil === void 0 ? void 0 : _centralPlant$getUtil.componentDictionary) || (centralPlant === null || centralPlant === void 0 || (_centralPlant$manager = centralPlant.managers) === null || _centralPlant$manager === void 0 || (_centralPlant$manager = _centralPlant$manager.componentDataManager) === null || _centralPlant$manager === void 0 ? void 0 : _centralPlant$manager.componentDictionary) || null;
|
|
10
|
+
}
|
|
11
|
+
function statesFromBehaviorConfig(device) {
|
|
12
|
+
if (!(device !== null && device !== void 0 && device.behaviorConfig) || !Array.isArray(device.behaviorConfig)) return [];
|
|
13
|
+
return device.behaviorConfig.map(function (b) {
|
|
14
|
+
return b.stateVariable;
|
|
15
|
+
}).filter(Boolean).filter(function (v, i, arr) {
|
|
16
|
+
return arr.indexOf(v) === i;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function resolveStatesForDevice(ioObj, deviceId, componentDictionary) {
|
|
20
|
+
var _ioObj$userData;
|
|
21
|
+
var device = componentDictionary === null || componentDictionary === void 0 ? void 0 : componentDictionary[deviceId];
|
|
22
|
+
var fromBehaviorConfig = statesFromBehaviorConfig(device);
|
|
23
|
+
if (fromBehaviorConfig.length) return fromBehaviorConfig;
|
|
24
|
+
return (((_ioObj$userData = ioObj.userData) === null || _ioObj$userData === void 0 ? void 0 : _ioObj$userData.dataPoints) || []).map(function (dp) {
|
|
25
|
+
return dp.id || dp.name;
|
|
26
|
+
}).filter(Boolean).filter(function (v, i, arr) {
|
|
27
|
+
return arr.indexOf(v) === i;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Scan the live Three.js scene for smart-component io-device endpoints.
|
|
33
|
+
*/
|
|
34
|
+
function scanSceneIoEndpoints(centralPlant) {
|
|
35
|
+
var _centralPlant$sceneVi;
|
|
36
|
+
var scene = centralPlant === null || centralPlant === void 0 || (_centralPlant$sceneVi = centralPlant.sceneViewer) === null || _centralPlant$sceneVi === void 0 ? void 0 : _centralPlant$sceneVi.scene;
|
|
37
|
+
if (!scene) return [];
|
|
38
|
+
var dict = getComponentDictionary(centralPlant);
|
|
39
|
+
var endpoints = [];
|
|
40
|
+
scene.traverse(function (obj) {
|
|
41
|
+
var _obj$userData, _parent$userData, _parent$userData2;
|
|
42
|
+
if (((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.objectType) !== 'io-device') return;
|
|
43
|
+
var parent = obj.parent;
|
|
44
|
+
var parentUuid = obj.userData.parentComponentId || (parent === null || parent === void 0 ? void 0 : parent.uuid) || '';
|
|
45
|
+
var parentName = (parent === null || parent === void 0 || (_parent$userData = parent.userData) === null || _parent$userData === void 0 ? void 0 : _parent$userData.hardcodedUuid) || (parent === null || parent === void 0 ? void 0 : parent.name) || parentUuid;
|
|
46
|
+
var libraryId = (parent === null || parent === void 0 || (_parent$userData2 = parent.userData) === null || _parent$userData2 === void 0 ? void 0 : _parent$userData2.libraryId) || '';
|
|
47
|
+
var attachmentId = obj.userData.attachmentId || obj.name || obj.uuid;
|
|
48
|
+
var deviceId = obj.userData.deviceId || '';
|
|
49
|
+
endpoints.push({
|
|
50
|
+
key: getScopedAttachmentKey(attachmentId, parentUuid),
|
|
51
|
+
parentUuid: parentUuid,
|
|
52
|
+
parentName: parentName,
|
|
53
|
+
libraryId: libraryId,
|
|
54
|
+
attachmentId: attachmentId,
|
|
55
|
+
attachmentLabel: obj.userData.attachmentLabel || attachmentId,
|
|
56
|
+
deviceId: deviceId,
|
|
57
|
+
states: resolveStatesForDevice(obj, deviceId, dict)
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
return endpoints;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Load cross-component behaviors from scene data mirrors.
|
|
65
|
+
*/
|
|
66
|
+
function loadCrossComponentBehaviors(centralPlant) {
|
|
67
|
+
var _centralPlant$importe, _centralPlant$sceneVi2;
|
|
68
|
+
return (centralPlant === null || centralPlant === void 0 || (_centralPlant$importe = centralPlant.importedSceneData) === null || _centralPlant$importe === void 0 ? void 0 : _centralPlant$importe.behaviors) || (centralPlant === null || centralPlant === void 0 || (_centralPlant$sceneVi2 = centralPlant.sceneViewer) === null || _centralPlant$sceneVi2 === void 0 || (_centralPlant$sceneVi2 = _centralPlant$sceneVi2.currentSceneData) === null || _centralPlant$sceneVi2 === void 0 ? void 0 : _centralPlant$sceneVi2.behaviors) || [];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Persist cross-component behaviors to scene data mirrors and the runtime manager.
|
|
73
|
+
*/
|
|
74
|
+
function applyCrossComponentBehaviors(centralPlant, behaviors) {
|
|
75
|
+
var normalized = behaviors || [];
|
|
76
|
+
if (centralPlant.importedSceneData) {
|
|
77
|
+
if (normalized.length) {
|
|
78
|
+
centralPlant.importedSceneData.behaviors = normalized;
|
|
79
|
+
} else {
|
|
80
|
+
delete centralPlant.importedSceneData.behaviors;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
var sceneViewer = centralPlant.sceneViewer;
|
|
84
|
+
if (sceneViewer && !sceneViewer.currentSceneData) {
|
|
85
|
+
var _centralPlant$getConn;
|
|
86
|
+
sceneViewer.currentSceneData = {
|
|
87
|
+
version: '2.3',
|
|
88
|
+
connections: ((_centralPlant$getConn = centralPlant.getConnections) === null || _centralPlant$getConn === void 0 ? void 0 : _centralPlant$getConn.call(centralPlant)) || [],
|
|
89
|
+
scene: {
|
|
90
|
+
children: []
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
var currentSceneData = sceneViewer === null || sceneViewer === void 0 ? void 0 : sceneViewer.currentSceneData;
|
|
95
|
+
if (currentSceneData) {
|
|
96
|
+
if (normalized.length) {
|
|
97
|
+
currentSceneData.behaviors = normalized;
|
|
98
|
+
} else {
|
|
99
|
+
delete currentSceneData.behaviors;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
var ioBehavMgr = getIoBehaviorManager(sceneViewer);
|
|
103
|
+
if (ioBehavMgr) {
|
|
104
|
+
ioBehavMgr.setCrossComponentBehaviors(normalized);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Re-register intra-component behaviors on all scene instances of a smart component.
|
|
110
|
+
*/
|
|
111
|
+
function refreshSceneIntraBehaviors(centralPlant, libraryId, behaviors) {
|
|
112
|
+
var _centralPlant$sceneVi3;
|
|
113
|
+
var ioBehavMgr = getIoBehaviorManager(centralPlant === null || centralPlant === void 0 ? void 0 : centralPlant.sceneViewer);
|
|
114
|
+
var scene = centralPlant === null || centralPlant === void 0 || (_centralPlant$sceneVi3 = centralPlant.sceneViewer) === null || _centralPlant$sceneVi3 === void 0 ? void 0 : _centralPlant$sceneVi3.scene;
|
|
115
|
+
if (!ioBehavMgr || !scene || !libraryId) return;
|
|
116
|
+
scene.traverse(function (obj) {
|
|
117
|
+
var _obj$userData2, _obj$userData3;
|
|
118
|
+
if (((_obj$userData2 = obj.userData) === null || _obj$userData2 === void 0 ? void 0 : _obj$userData2.objectType) === 'component' && ((_obj$userData3 = obj.userData) === null || _obj$userData3 === void 0 ? void 0 : _obj$userData3.libraryId) === libraryId) {
|
|
119
|
+
ioBehavMgr.registerComponentBehaviors(obj.uuid, behaviors || []);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Re-register intra- and cross-component behaviors for all instances in the live scene.
|
|
126
|
+
*/
|
|
127
|
+
function reregisterSceneBehaviors(centralPlant) {
|
|
128
|
+
var _centralPlant$sceneVi4;
|
|
129
|
+
var ioBehavMgr = getIoBehaviorManager(centralPlant === null || centralPlant === void 0 ? void 0 : centralPlant.sceneViewer);
|
|
130
|
+
var scene = centralPlant === null || centralPlant === void 0 || (_centralPlant$sceneVi4 = centralPlant.sceneViewer) === null || _centralPlant$sceneVi4 === void 0 ? void 0 : _centralPlant$sceneVi4.scene;
|
|
131
|
+
var dict = getComponentDictionary(centralPlant);
|
|
132
|
+
if (!ioBehavMgr || !scene) return;
|
|
133
|
+
var crossBehaviors = loadCrossComponentBehaviors(centralPlant);
|
|
134
|
+
ioBehavMgr.setCrossComponentBehaviors(crossBehaviors);
|
|
135
|
+
if (!dict) return;
|
|
136
|
+
scene.traverse(function (obj) {
|
|
137
|
+
var _obj$userData4, _obj$userData5;
|
|
138
|
+
if (((_obj$userData4 = obj.userData) === null || _obj$userData4 === void 0 ? void 0 : _obj$userData4.objectType) !== 'component') return;
|
|
139
|
+
var libraryId = (_obj$userData5 = obj.userData) === null || _obj$userData5 === void 0 ? void 0 : _obj$userData5.libraryId;
|
|
140
|
+
if (!libraryId) return;
|
|
141
|
+
var componentData = dict[libraryId];
|
|
142
|
+
if (!componentData) return;
|
|
143
|
+
registerBehaviorsForComponent(ioBehavMgr, obj.uuid, componentData, obj, dict);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export { applyCrossComponentBehaviors, loadCrossComponentBehaviors, refreshSceneIntraBehaviors, reregisterSceneBehaviors, scanSceneIoEndpoints };
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { objectSpread2 as _objectSpread2, slicedToArray as _slicedToArray, typeof as _typeof } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared behavior schema helpers for runtime normalization and UI authoring.
|
|
5
|
+
* Used by IoBehaviorManager and sandbox BehaviorDialog.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Normalize behavior from shorthand to full format.
|
|
10
|
+
* Supports:
|
|
11
|
+
* - input: "attachment.state" → { attachment, state }
|
|
12
|
+
* - outputs: ["attachment.state", ...] → converted to _outputs array
|
|
13
|
+
*
|
|
14
|
+
* @param {Object} behavior - Raw behavior from scene JSON
|
|
15
|
+
* @returns {Object} Normalized behavior
|
|
16
|
+
*/
|
|
17
|
+
function normalizeBehavior(behavior) {
|
|
18
|
+
var normalized = _objectSpread2({}, behavior);
|
|
19
|
+
if (typeof behavior.input === 'string') {
|
|
20
|
+
var _behavior$input$split = behavior.input.split('.'),
|
|
21
|
+
_behavior$input$split2 = _slicedToArray(_behavior$input$split, 2),
|
|
22
|
+
attachment = _behavior$input$split2[0],
|
|
23
|
+
state = _behavior$input$split2[1];
|
|
24
|
+
normalized.input = {
|
|
25
|
+
attachment: attachment,
|
|
26
|
+
state: state
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (behavior.outputs) {
|
|
30
|
+
normalized._outputs = behavior.outputs.map(function (out) {
|
|
31
|
+
if (typeof out === 'string') {
|
|
32
|
+
var _out$split = out.split('.'),
|
|
33
|
+
_out$split2 = _slicedToArray(_out$split, 2),
|
|
34
|
+
_attachment = _out$split2[0],
|
|
35
|
+
_state = _out$split2[1];
|
|
36
|
+
return {
|
|
37
|
+
attachment: _attachment,
|
|
38
|
+
state: _state
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
});
|
|
43
|
+
delete normalized.outputs;
|
|
44
|
+
} else if (typeof behavior.output === 'string') {
|
|
45
|
+
var _behavior$output$spli = behavior.output.split('.'),
|
|
46
|
+
_behavior$output$spli2 = _slicedToArray(_behavior$output$spli, 2),
|
|
47
|
+
_attachment2 = _behavior$output$spli2[0],
|
|
48
|
+
_state2 = _behavior$output$spli2[1];
|
|
49
|
+
normalized.output = {
|
|
50
|
+
attachment: _attachment2,
|
|
51
|
+
state: _state2
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return normalized;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Build intra-component shorthand behavior from form fields.
|
|
59
|
+
*/
|
|
60
|
+
function buildIntraBehavior(_ref) {
|
|
61
|
+
var id = _ref.id,
|
|
62
|
+
inputAttachment = _ref.inputAttachment,
|
|
63
|
+
inputState = _ref.inputState,
|
|
64
|
+
outputs = _ref.outputs;
|
|
65
|
+
return {
|
|
66
|
+
id: id || "behavior-".concat(Date.now()),
|
|
67
|
+
input: "".concat(inputAttachment, ".").concat(inputState),
|
|
68
|
+
outputs: outputs.filter(function (o) {
|
|
69
|
+
return o.attachment && o.state;
|
|
70
|
+
}).map(function (o) {
|
|
71
|
+
return "".concat(o.attachment, ".").concat(o.state);
|
|
72
|
+
})
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Parse intra-component shorthand into form fields.
|
|
78
|
+
*/
|
|
79
|
+
function parseIntraBehavior(behavior) {
|
|
80
|
+
var inputAttachment = null;
|
|
81
|
+
var inputState = null;
|
|
82
|
+
if (typeof behavior.input === 'string') {
|
|
83
|
+
var _behavior$input$split3 = behavior.input.split('.');
|
|
84
|
+
var _behavior$input$split4 = _slicedToArray(_behavior$input$split3, 2);
|
|
85
|
+
inputAttachment = _behavior$input$split4[0];
|
|
86
|
+
inputState = _behavior$input$split4[1];
|
|
87
|
+
} else if (behavior.input && _typeof(behavior.input) === 'object') {
|
|
88
|
+
inputAttachment = behavior.input.attachment || null;
|
|
89
|
+
inputState = behavior.input.state || null;
|
|
90
|
+
}
|
|
91
|
+
var outputs = (behavior.outputs || []).map(function (out) {
|
|
92
|
+
if (typeof out === 'string') {
|
|
93
|
+
var _out$split3 = out.split('.'),
|
|
94
|
+
_out$split4 = _slicedToArray(_out$split3, 2),
|
|
95
|
+
attachment = _out$split4[0],
|
|
96
|
+
state = _out$split4[1];
|
|
97
|
+
return {
|
|
98
|
+
attachment: attachment,
|
|
99
|
+
state: state
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
attachment: (out === null || out === void 0 ? void 0 : out.attachment) || null,
|
|
104
|
+
state: (out === null || out === void 0 ? void 0 : out.state) || null
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
return {
|
|
108
|
+
id: behavior.id || '',
|
|
109
|
+
inputAttachment: inputAttachment || null,
|
|
110
|
+
inputState: inputState || null,
|
|
111
|
+
outputs: outputs.length ? outputs : [{
|
|
112
|
+
attachment: null,
|
|
113
|
+
state: null
|
|
114
|
+
}]
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Build cross-component behavior with component instance scoping.
|
|
120
|
+
*/
|
|
121
|
+
function buildCrossBehavior(_ref2) {
|
|
122
|
+
var id = _ref2.id,
|
|
123
|
+
inputEndpoint = _ref2.inputEndpoint,
|
|
124
|
+
inputState = _ref2.inputState,
|
|
125
|
+
outputs = _ref2.outputs;
|
|
126
|
+
var _split = (inputEndpoint || '').split('::'),
|
|
127
|
+
_split2 = _slicedToArray(_split, 2),
|
|
128
|
+
inputComponent = _split2[0],
|
|
129
|
+
inputAttachment = _split2[1];
|
|
130
|
+
return {
|
|
131
|
+
id: id || "behavior-".concat(Date.now()),
|
|
132
|
+
input: {
|
|
133
|
+
component: inputComponent,
|
|
134
|
+
attachment: inputAttachment,
|
|
135
|
+
state: inputState
|
|
136
|
+
},
|
|
137
|
+
outputs: outputs.filter(function (o) {
|
|
138
|
+
return o.endpoint && o.state;
|
|
139
|
+
}).map(function (o) {
|
|
140
|
+
var _o$endpoint$split = o.endpoint.split('::'),
|
|
141
|
+
_o$endpoint$split2 = _slicedToArray(_o$endpoint$split, 2),
|
|
142
|
+
component = _o$endpoint$split2[0],
|
|
143
|
+
attachment = _o$endpoint$split2[1];
|
|
144
|
+
return {
|
|
145
|
+
component: component,
|
|
146
|
+
attachment: attachment,
|
|
147
|
+
state: o.state
|
|
148
|
+
};
|
|
149
|
+
})
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Parse cross-component behavior into form fields.
|
|
155
|
+
*/
|
|
156
|
+
function parseCrossBehavior(behavior) {
|
|
157
|
+
var inputComponent, inputAttachment, inputState;
|
|
158
|
+
if (typeof behavior.input === 'string') {
|
|
159
|
+
var _behavior$input$split5 = behavior.input.split('.'),
|
|
160
|
+
_behavior$input$split6 = _slicedToArray(_behavior$input$split5, 2),
|
|
161
|
+
attachment = _behavior$input$split6[0],
|
|
162
|
+
state = _behavior$input$split6[1];
|
|
163
|
+
inputAttachment = attachment;
|
|
164
|
+
inputState = state;
|
|
165
|
+
inputComponent = null;
|
|
166
|
+
} else if (behavior.input) {
|
|
167
|
+
inputComponent = behavior.input.component;
|
|
168
|
+
inputAttachment = behavior.input.attachment;
|
|
169
|
+
inputState = behavior.input.state;
|
|
170
|
+
}
|
|
171
|
+
var rawOutputs = behavior.outputs || (behavior.output ? [behavior.output] : behavior._outputs || []);
|
|
172
|
+
var outputs = rawOutputs.map(function (out) {
|
|
173
|
+
if (typeof out === 'string') {
|
|
174
|
+
var _out$split5 = out.split('.'),
|
|
175
|
+
_out$split6 = _slicedToArray(_out$split5, 2),
|
|
176
|
+
_attachment3 = _out$split6[0],
|
|
177
|
+
_state3 = _out$split6[1];
|
|
178
|
+
return {
|
|
179
|
+
endpoint: _attachment3 ? "::".concat(_attachment3) : null,
|
|
180
|
+
state: _state3
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
var endpoint = out.component && out.attachment ? "".concat(out.component, "::").concat(out.attachment) : out.attachment ? "::".concat(out.attachment) : null;
|
|
184
|
+
return {
|
|
185
|
+
endpoint: endpoint,
|
|
186
|
+
state: out.state || null
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
var inputEndpoint = inputComponent && inputAttachment ? "".concat(inputComponent, "::").concat(inputAttachment) : inputAttachment ? "::".concat(inputAttachment) : null;
|
|
190
|
+
return {
|
|
191
|
+
id: behavior.id || '',
|
|
192
|
+
inputEndpoint: inputEndpoint,
|
|
193
|
+
inputState: inputState || null,
|
|
194
|
+
outputs: outputs.length ? outputs : [{
|
|
195
|
+
endpoint: null,
|
|
196
|
+
state: null
|
|
197
|
+
}]
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export { buildCrossBehavior, buildIntraBehavior, normalizeBehavior, parseCrossBehavior, parseIntraBehavior };
|
package/dist/index.d.ts
CHANGED
|
@@ -30,8 +30,9 @@ export interface IoDeviceState {
|
|
|
30
30
|
id: string
|
|
31
31
|
name: string
|
|
32
32
|
defaultValue: any
|
|
33
|
-
stateType: 'binary' | 'number' | 'enum' | 'float' | 'string'
|
|
33
|
+
stateType: 'binary' | 'number' | 'enum' | 'float' | 'string' | 'continuous' | 'boolean'
|
|
34
34
|
stateConfig?: Record<string, any>
|
|
35
|
+
direction?: 'input' | 'output'
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
export interface IoDeviceConfig {
|
|
@@ -39,11 +40,57 @@ export interface IoDeviceConfig {
|
|
|
39
40
|
states: IoDeviceState[]
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
export interface BehaviorMapping {
|
|
44
|
+
stateValue: any
|
|
45
|
+
transform?: { x?: number; y?: number; z?: number }
|
|
46
|
+
rotationTransform?: number
|
|
47
|
+
colorTransform?: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface BehaviorEntry {
|
|
51
|
+
name?: string
|
|
52
|
+
meshUuid?: string
|
|
53
|
+
meshName?: string
|
|
54
|
+
stateVariable: string
|
|
55
|
+
stateType?: 'binary' | 'enum' | 'continuous' | 'number' | 'boolean'
|
|
56
|
+
transformTypes?: string[]
|
|
57
|
+
rotAxis?: 'x' | 'y' | 'z'
|
|
58
|
+
rotAxisOffset?: { x: number; y: number; z: number }
|
|
59
|
+
mappingAxis?: 'x' | 'y' | 'z'
|
|
60
|
+
mappings?: BehaviorMapping[]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface CrossComponentBehavior {
|
|
64
|
+
id?: string
|
|
65
|
+
input: string | { component?: string; attachment: string; state: string }
|
|
66
|
+
output?: string | { component?: string; attachment: string; state: string; child?: string }
|
|
67
|
+
outputs?: Array<string | { component?: string; attachment: string; state: string; child?: string }>
|
|
68
|
+
conditions?: Array<{ expression: string }>
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface IoStateAdapter {
|
|
72
|
+
getState(attachmentId: string, dataPointId: string): any
|
|
73
|
+
setState(attachmentId: string, dataPointId: string, value: any): void
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface SceneIoEndpoint {
|
|
77
|
+
key: string
|
|
78
|
+
parentUuid: string
|
|
79
|
+
parentName: string
|
|
80
|
+
libraryId: string
|
|
81
|
+
attachmentId: string
|
|
82
|
+
attachmentLabel: string
|
|
83
|
+
deviceId: string
|
|
84
|
+
states: string[]
|
|
85
|
+
}
|
|
86
|
+
|
|
42
87
|
export interface IoDeviceAsset {
|
|
43
88
|
uuid: string
|
|
44
89
|
name: string
|
|
45
90
|
assetType: 'I/O Device'
|
|
46
91
|
ioConfig: IoDeviceConfig
|
|
92
|
+
behaviorConfig?: BehaviorEntry[]
|
|
93
|
+
meshNameMap?: Record<string, string>
|
|
47
94
|
}
|
|
48
95
|
|
|
49
96
|
export interface AttachmentDescriptor {
|
|
@@ -68,9 +115,122 @@ export interface SmartComponentAsset {
|
|
|
68
115
|
attachmentPoint: AttachmentDescriptor['attachmentPoint'] | null
|
|
69
116
|
attachedAt: string
|
|
70
117
|
}>
|
|
118
|
+
behaviors?: CrossComponentBehavior[]
|
|
71
119
|
[key: string]: any
|
|
72
120
|
}
|
|
73
121
|
|
|
122
|
+
export declare function normalizeBehavior(behavior: CrossComponentBehavior): CrossComponentBehavior
|
|
123
|
+
export declare function buildIntraBehavior(form: {
|
|
124
|
+
id?: string
|
|
125
|
+
inputAttachment: string
|
|
126
|
+
inputState: string
|
|
127
|
+
outputs: Array<{ attachment: string; state: string }>
|
|
128
|
+
}): CrossComponentBehavior
|
|
129
|
+
export declare function parseIntraBehavior(behavior: CrossComponentBehavior): {
|
|
130
|
+
id: string
|
|
131
|
+
inputAttachment: string
|
|
132
|
+
inputState: string
|
|
133
|
+
outputs: Array<{ attachment: string; state: string }>
|
|
134
|
+
}
|
|
135
|
+
export declare function buildCrossBehavior(form: {
|
|
136
|
+
id?: string
|
|
137
|
+
inputEndpoint: string
|
|
138
|
+
inputState: string
|
|
139
|
+
outputs: Array<{ endpoint: string; state: string }>
|
|
140
|
+
}): CrossComponentBehavior
|
|
141
|
+
export declare function parseCrossBehavior(behavior: CrossComponentBehavior): {
|
|
142
|
+
id: string
|
|
143
|
+
inputEndpoint: string
|
|
144
|
+
inputState: string
|
|
145
|
+
outputs: Array<{ endpoint: string; state: string }>
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export declare function getScopedAttachmentKey(attachmentId: string, parentUuid?: string | null): string
|
|
149
|
+
export declare function getIoBehaviorManager(sceneViewer: any): IoBehaviorManager | null
|
|
150
|
+
export declare function resolveDataPoints(
|
|
151
|
+
parentUuid: string,
|
|
152
|
+
attachmentId: string,
|
|
153
|
+
userData: Record<string, any>,
|
|
154
|
+
ioBehaviorManager: IoBehaviorManager | null,
|
|
155
|
+
hitMesh?: any
|
|
156
|
+
): IoDeviceState[]
|
|
157
|
+
|
|
158
|
+
export declare function registerBehaviorsForComponent(
|
|
159
|
+
ioBehavMgr: IoBehaviorManager,
|
|
160
|
+
componentUuid: string,
|
|
161
|
+
componentData: SmartComponentAsset,
|
|
162
|
+
componentModel: any,
|
|
163
|
+
componentDictionary: Record<string, any>
|
|
164
|
+
): void
|
|
165
|
+
|
|
166
|
+
export declare function reloadBehaviorsForDeviceAsset(
|
|
167
|
+
ioBehavMgr: IoBehaviorManager,
|
|
168
|
+
deviceAssetId: string,
|
|
169
|
+
componentDictionary: Record<string, any>,
|
|
170
|
+
centralPlant: any
|
|
171
|
+
): void
|
|
172
|
+
|
|
173
|
+
export declare function scanSceneIoEndpoints(centralPlant: any): SceneIoEndpoint[]
|
|
174
|
+
export declare function applyCrossComponentBehaviors(centralPlant: any, behaviors: CrossComponentBehavior[]): void
|
|
175
|
+
export declare function loadCrossComponentBehaviors(centralPlant: any): CrossComponentBehavior[]
|
|
176
|
+
export declare function refreshSceneIntraBehaviors(centralPlant: any, libraryId: string, behaviors: CrossComponentBehavior[]): void
|
|
177
|
+
export declare function reregisterSceneBehaviors(centralPlant: any): void
|
|
178
|
+
|
|
179
|
+
export declare function modelOffsetToWorldDelta(
|
|
180
|
+
modelRoot: any,
|
|
181
|
+
offset: { x?: number; y?: number; z?: number } | { clone(): any }
|
|
182
|
+
): any
|
|
183
|
+
export declare function applyModelRootTranslation(
|
|
184
|
+
mesh: any,
|
|
185
|
+
modelRoot: any,
|
|
186
|
+
origLocalPos: any,
|
|
187
|
+
modelOffset: { x?: number; y?: number; z?: number }
|
|
188
|
+
): void
|
|
189
|
+
export declare function applyModelRootTranslationFromWorldBase(
|
|
190
|
+
mesh: any,
|
|
191
|
+
modelRoot: any,
|
|
192
|
+
baseWorldPos: any,
|
|
193
|
+
modelOffset: { x?: number; y?: number; z?: number }
|
|
194
|
+
): void
|
|
195
|
+
|
|
196
|
+
export declare class IoBehaviorManager {
|
|
197
|
+
constructor(sceneViewer: any)
|
|
198
|
+
loadBehaviors(attachmentId: string, behaviorConfig: BehaviorEntry[] | { behaviors: BehaviorEntry[] }, deviceModelRoot: any, parentUuid: string): void
|
|
199
|
+
triggerState(attachmentId: string, dataPointId: string, value: any, parentUuid?: string | null): void
|
|
200
|
+
setCrossComponentBehaviors(behaviors: CrossComponentBehavior[]): void
|
|
201
|
+
registerComponentBehaviors(componentUuid: string, behaviors: CrossComponentBehavior[]): void
|
|
202
|
+
configure(stateAdapter: IoStateAdapter): void
|
|
203
|
+
getAnimationDataPoints(parentUuid: string, attachmentId: string, hitMesh?: any): IoDeviceState[]
|
|
204
|
+
getAnimatedMeshes(parentUuid: string, attachmentId: string): any[]
|
|
205
|
+
unloadForComponent(parentUuid: string): void
|
|
206
|
+
unloadForAttachment(parentUuid: string, attachmentId: string): void
|
|
207
|
+
resetForScene(): void
|
|
208
|
+
dispose(): void
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export declare class ComponentTooltipManager {
|
|
212
|
+
constructor(sceneViewer: any)
|
|
213
|
+
configure(stateAdapter: IoStateAdapter): void
|
|
214
|
+
onSelectionChanged(object: any | null): void
|
|
215
|
+
update(): void
|
|
216
|
+
hide(): void
|
|
217
|
+
dispose(): void
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface CentralPlantBehaviorApi {
|
|
221
|
+
configureStateAdapter(adapter: IoStateAdapter): void
|
|
222
|
+
setIoDeviceState(attachmentId: string, stateId: string, value: any, parentUuid?: string | null): void
|
|
223
|
+
mergeBehaviorConfigsIntoDictionary(configsByAssetId: Record<string, {
|
|
224
|
+
behaviorConfig?: BehaviorEntry[]
|
|
225
|
+
meshNameMap?: Record<string, string>
|
|
226
|
+
behaviors?: CrossComponentBehavior[]
|
|
227
|
+
}>): number
|
|
228
|
+
scanSceneIoEndpoints(): SceneIoEndpoint[]
|
|
229
|
+
setSceneBehaviors(behaviors: CrossComponentBehavior[]): void
|
|
230
|
+
getSceneBehaviors(): CrossComponentBehavior[]
|
|
231
|
+
reregisterSceneBehaviors(): void
|
|
232
|
+
}
|
|
233
|
+
|
|
74
234
|
export interface IoDeviceUsageEntry {
|
|
75
235
|
componentId: string
|
|
76
236
|
componentName: string
|
|
@@ -140,6 +300,31 @@ export declare class PathFlowManager {
|
|
|
140
300
|
|
|
141
301
|
// ─── Re-exports ───────────────────────────────────────────────────────────────
|
|
142
302
|
export { CentralPlant } from './core/centralPlant.js';
|
|
303
|
+
export { IoBehaviorManager } from './managers/behaviors/IoBehaviorManager.js';
|
|
304
|
+
export { ComponentTooltipManager } from './managers/scene/componentTooltipManager.js';
|
|
305
|
+
export {
|
|
306
|
+
normalizeBehavior,
|
|
307
|
+
buildIntraBehavior,
|
|
308
|
+
parseIntraBehavior,
|
|
309
|
+
buildCrossBehavior,
|
|
310
|
+
parseCrossBehavior
|
|
311
|
+
} from './utils/behaviorSchema.js';
|
|
312
|
+
export {
|
|
313
|
+
registerBehaviorsForComponent,
|
|
314
|
+
reloadBehaviorsForDeviceAsset
|
|
315
|
+
} from './utils/behaviorRegistration.js';
|
|
316
|
+
export {
|
|
317
|
+
getScopedAttachmentKey,
|
|
318
|
+
getIoBehaviorManager,
|
|
319
|
+
resolveDataPoints
|
|
320
|
+
} from './utils/behaviorDispatch.js';
|
|
321
|
+
export {
|
|
322
|
+
scanSceneIoEndpoints,
|
|
323
|
+
applyCrossComponentBehaviors,
|
|
324
|
+
loadCrossComponentBehaviors,
|
|
325
|
+
refreshSceneIntraBehaviors,
|
|
326
|
+
reregisterSceneBehaviors
|
|
327
|
+
} from './utils/behaviorSceneUtils.js';
|
|
143
328
|
export { DebugLogger, logger, transformLogger, pathfinderLogger, modelLogger } from './core/debugLogger.js';
|
|
144
329
|
export { generateUuidFromName, getHardcodedUuid, findObjectByHardcodedUuid } from './core/nameUtils.js';
|
|
145
330
|
|