@buerli.io/core 0.13.1-beta.8.apiversion → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +19 -12
  2. package/build/cjs/geometry/ThreeGeometryCreator.js +320 -320
  3. package/build/cjs/geometry/index.js +17 -17
  4. package/build/cjs/graphic/filters.js +25 -25
  5. package/build/cjs/index.js +26 -26
  6. package/build/cjs/re-export.js +29 -29
  7. package/build/cjs/store/index.js +37 -37
  8. package/build/cjs/store/states/buerli.js +98 -98
  9. package/build/cjs/store/states/cad.js +47 -47
  10. package/build/cjs/store/states/drawing.js +49 -49
  11. package/build/cjs/store/states/geometry.js +157 -157
  12. package/build/cjs/store/states/graphic.js +115 -115
  13. package/build/cjs/store/states/interaction.js +55 -55
  14. package/build/cjs/store/states/message.js +25 -25
  15. package/build/cjs/store/states/plugin.js +115 -115
  16. package/build/cjs/store/states/selection.js +267 -267
  17. package/build/cjs/store/states/structure.js +250 -250
  18. package/build/cjs/store/store.js +9 -9
  19. package/build/cjs/store/subscribtion/selection.js +49 -49
  20. package/build/cjs/store/subscribtion/subscribeToDrawing.js +13 -13
  21. package/build/cjs/types/InteractionInfo.js +11 -11
  22. package/build/cjs/types/index.js +34 -34
  23. package/build/cjs/utils/Math.js +91 -91
  24. package/build/cjs/utils/Measure.js +576 -576
  25. package/build/cjs/utils/Timing.js +34 -34
  26. package/build/esm/geometry/ThreeGeometryCreator.js +291 -291
  27. package/build/esm/geometry/index.js +1 -1
  28. package/build/esm/graphic/filters.js +12 -12
  29. package/build/esm/index.js +10 -10
  30. package/build/esm/re-export.js +23 -23
  31. package/build/esm/store/index.js +26 -26
  32. package/build/esm/store/states/buerli.js +92 -92
  33. package/build/esm/store/states/cad.js +42 -42
  34. package/build/esm/store/states/drawing.js +45 -45
  35. package/build/esm/store/states/geometry.js +129 -129
  36. package/build/esm/store/states/graphic.js +110 -110
  37. package/build/esm/store/states/interaction.js +50 -50
  38. package/build/esm/store/states/message.js +21 -21
  39. package/build/esm/store/states/plugin.js +109 -109
  40. package/build/esm/store/states/selection.js +261 -261
  41. package/build/esm/store/states/structure.js +219 -219
  42. package/build/esm/store/store.js +3 -3
  43. package/build/esm/store/subscribtion/selection.js +44 -44
  44. package/build/esm/store/subscribtion/subscribeToDrawing.js +9 -9
  45. package/build/esm/types/InteractionInfo.js +6 -6
  46. package/build/esm/types/index.js +16 -16
  47. package/build/esm/utils/Math.js +65 -65
  48. package/build/esm/utils/Measure.js +550 -550
  49. package/build/esm/utils/Timing.js +31 -31
  50. package/build/types/geometry/ThreeGeometryCreator.d.ts +256 -256
  51. package/build/types/geometry/index.d.ts +1 -1
  52. package/build/types/graphic/filters.d.ts +11 -11
  53. package/build/types/index.d.ts +38 -38
  54. package/build/types/re-export.d.ts +70 -70
  55. package/build/types/store/index.d.ts +16 -16
  56. package/build/types/store/states/buerli.d.ts +41 -41
  57. package/build/types/store/states/cad.d.ts +56 -53
  58. package/build/types/store/states/drawing.d.ts +45 -45
  59. package/build/types/store/states/geometry.d.ts +64 -64
  60. package/build/types/store/states/graphic.d.ts +21 -21
  61. package/build/types/store/states/interaction.d.ts +34 -34
  62. package/build/types/store/states/message.d.ts +30 -30
  63. package/build/types/store/states/plugin.d.ts +53 -53
  64. package/build/types/store/states/selection.d.ts +69 -69
  65. package/build/types/store/states/structure.d.ts +47 -47
  66. package/build/types/store/store.d.ts +2 -2
  67. package/build/types/store/subscribtion/selection.d.ts +7 -7
  68. package/build/types/store/subscribtion/subscribeToDrawing.d.ts +4 -4
  69. package/build/types/types/InteractionInfo.d.ts +42 -42
  70. package/build/types/types/index.d.ts +7 -7
  71. package/build/types/utils/Math.d.ts +21 -21
  72. package/build/types/utils/Measure.d.ts +64 -64
  73. package/build/types/utils/Timing.d.ts +8 -8
  74. package/package.json +45 -45
  75. package/CHANGELOG.md +0 -7
@@ -1,219 +1,219 @@
1
- import fastpatch from 'fast-json-patch';
2
- import jsonpatch from 'jsonpatch';
3
- import * as THREE from 'three';
4
- import { DEFAULT_STRUCTURE_TREE } from '../../types';
5
- import { MathUtils } from '../../utils/Math';
6
- ////////////////////////////////////////////////////
7
- // DATA
8
- ////////////////////////////////////////////////////
9
- export const structureData = () => {
10
- return Object.assign(Object.assign({}, DEFAULT_STRUCTURE_TREE()), { visibleContainers: [], products: [] });
11
- };
12
- ////////////////////////////////////////////////////
13
- // API
14
- ////////////////////////////////////////////////////
15
- export const structureApi = (set, get, buerliApi) => ({
16
- get: () => {
17
- return get().structure;
18
- },
19
- set: (structure) => {
20
- const { api } = get();
21
- // TODO: clear object selection if needed
22
- // 1. set the state
23
- set({
24
- structure: Object.assign(Object.assign({}, get().structure), structure),
25
- });
26
- // 2. collect and cleanup data
27
- api.graphic.cleanupGraphicRecords();
28
- // console.log('cleanup')
29
- api.structure.postProcessStructureUpdate();
30
- },
31
- applyPatches: (patches) => {
32
- const before = get().structure.products.concat(get().structure.visibleContainers);
33
- const applyBlock = (block) => {
34
- if (block.length === 0)
35
- return;
36
- set(state => {
37
- let structure = state.structure;
38
- try {
39
- // TODO: keep an eye on the patch behaviour in general.
40
- // For large changes 'fast-json-patch' is much more performant than 'jsonpatch'.
41
- // However, for smaller changes 'jsonpatch' is more performant than 'fast-json-patch'.
42
- if (block.length > 100) {
43
- structure = fastpatch.applyPatch(state.structure, block, false, false).newDocument;
44
- }
45
- else {
46
- structure = jsonpatch.apply_patch(state.structure, block);
47
- }
48
- }
49
- catch (e) {
50
- console.error(e);
51
- }
52
- // console.info('currentProduct in new patched structure: ', structure.currentProduct)
53
- return { structure: Object.assign(Object.assign({}, state.structure), structure) };
54
- });
55
- };
56
- const treePatches = [];
57
- const otherPatches = [];
58
- for (const patch of patches) {
59
- if (patch.path.startsWith('/tree/')) {
60
- treePatches.push(patch);
61
- }
62
- else {
63
- otherPatches.push(patch);
64
- }
65
- }
66
- // console.info(JSON.stringify(otherPatches))
67
- //////////////////////////////////////////////////////////////////////////////
68
- // The following split of the state update helps very much in some cases to
69
- // prevent not existing object access in many React hooks.
70
- // 1. Perform meta information update as the first step (root, currentProduct, ...)
71
- applyBlock(otherPatches);
72
- // 2. Perform tree update as a second, separate step
73
- applyBlock(treePatches);
74
- // TODO: The update behaviour for structure updates in buerli/zustand/react-hooks
75
- // has to be analyzed in more detail based on a very simple example.
76
- //////////////////////////////////////////////////////////////////////////////
77
- const { api } = get();
78
- api.structure.postProcessStructureUpdate();
79
- // Update the bounds, but only if products or visible containers changed.
80
- const after = get().structure.products.concat(get().structure.visibleContainers);
81
- if (before.sort().join() !== after.sort().join()) {
82
- api.geometry.updateBounds();
83
- }
84
- },
85
- filterTree: (tree, filter) => {
86
- const objs = [];
87
- const keys = Object.getOwnPropertyNames(tree);
88
- for (const key of keys) {
89
- const obj = tree[key];
90
- if (filter(obj)) {
91
- objs.push(obj);
92
- }
93
- }
94
- return objs;
95
- },
96
- findTree: (tree, filter) => {
97
- const keys = Object.getOwnPropertyNames(tree);
98
- for (const key of keys) {
99
- const obj = tree[key];
100
- if (filter(obj)) {
101
- return obj;
102
- }
103
- }
104
- return undefined;
105
- },
106
- collectUsedSolidIds: () => {
107
- const { api, structure } = get();
108
- const solidObjs = api.structure.filterTree(structure.tree, obj => typeof obj.geometryIdList !== 'undefined');
109
- const solidIds = [];
110
- solidObjs.forEach(solidObj => solidIds.push(...(solidObj.geometryIdList || [])));
111
- return solidIds;
112
- },
113
- collectProducts: (root) => {
114
- const { structure } = get();
115
- const products = [];
116
- const recursive = (id) => {
117
- const obj = structure.tree[id];
118
- if (obj) {
119
- if ((obj.solids && obj.solids.length > 0) || obj.link) {
120
- products.push(obj);
121
- }
122
- if (obj.children) {
123
- for (const child of obj.children) {
124
- recursive(child);
125
- }
126
- }
127
- }
128
- };
129
- recursive(root);
130
- return products;
131
- },
132
- getProductSolidIds: (productId) => {
133
- const { structure } = get();
134
- let solids;
135
- const product = structure.tree[productId];
136
- if (product.link !== undefined) {
137
- solids = structure.tree[product.link].solids || [];
138
- }
139
- else {
140
- solids = product.solids || [];
141
- }
142
- return [...solids];
143
- },
144
- postProcessStructureUpdate: () => {
145
- const { api, structure } = get();
146
- //////////
147
- // 1. Collect the products
148
- //////////
149
- const searchRoot = structure.root; // || structure.currentInstance || structure.currentProduct
150
- const productIds = api.structure.collectProducts(searchRoot).map(p => p.id);
151
- //////////
152
- // 2. Collect the solid ids
153
- //////////
154
- let solidIds = [];
155
- productIds.forEach(prodId => solidIds.push(...(api.structure.getProductSolidIds(prodId) || [])));
156
- // remove duplicates
157
- solidIds = solidIds.filter((item, index) => solidIds.indexOf(item) === index);
158
- //////////
159
- // 3. Add the result to the state
160
- //////////
161
- set(state => ({
162
- structure: Object.assign(Object.assign({}, state.structure), { visibleContainers: solidIds, products: productIds }),
163
- }));
164
- },
165
- /**
166
- * Calculates the global transformation matrix for the given _objectId_.
167
- *
168
- * @param objectId The object to calculate the global transformation for.
169
- * @param matrix The initial matrix (mainly used for recursion). It is an out parameter and in the end, it will contain the same matrix as the return value of this function.
170
- * @returns The global transformation matrix for the given _objectId_.
171
- */
172
- calculateGlobalTransformation: (objectId, matrix = new THREE.Matrix4().identity()) => {
173
- const { structure, api } = get();
174
- const { tree, root } = structure;
175
- const obj = tree[objectId];
176
- if (obj && obj.coordinateSystem) {
177
- const objMatrix = MathUtils.convertToMatrix4(obj.coordinateSystem);
178
- matrix = matrix.clone().premultiply(objMatrix);
179
- }
180
- if (objectId !== root && obj.parent) {
181
- matrix = api.structure.calculateGlobalTransformation(obj.parent, matrix);
182
- }
183
- return matrix;
184
- },
185
- calculateProductBounds: (productId, base) => {
186
- const { graphic, api } = get();
187
- const posInf = Number.POSITIVE_INFINITY;
188
- const negInf = Number.NEGATIVE_INFINITY;
189
- const baseMin = base ? base.min.clone() : new THREE.Vector3(posInf, posInf, posInf);
190
- const baseMax = base ? base.max.clone() : new THREE.Vector3(negInf, negInf, negInf);
191
- let box = new THREE.Box3(baseMin, baseMax);
192
- const productIds = api.structure.collectProducts(productId).map(p => p.id);
193
- for (const pId of productIds) {
194
- const matrix = api.structure.calculateGlobalTransformation(pId);
195
- const contIds = api.structure.getProductSolidIds(pId);
196
- for (const contId of contIds) {
197
- const cont = graphic.containers[contId];
198
- if (cont) {
199
- const min = new THREE.Vector3().fromArray(cont.properties.min);
200
- const max = new THREE.Vector3().fromArray(cont.properties.max);
201
- const b = new THREE.Box3(min.clone(), max.clone());
202
- b.applyMatrix4(matrix);
203
- box = box.union(b);
204
- }
205
- }
206
- }
207
- const sphere = new THREE.Sphere();
208
- box.getBoundingSphere(sphere);
209
- return { center: sphere.center, radius: sphere.radius, max: box.max, min: box.min };
210
- },
211
- /**
212
- * This is a workaround to get the corresponding drawing id via API.
213
- *
214
- * > !!! Should not be used in user code !!!
215
- *
216
- * @returns The drawing id.
217
- */
218
- getDrawingId: () => get().id,
219
- });
1
+ import fastpatch from 'fast-json-patch';
2
+ import jsonpatch from 'jsonpatch';
3
+ import * as THREE from 'three';
4
+ import { DEFAULT_STRUCTURE_TREE } from '../../types';
5
+ import { MathUtils } from '../../utils/Math';
6
+ ////////////////////////////////////////////////////
7
+ // DATA
8
+ ////////////////////////////////////////////////////
9
+ export const structureData = () => {
10
+ return Object.assign(Object.assign({}, DEFAULT_STRUCTURE_TREE()), { visibleContainers: [], products: [] });
11
+ };
12
+ ////////////////////////////////////////////////////
13
+ // API
14
+ ////////////////////////////////////////////////////
15
+ export const structureApi = (set, get, buerliApi) => ({
16
+ get: () => {
17
+ return get().structure;
18
+ },
19
+ set: (structure) => {
20
+ const { api } = get();
21
+ // TODO: clear object selection if needed
22
+ // 1. set the state
23
+ set({
24
+ structure: Object.assign(Object.assign({}, get().structure), structure),
25
+ });
26
+ // 2. collect and cleanup data
27
+ api.graphic.cleanupGraphicRecords();
28
+ // console.log('cleanup')
29
+ api.structure.postProcessStructureUpdate();
30
+ },
31
+ applyPatches: (patches) => {
32
+ const before = get().structure.products.concat(get().structure.visibleContainers);
33
+ const applyBlock = (block) => {
34
+ if (block.length === 0)
35
+ return;
36
+ set(state => {
37
+ let structure = state.structure;
38
+ try {
39
+ // TODO: keep an eye on the patch behaviour in general.
40
+ // For large changes 'fast-json-patch' is much more performant than 'jsonpatch'.
41
+ // However, for smaller changes 'jsonpatch' is more performant than 'fast-json-patch'.
42
+ if (block.length > 100) {
43
+ structure = fastpatch.applyPatch(state.structure, block, false, false).newDocument;
44
+ }
45
+ else {
46
+ structure = jsonpatch.apply_patch(state.structure, block);
47
+ }
48
+ }
49
+ catch (e) {
50
+ console.error(e);
51
+ }
52
+ // console.info('currentProduct in new patched structure: ', structure.currentProduct)
53
+ return { structure: Object.assign(Object.assign({}, state.structure), structure) };
54
+ });
55
+ };
56
+ const treePatches = [];
57
+ const otherPatches = [];
58
+ for (const patch of patches) {
59
+ if (patch.path.startsWith('/tree/')) {
60
+ treePatches.push(patch);
61
+ }
62
+ else {
63
+ otherPatches.push(patch);
64
+ }
65
+ }
66
+ // console.info(JSON.stringify(otherPatches))
67
+ //////////////////////////////////////////////////////////////////////////////
68
+ // The following split of the state update helps very much in some cases to
69
+ // prevent not existing object access in many React hooks.
70
+ // 1. Perform meta information update as the first step (root, currentProduct, ...)
71
+ applyBlock(otherPatches);
72
+ // 2. Perform tree update as a second, separate step
73
+ applyBlock(treePatches);
74
+ // TODO: The update behaviour for structure updates in buerli/zustand/react-hooks
75
+ // has to be analyzed in more detail based on a very simple example.
76
+ //////////////////////////////////////////////////////////////////////////////
77
+ const { api } = get();
78
+ api.structure.postProcessStructureUpdate();
79
+ // Update the bounds, but only if products or visible containers changed.
80
+ const after = get().structure.products.concat(get().structure.visibleContainers);
81
+ if (before.sort().join() !== after.sort().join()) {
82
+ api.geometry.updateBounds();
83
+ }
84
+ },
85
+ filterTree: (tree, filter) => {
86
+ const objs = [];
87
+ const keys = Object.getOwnPropertyNames(tree);
88
+ for (const key of keys) {
89
+ const obj = tree[key];
90
+ if (filter(obj)) {
91
+ objs.push(obj);
92
+ }
93
+ }
94
+ return objs;
95
+ },
96
+ findTree: (tree, filter) => {
97
+ const keys = Object.getOwnPropertyNames(tree);
98
+ for (const key of keys) {
99
+ const obj = tree[key];
100
+ if (filter(obj)) {
101
+ return obj;
102
+ }
103
+ }
104
+ return undefined;
105
+ },
106
+ collectUsedSolidIds: () => {
107
+ const { api, structure } = get();
108
+ const solidObjs = api.structure.filterTree(structure.tree, obj => typeof obj.geometryIdList !== 'undefined');
109
+ const solidIds = [];
110
+ solidObjs.forEach(solidObj => solidIds.push(...(solidObj.geometryIdList || [])));
111
+ return solidIds;
112
+ },
113
+ collectProducts: (root) => {
114
+ const { structure } = get();
115
+ const products = [];
116
+ const recursive = (id) => {
117
+ const obj = structure.tree[id];
118
+ if (obj) {
119
+ if ((obj.solids && obj.solids.length > 0) || obj.link) {
120
+ products.push(obj);
121
+ }
122
+ if (obj.children) {
123
+ for (const child of obj.children) {
124
+ recursive(child);
125
+ }
126
+ }
127
+ }
128
+ };
129
+ recursive(root);
130
+ return products;
131
+ },
132
+ getProductSolidIds: (productId) => {
133
+ const { structure } = get();
134
+ let solids;
135
+ const product = structure.tree[productId];
136
+ if (product.link !== undefined) {
137
+ solids = structure.tree[product.link].solids || [];
138
+ }
139
+ else {
140
+ solids = product.solids || [];
141
+ }
142
+ return [...solids];
143
+ },
144
+ postProcessStructureUpdate: () => {
145
+ const { api, structure } = get();
146
+ //////////
147
+ // 1. Collect the products
148
+ //////////
149
+ const searchRoot = structure.root; // || structure.currentInstance || structure.currentProduct
150
+ const productIds = api.structure.collectProducts(searchRoot).map(p => p.id);
151
+ //////////
152
+ // 2. Collect the solid ids
153
+ //////////
154
+ let solidIds = [];
155
+ productIds.forEach(prodId => solidIds.push(...(api.structure.getProductSolidIds(prodId) || [])));
156
+ // remove duplicates
157
+ solidIds = solidIds.filter((item, index) => solidIds.indexOf(item) === index);
158
+ //////////
159
+ // 3. Add the result to the state
160
+ //////////
161
+ set(state => ({
162
+ structure: Object.assign(Object.assign({}, state.structure), { visibleContainers: solidIds, products: productIds }),
163
+ }));
164
+ },
165
+ /**
166
+ * Calculates the global transformation matrix for the given _objectId_.
167
+ *
168
+ * @param objectId The object to calculate the global transformation for.
169
+ * @param matrix The initial matrix (mainly used for recursion). It is an out parameter and in the end, it will contain the same matrix as the return value of this function.
170
+ * @returns The global transformation matrix for the given _objectId_.
171
+ */
172
+ calculateGlobalTransformation: (objectId, matrix = new THREE.Matrix4().identity()) => {
173
+ const { structure, api } = get();
174
+ const { tree, root } = structure;
175
+ const obj = tree[objectId];
176
+ if (obj && obj.coordinateSystem) {
177
+ const objMatrix = MathUtils.convertToMatrix4(obj.coordinateSystem);
178
+ matrix = matrix.clone().premultiply(objMatrix);
179
+ }
180
+ if (objectId !== root && obj.parent) {
181
+ matrix = api.structure.calculateGlobalTransformation(obj.parent, matrix);
182
+ }
183
+ return matrix;
184
+ },
185
+ calculateProductBounds: (productId, base) => {
186
+ const { graphic, api } = get();
187
+ const posInf = Number.POSITIVE_INFINITY;
188
+ const negInf = Number.NEGATIVE_INFINITY;
189
+ const baseMin = base ? base.min.clone() : new THREE.Vector3(posInf, posInf, posInf);
190
+ const baseMax = base ? base.max.clone() : new THREE.Vector3(negInf, negInf, negInf);
191
+ let box = new THREE.Box3(baseMin, baseMax);
192
+ const productIds = api.structure.collectProducts(productId).map(p => p.id);
193
+ for (const pId of productIds) {
194
+ const matrix = api.structure.calculateGlobalTransformation(pId);
195
+ const contIds = api.structure.getProductSolidIds(pId);
196
+ for (const contId of contIds) {
197
+ const cont = graphic.containers[contId];
198
+ if (cont) {
199
+ const min = new THREE.Vector3().fromArray(cont.properties.min);
200
+ const max = new THREE.Vector3().fromArray(cont.properties.max);
201
+ const b = new THREE.Box3(min.clone(), max.clone());
202
+ b.applyMatrix4(matrix);
203
+ box = box.union(b);
204
+ }
205
+ }
206
+ }
207
+ const sphere = new THREE.Sphere();
208
+ box.getBoundingSphere(sphere);
209
+ return { center: sphere.center, radius: sphere.radius, max: box.max, min: box.min };
210
+ },
211
+ /**
212
+ * This is a workaround to get the corresponding drawing id via API.
213
+ *
214
+ * > !!! Should not be used in user code !!!
215
+ *
216
+ * @returns The drawing id.
217
+ */
218
+ getDrawingId: () => get().id,
219
+ });
@@ -1,3 +1,3 @@
1
- import vanillaCreate from 'zustand/vanilla';
2
- import { createState } from './states/buerli';
3
- export const api = vanillaCreate()(createState);
1
+ import vanillaCreate from 'zustand/vanilla';
2
+ import { createState } from './states/buerli';
3
+ export const api = vanillaCreate()(createState);
@@ -1,44 +1,44 @@
1
- // This is the solution for cases when object was deleted from tree and we need to remove corresponding selectedItem.
2
- import { subscribeToDrawing } from './subscribeToDrawing';
3
- // This object contains unsubscibe function for all existing selections in all drawings
4
- export const unsubs = {};
5
- function getId(selectorId, itemId) {
6
- return `${selectorId}_${itemId}`;
7
- }
8
- export function subscribeItems(buerliApi, drawingId, selectorId, items) {
9
- const items_ = items || buerliApi.getState().drawing.refs[drawingId].selection.refs[selectorId].items;
10
- items_.forEach(item => {
11
- subscribeItem(buerliApi, drawingId, selectorId, item);
12
- });
13
- }
14
- function subscribeItem(buerliApi, drawingId, selectorId, item) {
15
- if (item.removeCondition && !unsubs[getId(selectorId, item.id)]) {
16
- const selApi = buerliApi.getState().drawing.refs[drawingId].api.selection;
17
- unsubs[getId(selectorId, item.id)] = subscribeToDrawing(buerliApi, drawingId, (d) => item.removeCondition && item.removeCondition(d), (removeCond) => {
18
- var _a;
19
- // Unselect item whose removeCondition got true
20
- if (removeCond) {
21
- const newItems = ((_a = buerliApi.getState().drawing.refs[drawingId].selection.refs[selectorId]) === null || _a === void 0 ? void 0 : _a.items) || [];
22
- selApi.setItems(selectorId, newItems.filter(item_ => item_.id !== item.id));
23
- }
24
- });
25
- }
26
- }
27
- export function unsubscribeItems(buerliApi, drawingId, selectorId, items) {
28
- var _a, _b, _c, _d;
29
- // The following line leeds to exceptions if for example the corresponding drawing is going to be reset.
30
- // To prevent those exceptions, check all properties for existance.
31
- const items_ = items || ((_d = (_c = (_b = (_a = buerliApi.getState().drawing.refs[drawingId]) === null || _a === void 0 ? void 0 : _a.selection) === null || _b === void 0 ? void 0 : _b.refs) === null || _c === void 0 ? void 0 : _c[selectorId]) === null || _d === void 0 ? void 0 : _d.items) || [];
32
- items_.forEach(item => {
33
- unsubscribeItem(selectorId, item);
34
- });
35
- }
36
- function unsubscribeItem(selectorId, item) {
37
- if (item.removeCondition) {
38
- const id = getId(selectorId, item.id);
39
- if (unsubs[id]) {
40
- unsubs[id]();
41
- delete unsubs[id];
42
- }
43
- }
44
- }
1
+ // This is the solution for cases when object was deleted from tree and we need to remove corresponding selectedItem.
2
+ import { subscribeToDrawing } from './subscribeToDrawing';
3
+ // This object contains unsubscibe function for all existing selections in all drawings
4
+ export const unsubs = {};
5
+ function getId(selectorId, itemId) {
6
+ return `${selectorId}_${itemId}`;
7
+ }
8
+ export function subscribeItems(buerliApi, drawingId, selectorId, items) {
9
+ const items_ = items || buerliApi.getState().drawing.refs[drawingId].selection.refs[selectorId].items;
10
+ items_.forEach(item => {
11
+ subscribeItem(buerliApi, drawingId, selectorId, item);
12
+ });
13
+ }
14
+ function subscribeItem(buerliApi, drawingId, selectorId, item) {
15
+ if (item.removeCondition && !unsubs[getId(selectorId, item.id)]) {
16
+ const selApi = buerliApi.getState().drawing.refs[drawingId].api.selection;
17
+ unsubs[getId(selectorId, item.id)] = subscribeToDrawing(buerliApi, drawingId, (d) => item.removeCondition && item.removeCondition(d), (removeCond) => {
18
+ var _a;
19
+ // Unselect item whose removeCondition got true
20
+ if (removeCond) {
21
+ const newItems = ((_a = buerliApi.getState().drawing.refs[drawingId].selection.refs[selectorId]) === null || _a === void 0 ? void 0 : _a.items) || [];
22
+ selApi.setItems(selectorId, newItems.filter(item_ => item_.id !== item.id));
23
+ }
24
+ });
25
+ }
26
+ }
27
+ export function unsubscribeItems(buerliApi, drawingId, selectorId, items) {
28
+ var _a, _b, _c, _d;
29
+ // The following line leeds to exceptions if for example the corresponding drawing is going to be reset.
30
+ // To prevent those exceptions, check all properties for existance.
31
+ const items_ = items || ((_d = (_c = (_b = (_a = buerliApi.getState().drawing.refs[drawingId]) === null || _a === void 0 ? void 0 : _a.selection) === null || _b === void 0 ? void 0 : _b.refs) === null || _c === void 0 ? void 0 : _c[selectorId]) === null || _d === void 0 ? void 0 : _d.items) || [];
32
+ items_.forEach(item => {
33
+ unsubscribeItem(selectorId, item);
34
+ });
35
+ }
36
+ function unsubscribeItem(selectorId, item) {
37
+ if (item.removeCondition) {
38
+ const id = getId(selectorId, item.id);
39
+ if (unsubs[id]) {
40
+ unsubs[id]();
41
+ delete unsubs[id];
42
+ }
43
+ }
44
+ }
@@ -1,9 +1,9 @@
1
- export function subscribeToDrawing(buerliApi, drawingId, sel, callback) {
2
- const unsub = buerliApi.subscribe((state, prev) => {
3
- const curDrawing = state.drawing.refs[drawingId] && sel(state.drawing.refs[drawingId]);
4
- const prevDrawing = prev.drawing.refs[drawingId] && sel(prev.drawing.refs[drawingId]);
5
- if (curDrawing !== prevDrawing)
6
- callback(curDrawing);
7
- });
8
- return unsub;
9
- }
1
+ export function subscribeToDrawing(buerliApi, drawingId, sel, callback) {
2
+ const unsub = buerliApi.subscribe((state, prev) => {
3
+ const curDrawing = state.drawing.refs[drawingId] && sel(state.drawing.refs[drawingId]);
4
+ const prevDrawing = prev.drawing.refs[drawingId] && sel(prev.drawing.refs[drawingId]);
5
+ if (curDrawing !== prevDrawing)
6
+ callback(curDrawing);
7
+ });
8
+ return unsub;
9
+ }
@@ -1,6 +1,6 @@
1
- export const createInfo = (data) => {
2
- return Object.assign({ uniqueIdent: createUniqueIdent(data) }, data);
3
- };
4
- export const createUniqueIdent = (data) => {
5
- return `${[data.prodRefId, data.objectId, data.containerId, data.graphicId]}`;
6
- };
1
+ export const createInfo = (data) => {
2
+ return Object.assign({ uniqueIdent: createUniqueIdent(data) }, data);
3
+ };
4
+ export const createUniqueIdent = (data) => {
5
+ return `${[data.prodRefId, data.objectId, data.containerId, data.graphicId]}`;
6
+ };
@@ -1,16 +1,16 @@
1
- import { NOID } from '../re-export';
2
- export * from './InteractionInfo';
3
- /**
4
- * Defines the default structure tree.
5
- * Should be used to initialize a new structure tree.
6
- */
7
- export const DEFAULT_STRUCTURE_TREE = () => {
8
- return {
9
- tree: {},
10
- root: NOID,
11
- currentProduct: NOID,
12
- currentNode: NOID,
13
- currentInstance: NOID,
14
- testRoot: NOID,
15
- };
16
- };
1
+ import { NOID } from '../re-export';
2
+ export * from './InteractionInfo';
3
+ /**
4
+ * Defines the default structure tree.
5
+ * Should be used to initialize a new structure tree.
6
+ */
7
+ export const DEFAULT_STRUCTURE_TREE = () => {
8
+ return {
9
+ tree: {},
10
+ root: NOID,
11
+ currentProduct: NOID,
12
+ currentNode: NOID,
13
+ currentInstance: NOID,
14
+ testRoot: NOID,
15
+ };
16
+ };