@itwin/unified-selection 1.5.1 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -8
- package/README.md +0 -2
- package/lib/cjs/unified-selection/EnableUnifiedSelectionSyncWithIModel.d.ts +2 -3
- package/lib/cjs/unified-selection/EnableUnifiedSelectionSyncWithIModel.d.ts.map +1 -1
- package/lib/cjs/unified-selection/EnableUnifiedSelectionSyncWithIModel.js +56 -27
- package/lib/cjs/unified-selection/EnableUnifiedSelectionSyncWithIModel.js.map +1 -1
- package/lib/cjs/unified-selection/Selectable.js +3 -3
- package/lib/cjs/unified-selection/Selectable.js.map +1 -1
- package/lib/cjs/unified-selection/SelectionScope.js +2 -0
- package/lib/cjs/unified-selection/SelectionScope.js.map +1 -1
- package/lib/esm/unified-selection/EnableUnifiedSelectionSyncWithIModel.d.ts +2 -3
- package/lib/esm/unified-selection/EnableUnifiedSelectionSyncWithIModel.d.ts.map +1 -1
- package/lib/esm/unified-selection/EnableUnifiedSelectionSyncWithIModel.js +55 -26
- package/lib/esm/unified-selection/EnableUnifiedSelectionSyncWithIModel.js.map +1 -1
- package/lib/esm/unified-selection/Selectable.js +3 -3
- package/lib/esm/unified-selection/Selectable.js.map +1 -1
- package/lib/esm/unified-selection/SelectionScope.js +2 -0
- package/lib/esm/unified-selection/SelectionScope.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @itwin/unified-selection
|
|
2
2
|
|
|
3
|
+
## 1.5.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1077](https://github.com/iTwin/presentation/pull/1077): Fix `enableUnifiedSelectionSyncWithIModel` not updating selection & hilite sets, after selection set is changed directly in a way that doesn't cause a selection storage change.
|
|
8
|
+
|
|
9
|
+
A specific example:
|
|
10
|
+
1. `enableUnifiedSelectionSyncWithIModel` is set up to use `assembly` selection scope.
|
|
11
|
+
2. User clicks on an assembly part in the graphics view, causing its parent element (assembly) to be added to selection storage, and selection & hilite sets to be updated with all assembly parts.
|
|
12
|
+
3. User clicks on another part of the same assembly, causing selection storage to remain unchanged (still contains the assembly), and selection & hilite sets to NOT be updated with all assembly parts. As a result, the latter sets now contain only the newly clicked part, which is incorrect.
|
|
13
|
+
|
|
3
14
|
## 1.5.1
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
|
@@ -13,7 +24,6 @@
|
|
|
13
24
|
### Minor Changes
|
|
14
25
|
|
|
15
26
|
- [#1018](https://github.com/iTwin/presentation/pull/1018): Fixed `enableUnifiedSelectionSyncWithIModel` not using (and not being able to use) the underlying hilite set provider of the given custom `CachingHiliteSetProvider`, causing selection synchronization to work incorrectly in cases when items were added or removed to iModel's selection set.
|
|
16
|
-
|
|
17
27
|
- Introduced `IModelHiliteSetProvider` interface and a factory function `createIModelHiliteSetProvider` that creates an instance of it. Functionality-wise these are very similar to `CachingHiliteSetProvider` and `createCachingHiliteSetProvider` but the new type provides access to the underlying hilite set provider of the given iModel. And the naming better represents the purpose of the type.
|
|
18
28
|
- Deprecated `CachingHiliteSetProvider` and `createCachingHiliteSetProvider` in favor of the above.
|
|
19
29
|
- For the `enableUnifiedSelectionSyncWithIModel` function, deprecated the `cachingHiliteSetProvider` prop in favor of the newly added `imodelHiliteSetProvider`.
|
|
@@ -69,7 +79,6 @@
|
|
|
69
79
|
- [#901](https://github.com/iTwin/presentation/pull/901): Export `SelectionScope` type to make it easier for consumers to define "active scope" type.
|
|
70
80
|
|
|
71
81
|
APIs that use this type:
|
|
72
|
-
|
|
73
82
|
- The `scope` prop of `computeSelection` function.
|
|
74
83
|
- Return type of `activeScopeProvider` callback prop of `enableUnifiedSelectionSyncWithIModel` function.
|
|
75
84
|
|
|
@@ -206,14 +215,12 @@
|
|
|
206
215
|
### Minor Changes
|
|
207
216
|
|
|
208
217
|
- [#693](https://github.com/iTwin/presentation/pull/693): Selection events API cleanup:
|
|
209
|
-
|
|
210
218
|
- Remove the second `StorageSelectionChangesListener` argument, which represented the `SelectionStorage` where the selection change happened. As a replacement, added it as a property to `StorageSelectionChangeEventArgs`, which is the first and now the only argument of the listener.
|
|
211
219
|
- Remove `SelectionChangeEvent` interface in favor of `Event<StorageSelectionChangesListener>`.
|
|
212
220
|
|
|
213
221
|
### Patch Changes
|
|
214
222
|
|
|
215
223
|
- [#693](https://github.com/iTwin/presentation/pull/693): API documentation improvements:
|
|
216
|
-
|
|
217
224
|
- Add warnings to interfaces which are not supposed to be extended or implemented by consumers. Objects of such interfaces are only supposed to be created by functions in this package. As such, adding required members to these interfaces is not considered a breaking change.
|
|
218
225
|
- Changed `string` to `Id64String` where appropriate, to make it clear that the string is expected to be a valid Id64 string. Note that this is not a breaking change, as `Id64String` is just a type alias for `string`.
|
|
219
226
|
|
|
@@ -276,7 +283,6 @@
|
|
|
276
283
|
Some of the APIs were accepting `ECSchemaProvider` as a parameter and used it to only inspect class hierarchy. This change switches them to accept `ECClassHierarchyInspector` instead - this reduces the surface area of the API and makes it more clear that only class hierarchy is being inspected, while also possibly improving performance.
|
|
277
284
|
|
|
278
285
|
This is a breaking change for the following APIs:
|
|
279
|
-
|
|
280
286
|
- `createHiliteSetProvider` prop `imodelAccess`.
|
|
281
287
|
- `createCachingHiliteSetProvider` prop `imodelProvider`.
|
|
282
288
|
- `enableUnifiedSelectionSyncWithIModel` prop `imodelAccess`.
|
|
@@ -318,7 +324,6 @@
|
|
|
318
324
|
|
|
319
325
|
- [#530](https://github.com/iTwin/presentation/pull/530): Added `enableUnifiedSelectionSyncWithIModel` for enabling synchronization between iModel's tool selection and unified selection storage.
|
|
320
326
|
- [#544](https://github.com/iTwin/presentation/pull/544): Breaking API changes
|
|
321
|
-
|
|
322
327
|
- The type of ECSQL query executor's `createQueryReader` function was changed from:
|
|
323
328
|
|
|
324
329
|
```ts
|
|
@@ -365,7 +370,6 @@
|
|
|
365
370
|
This makes the API consistent with other Presentation packages and allows additional manipulation on ECSQL, which was not possible previously when ECSQL contained CTEs.
|
|
366
371
|
|
|
367
372
|
The change affects the following public APIs:
|
|
368
|
-
|
|
369
373
|
- `computeSelection` (`queryExecutor` prop),
|
|
370
374
|
- `createHiliteSetProvider` (previously `queryExecutor` prop, now `imodelAccess` prop),
|
|
371
375
|
- `createCachingHiliteSetProvider` (`iModelProvider` prop).
|
|
@@ -419,7 +423,6 @@
|
|
|
419
423
|
```
|
|
420
424
|
|
|
421
425
|
- [#551](https://github.com/iTwin/presentation/pull/551): Changed `iModel` in attribute names to `imodel`. The change was made to be consistent with other Presentation packages and affects the following APIs:
|
|
422
|
-
|
|
423
426
|
- `SelectionStorage` methods now accept `imodelKey` prop rather than `iModelKey`. It's `selectionChangeEvent` is also now raised with `imodelKey` prop in `StorageSelectionChangeEventArgs`.
|
|
424
427
|
- `CachingHiliteSetProvider.getHiliteSet` now accepts an `imodelKey` prop rather than `iModelKey`.
|
|
425
428
|
- `createCachingHiliteSetProvider` props now accept `imodelProvider` callback rather than `iModelProvider`.
|
package/README.md
CHANGED
|
@@ -9,14 +9,12 @@ The purpose of the `@itwin/unified-selection` package and unified selection in g
|
|
|
9
9
|
The API consists of a few very basic concepts:
|
|
10
10
|
|
|
11
11
|
- A `Selectable` is something that can be selected and is associated with an [EC](https://www.itwinjs.org/bis/ec/) instance. There are 2 types of selectables:
|
|
12
|
-
|
|
13
12
|
- `SelectableInstanceKey` uniquely identifies a single EC instance through a full class name and [ECInstanceId](https://www.itwinjs.org/learning/ecsql/#ecinstanceid-and-ecclassid).
|
|
14
13
|
- `CustomSelectable` is identified by an arbitrary `identifier` string and knows how to get any number of `SelectableInstanceKey` associated with it.
|
|
15
14
|
|
|
16
15
|
- `Selectables` is a container for multiple `Selectable` instances. The container is structured in a way that allows to quickly find specific selectables by their identifier.
|
|
17
16
|
|
|
18
17
|
- `SelectionStorage` is an interface that manages `Selectables` for different [iModels](https://www.itwinjs.org/learning/imodels/). It allows:
|
|
19
|
-
|
|
20
18
|
- Changing the selection (add, remove, replace, clear).
|
|
21
19
|
- Get active selection.
|
|
22
20
|
- Listen to selection changes.
|
|
@@ -95,6 +95,7 @@ export declare class IModelSelectionHandler {
|
|
|
95
95
|
private _imodelHiliteSetProvider;
|
|
96
96
|
private _activeScopeProvider;
|
|
97
97
|
private _isSuspended;
|
|
98
|
+
private _selectionStorageChangeTracker;
|
|
98
99
|
private _cancelOngoingChanges;
|
|
99
100
|
private _unregisterUnifiedSelectionListener;
|
|
100
101
|
private _unregisterIModelSelectionSetListener;
|
|
@@ -107,13 +108,11 @@ export declare class IModelSelectionHandler {
|
|
|
107
108
|
suspendIModelToolSelectionSync(): {
|
|
108
109
|
[Symbol.dispose]: () => void;
|
|
109
110
|
};
|
|
110
|
-
private
|
|
111
|
+
private syncHiliteSet;
|
|
111
112
|
private onUnifiedSelectionChanged;
|
|
112
113
|
private applyCurrentHiliteSet;
|
|
113
114
|
private addHiliteSet;
|
|
114
115
|
private removeHiliteSet;
|
|
115
116
|
private onIModelSelectionChanged;
|
|
116
|
-
private handleIModelSelectionChange;
|
|
117
|
-
private getSelectionSetChangeIds;
|
|
118
117
|
}
|
|
119
118
|
//# sourceMappingURL=EnableUnifiedSelectionSyncWithIModel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnableUnifiedSelectionSyncWithIModel.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/EnableUnifiedSelectionSyncWithIModel.ts"],"names":[],"mappings":"AAKA,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC3F,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAsC,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC/F,OAAO,EAAiC,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAGtG,OAAO,EAAoB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAA6E,MAAM,mBAAmB,CAAC;AAG3J;;;GAGG;AACH,MAAM,WAAW,yCAAyC;IACxD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,YAAY,EAAE,kBAAkB,GAC9B,yBAAyB,GAAG;QAC1B,sEAAsE;QACtE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,mFAAmF;QACnF,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;QACxC,yFAAyF;QACzF,QAAQ,CAAC,YAAY,EAAE,sBAAsB,CAAC;KAC/C,CAAC;IAEJ;;;OAGG;IACH,gBAAgB,EAAE,gBAAgB,CAAC;IAEnC,uCAAuC;IACvC,mBAAmB,EAAE,MAAM,cAAc,CAAC;IAE1C;;;;;;;OAOG;IACH,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAElD;;;;;;;;;;;;;;OAcG;IAEH,wBAAwB,CAAC,EAAE,wBAAwB,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,SAAS,CAAC,GAAG;QAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAC;CACtI;AAED;;;;GAIG;AACH,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,yCAAyC,GAAG,MAAM,IAAI,CAGjH;AAED;;;;;GAKG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,oBAAoB,CAAU;IAEtC,OAAO,CAAC,aAAa,CAA4D;IACjF,OAAO,CAAC,iBAAiB,CAAmB;IAC5C,OAAO,CAAC,wBAAwB,CAAoF;IACpH,OAAO,CAAC,oBAAoB,CAAuB;IAEnD,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,mCAAmC,CAAa;IACxD,OAAO,CAAC,qCAAqC,CAAa;IAC1D,OAAO,CAAC,iCAAiC,CAAa;gBAEnC,KAAK,EAAE,yCAAyC,GAAG;QAAE,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;KAAE;IA4CxG,CAAC,MAAM,CAAC,OAAO,CAAC;IAOvB,4GAA4G;IACrG,8BAA8B;;;IAUrC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"EnableUnifiedSelectionSyncWithIModel.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/EnableUnifiedSelectionSyncWithIModel.ts"],"names":[],"mappings":"AAKA,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC3F,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAsC,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC/F,OAAO,EAAiC,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAGtG,OAAO,EAAoB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAA6E,MAAM,mBAAmB,CAAC;AAG3J;;;GAGG;AACH,MAAM,WAAW,yCAAyC;IACxD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,YAAY,EAAE,kBAAkB,GAC9B,yBAAyB,GAAG;QAC1B,sEAAsE;QACtE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,mFAAmF;QACnF,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;QACxC,yFAAyF;QACzF,QAAQ,CAAC,YAAY,EAAE,sBAAsB,CAAC;KAC/C,CAAC;IAEJ;;;OAGG;IACH,gBAAgB,EAAE,gBAAgB,CAAC;IAEnC,uCAAuC;IACvC,mBAAmB,EAAE,MAAM,cAAc,CAAC;IAE1C;;;;;;;OAOG;IACH,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAElD;;;;;;;;;;;;;;OAcG;IAEH,wBAAwB,CAAC,EAAE,wBAAwB,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,SAAS,CAAC,GAAG;QAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAC;CACtI;AAED;;;;GAIG;AACH,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,yCAAyC,GAAG,MAAM,IAAI,CAGjH;AAED;;;;;GAKG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,oBAAoB,CAAU;IAEtC,OAAO,CAAC,aAAa,CAA4D;IACjF,OAAO,CAAC,iBAAiB,CAAmB;IAC5C,OAAO,CAAC,wBAAwB,CAAoF;IACpH,OAAO,CAAC,oBAAoB,CAAuB;IAEnD,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,8BAA8B,CAAK;IAC3C,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,mCAAmC,CAAa;IACxD,OAAO,CAAC,qCAAqC,CAAa;IAC1D,OAAO,CAAC,iCAAiC,CAAa;gBAEnC,KAAK,EAAE,yCAAyC,GAAG;QAAE,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;KAAE;IA4CxG,CAAC,MAAM,CAAC,OAAO,CAAC;IAOvB,4GAA4G;IACrG,8BAA8B;;;IAUrC,OAAO,CAAC,aAAa;IAuCrB,OAAO,CAAC,yBAAyB,CAa/B;IAEF,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,YAAY;IAwBpB,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,wBAAwB,CA+C9B;CACH"}
|
|
@@ -62,6 +62,7 @@ require("./DisposePolyfill.js");
|
|
|
62
62
|
const rxjs_1 = require("rxjs");
|
|
63
63
|
const HiliteSetProvider_js_1 = require("./HiliteSetProvider.js");
|
|
64
64
|
const IModelHiliteSetProvider_js_1 = require("./IModelHiliteSetProvider.js");
|
|
65
|
+
const Selectable_js_1 = require("./Selectable.js");
|
|
65
66
|
const SelectionScope_js_1 = require("./SelectionScope.js");
|
|
66
67
|
const IModel_js_1 = require("./types/IModel.js");
|
|
67
68
|
const Utils_js_1 = require("./Utils.js");
|
|
@@ -87,6 +88,7 @@ class IModelSelectionHandler {
|
|
|
87
88
|
_imodelHiliteSetProvider;
|
|
88
89
|
_activeScopeProvider;
|
|
89
90
|
_isSuspended;
|
|
91
|
+
_selectionStorageChangeTracker = 0;
|
|
90
92
|
_cancelOngoingChanges = new rxjs_1.Subject();
|
|
91
93
|
_unregisterUnifiedSelectionListener;
|
|
92
94
|
_unregisterIModelSelectionSetListener;
|
|
@@ -144,7 +146,8 @@ class IModelSelectionHandler {
|
|
|
144
146
|
},
|
|
145
147
|
};
|
|
146
148
|
}
|
|
147
|
-
|
|
149
|
+
syncHiliteSet(props) {
|
|
150
|
+
const { changeType, selectables, source } = props;
|
|
148
151
|
switch (changeType) {
|
|
149
152
|
case "clear":
|
|
150
153
|
return this.applyCurrentHiliteSet({ activeSelectionAction: "clearAll" });
|
|
@@ -185,10 +188,12 @@ class IModelSelectionHandler {
|
|
|
185
188
|
if (args.imodelKey !== this._imodelAccess.key || args.level !== 0) {
|
|
186
189
|
return;
|
|
187
190
|
}
|
|
191
|
+
// update the selection storage change tracker so we know the selection storage changed
|
|
192
|
+
this._selectionStorageChangeTracker = (this._selectionStorageChangeTracker + 1) % Number.MAX_SAFE_INTEGER;
|
|
188
193
|
if (args.changeType === "replace" || args.changeType === "clear") {
|
|
189
194
|
this._cancelOngoingChanges.next();
|
|
190
195
|
}
|
|
191
|
-
this.
|
|
196
|
+
this.syncHiliteSet(args);
|
|
192
197
|
};
|
|
193
198
|
applyCurrentHiliteSet({ activeSelectionAction }) {
|
|
194
199
|
if (activeSelectionAction !== "keep") {
|
|
@@ -293,40 +298,64 @@ class IModelSelectionHandler {
|
|
|
293
298
|
this._selectionStorage.clearSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName });
|
|
294
299
|
return;
|
|
295
300
|
}
|
|
296
|
-
const ids =
|
|
301
|
+
const ids = getSelectionSetChangeIds(event);
|
|
297
302
|
const scopedSelection = (0, rxjs_1.merge)(ids.elements
|
|
298
303
|
? (0, rxjs_1.from)((0, SelectionScope_js_1.computeSelection)({ queryExecutor: this._imodelAccess, elementIds: ids.elements, scope: this._activeScopeProvider() }))
|
|
299
|
-
: /* c8 ignore next */ rxjs_1.EMPTY, ids.models ? (0, rxjs_1.from)(ids.models).pipe((0, rxjs_1.map)((id) => ({ className: "BisCore.Model", id }))) : /* c8 ignore next */ rxjs_1.EMPTY, ids.subcategories
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
const
|
|
304
|
-
const props = {
|
|
304
|
+
: /* c8 ignore next */ rxjs_1.EMPTY, ids.models ? (0, rxjs_1.from)(ids.models).pipe((0, rxjs_1.map)((id) => ({ className: "BisCore.Model", id }))) : /* c8 ignore next */ rxjs_1.EMPTY, ids.subcategories
|
|
305
|
+
? (0, rxjs_1.from)(ids.subcategories).pipe((0, rxjs_1.map)((id) => ({ className: "BisCore.SubCategory", id })))
|
|
306
|
+
: /* c8 ignore next */ rxjs_1.EMPTY);
|
|
307
|
+
const selectionStorageVersion = this._selectionStorageChangeTracker;
|
|
308
|
+
const changeSelectionStorageProps = {
|
|
305
309
|
imodelKey: this._imodelAccess.key,
|
|
306
310
|
source: this._selectionSourceName,
|
|
307
|
-
selectables,
|
|
311
|
+
selectables: await (0, rxjs_1.firstValueFrom)(scopedSelection.pipe((0, rxjs_1.toArray)())),
|
|
308
312
|
};
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
313
|
+
try {
|
|
314
|
+
switch (event.type) {
|
|
315
|
+
case IModel_js_1.CoreSelectionSetEventType.Add:
|
|
316
|
+
return this._selectionStorage.addToSelection(changeSelectionStorageProps);
|
|
317
|
+
case IModel_js_1.CoreSelectionSetEventType.Remove:
|
|
318
|
+
return this._selectionStorage.removeFromSelection(changeSelectionStorageProps);
|
|
319
|
+
case IModel_js_1.CoreSelectionSetEventType.Replace:
|
|
320
|
+
return this._selectionStorage.replaceSelection(changeSelectionStorageProps);
|
|
321
|
+
}
|
|
316
322
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
323
|
+
finally {
|
|
324
|
+
if (this._selectionStorageChangeTracker === selectionStorageVersion) {
|
|
325
|
+
// if the storage wasn't changed while we were processing the selection change, we have to re-sync the
|
|
326
|
+
// hilite set (otherwise it's done by the selection storage change handler)
|
|
327
|
+
this.syncHiliteSet({
|
|
328
|
+
...changeSelectionStorageProps,
|
|
329
|
+
selectables: Selectable_js_1.Selectables.create(changeSelectionStorageProps.selectables),
|
|
330
|
+
changeType: getUnifiedSelectionChangeType(event.type),
|
|
331
|
+
});
|
|
332
|
+
}
|
|
326
333
|
}
|
|
327
|
-
}
|
|
334
|
+
};
|
|
328
335
|
}
|
|
329
336
|
exports.IModelSelectionHandler = IModelSelectionHandler;
|
|
337
|
+
function getSelectionSetChangeIds(event) {
|
|
338
|
+
switch (event.type) {
|
|
339
|
+
case IModel_js_1.CoreSelectionSetEventType.Add:
|
|
340
|
+
return event.additions ?? (event.added ? { elements: event.added } : /* c8 ignore next */ {});
|
|
341
|
+
case IModel_js_1.CoreSelectionSetEventType.Remove:
|
|
342
|
+
return event.removals ?? (event.removed ? { elements: event.removed } : /* c8 ignore next */ {});
|
|
343
|
+
case IModel_js_1.CoreSelectionSetEventType.Replace:
|
|
344
|
+
return "active" in event.set ? event.set.active : { elements: event.set.elements };
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
function getUnifiedSelectionChangeType(coreChangeType) {
|
|
348
|
+
switch (coreChangeType) {
|
|
349
|
+
case IModel_js_1.CoreSelectionSetEventType.Add:
|
|
350
|
+
return "add";
|
|
351
|
+
case IModel_js_1.CoreSelectionSetEventType.Remove:
|
|
352
|
+
return "remove";
|
|
353
|
+
case IModel_js_1.CoreSelectionSetEventType.Replace:
|
|
354
|
+
return "replace";
|
|
355
|
+
case IModel_js_1.CoreSelectionSetEventType.Clear:
|
|
356
|
+
return "clear";
|
|
357
|
+
}
|
|
358
|
+
}
|
|
330
359
|
function is5xSelectionSet(selectionSet) {
|
|
331
360
|
return "active" in selectionSet;
|
|
332
361
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnableUnifiedSelectionSyncWithIModel.js","sourceRoot":"","sources":["../../../src/unified-selection/EnableUnifiedSelectionSyncWithIModel.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./DisposePolyfill.js\";\nimport { EMPTY, firstValueFrom, from, map, merge, Observable, Subject, takeUntil, toArray } from \"rxjs\";\nimport { Id64Arg, Id64Set } from \"@itwin/core-bentley\";\nimport { ECClassHierarchyInspector, ECSqlQueryExecutor } from \"@itwin/presentation-shared\";\nimport { CachingHiliteSetProvider } from \"./CachingHiliteSetProvider.js\";\nimport { createHiliteSetProvider, HiliteSet, HiliteSetProvider } from \"./HiliteSetProvider.js\";\nimport { createIModelHiliteSetProvider, IModelHiliteSetProvider } from \"./IModelHiliteSetProvider.js\";\nimport { SelectableInstanceKey, Selectables } from \"./Selectable.js\";\nimport { StorageSelectionChangeEventArgs, StorageSelectionChangeType } from \"./SelectionChangeEvent.js\";\nimport { computeSelection, SelectionScope } from \"./SelectionScope.js\";\nimport { SelectionStorage } from \"./SelectionStorage.js\";\nimport { CoreIModelHiliteSet, CoreIModelSelectionSet, CoreSelectableIds, CoreSelectionSetEventType, CoreSelectionSetEventUnsafe } from \"./types/IModel.js\";\nimport { safeDispose } from \"./Utils.js\";\n\n/**\n * Props for `enableUnifiedSelectionSyncWithIModel`.\n * @public\n */\nexport interface EnableUnifiedSelectionSyncWithIModelProps {\n /**\n * Provides access to different iModel's features: query executing, class hierarchy, selection and hilite sets.\n *\n * It's recommended to use `@itwin/presentation-core-interop` to create `key`, `ECSqlQueryExecutor` and `ECSchemaProvider` from\n * [IModelConnection](https://www.itwinjs.org/reference/core-frontend/imodelconnection/imodelconnection/), and map its\n * `hilited` and `selectionSet` attributes like this:\n *\n * ```ts\n * import { createECSqlQueryExecutor, createECSchemaProvider, createIModelKey } from \"@itwin/presentation-core-interop\";\n * import { createCachingECClassHierarchyInspector } from \"@itwin/presentation-shared\";\n * import { IModelConnection } from \"@itwin/core-frontend\";\n *\n * const imodel: IModelConnection = ...\n * const imodelAccess = {\n * ...createECSqlQueryExecutor(imodel),\n * ...createCachingECClassHierarchyInspector({ schemaProvider: createECSchemaProvider(MyAppFrontend.getSchemaContext(imodel)) }),\n * key: createIModelKey(imodel),\n * hiliteSet: imodel.hilited,\n * selectionSet: imodel.selectionSet,\n * };\n * ```\n */\n imodelAccess: ECSqlQueryExecutor &\n ECClassHierarchyInspector & {\n /** Key of the iModel. Generally taken from `IModelConnection.key`. */\n readonly key: string;\n /** The set of currently hilited elements taken from `IModelConnection.hilited`. */\n readonly hiliteSet: CoreIModelHiliteSet;\n /** The set of currently selected elements taken from `IModelConnection.selectionSet`. */\n readonly selectionSet: CoreIModelSelectionSet;\n };\n\n /**\n * Unified selection storage to synchronize IModel's tool selection with. The storage should be shared\n * across all components in the application to ensure unified selection experience.\n */\n selectionStorage: SelectionStorage;\n\n /** Active selection scope provider. */\n activeScopeProvider: () => SelectionScope;\n\n /**\n * An iModel hilite set provider used to retrieve hilite sets for different iModels. If not provided, a new `IModelHiliteSetProvider`\n * will be created for the given iModel using the provided `imodelAccess`.\n * If the consuming application already has a `IModelHiliteSetProvider` defined, it should be provided instead\n * to reuse the cache and avoid creating new providers for each iModel.\n *\n * @see `createIModelHiliteSetProvider`\n */\n imodelHiliteSetProvider?: IModelHiliteSetProvider;\n\n /**\n * A caching hilite set provider used to retrieve hilite sets for an iModel. If not provided, a new `CachingHiliteSetProvider`\n * will be created for the given iModel using the provided `imodelAccess`.\n * If the consuming application already has a `CachingHiliteSetProvider` defined, it should be provided instead\n * to reuse the cache and avoid creating new providers for each iModel.\n *\n * The type is defined in a way that makes it required for provider to have either the deprecated `dispose` or the\n * new `Symbol.dispose` method.\n *\n * **Warning:** When the given `CachingHiliteSetProvider` internally uses a custom `HiliteSetProvider`, the synchronization has\n * no access to it, and thus uses its own, default, `HiliteSetProvider`. As a result, the synchronization may not work as expected.\n * To alleviate this, the `imodelHiliteSetProvider` prop should be used instead.\n *\n * @deprecated in 1.5. Use `imodelHiliteSetProvider` prop instead.\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n cachingHiliteSetProvider?: CachingHiliteSetProvider | (Omit<CachingHiliteSetProvider, \"dispose\"> & { [Symbol.dispose]: () => void });\n}\n\n/**\n * Enables synchronization between iModel selection and unified selection.\n * @returns function for disposing the synchronization.\n * @public\n */\nexport function enableUnifiedSelectionSyncWithIModel(props: EnableUnifiedSelectionSyncWithIModelProps): () => void {\n const selectionHandler = new IModelSelectionHandler(props);\n return () => selectionHandler[Symbol.dispose]();\n}\n\n/**\n * A handler that syncs selection between unified selection storage (`SelectionStorage`) and\n * an iModel (`iModel.selectionSet`, `iModel.hilited`).\n *\n * @internal\n */\nexport class IModelSelectionHandler {\n private _selectionSourceName = \"Tool\";\n\n private _imodelAccess: EnableUnifiedSelectionSyncWithIModelProps[\"imodelAccess\"];\n private _selectionStorage: SelectionStorage;\n private _imodelHiliteSetProvider: NonNullable<EnableUnifiedSelectionSyncWithIModelProps[\"imodelHiliteSetProvider\"]>;\n private _activeScopeProvider: () => SelectionScope;\n\n private _isSuspended: boolean;\n private _cancelOngoingChanges = new Subject<void>();\n private _unregisterUnifiedSelectionListener: () => void;\n private _unregisterIModelSelectionSetListener: () => void;\n private _disposeInternalHiliteSetProvider: () => void;\n\n public constructor(props: EnableUnifiedSelectionSyncWithIModelProps & { hiliteSetProvider?: HiliteSetProvider }) {\n this._imodelAccess = props.imodelAccess;\n this._selectionStorage = props.selectionStorage;\n this._activeScopeProvider = props.activeScopeProvider;\n this._isSuspended = false;\n\n [this._imodelHiliteSetProvider, this._disposeInternalHiliteSetProvider] = (() => {\n if (props.imodelHiliteSetProvider) {\n return [props.imodelHiliteSetProvider, () => {}];\n }\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n if (props.cachingHiliteSetProvider) {\n return [\n createIModelHiliteSetProviderFromCachingProvider(\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n props.cachingHiliteSetProvider,\n props.hiliteSetProvider ?? createHiliteSetProvider({ imodelAccess: props.imodelAccess }),\n ),\n // don't need to dispose anything, because our wrapper has no dispose logic, and `cachingHiliteSetProvider` should be disposed\n // by whoever owns it\n () => {},\n ];\n }\n /* c8 ignore start */\n const internalProvider = createIModelHiliteSetProvider({\n selectionStorage: this._selectionStorage,\n imodelProvider: () => this._imodelAccess,\n createHiliteSetProvider: () => props.hiliteSetProvider ?? createHiliteSetProvider({ imodelAccess: props.imodelAccess }),\n });\n return [internalProvider, () => safeDispose(internalProvider)];\n /* c8 ignore end */\n })();\n\n this._unregisterIModelSelectionSetListener = this._imodelAccess.selectionSet.onChanged.addListener(this.onIModelSelectionChanged);\n this._unregisterUnifiedSelectionListener = this._selectionStorage.selectionChangeEvent.addListener(this.onUnifiedSelectionChanged);\n\n if (!is5xSelectionSet(this._imodelAccess.selectionSet)) {\n // itwinjs-core@4: stop imodel from syncing tool selection with hilited list - we want to manage that sync ourselves\n this._imodelAccess.hiliteSet.wantSyncWithSelectionSet = false;\n }\n\n this.applyCurrentHiliteSet({ activeSelectionAction: \"clearAll\" });\n }\n\n public [Symbol.dispose]() {\n this._cancelOngoingChanges.next();\n this._unregisterIModelSelectionSetListener();\n this._unregisterUnifiedSelectionListener();\n this._disposeInternalHiliteSetProvider();\n }\n\n /** Temporarily suspends tool selection synchronization until the returned disposable object is disposed. */\n public suspendIModelToolSelectionSync() {\n const wasSuspended = this._isSuspended;\n this._isSuspended = true;\n return {\n [Symbol.dispose]: () => {\n this._isSuspended = wasSuspended;\n },\n };\n }\n\n private handleUnifiedSelectionChange(changeType: StorageSelectionChangeType, selectables: Selectables, source: string): void {\n switch (changeType) {\n case \"clear\":\n return this.applyCurrentHiliteSet({ activeSelectionAction: \"clearAll\" });\n case \"replace\":\n return this.applyCurrentHiliteSet({\n activeSelectionAction:\n source === this._selectionSourceName\n ? is5xSelectionSet(this._imodelAccess.selectionSet)\n ? // with 5x core we don't need to clear anything when event is triggered by a Tool (hilite and selection sets are in sync already)\n \"keep\"\n : // with 4x core we need to clear hilite set, because it's not synced with selection set\n \"clearHilited\"\n : // when event is triggered not by a Tool, we need to clear everything\n \"clearAll\",\n });\n case \"add\":\n return void from(this._imodelHiliteSetProvider.getHiliteSetProvider({ imodelKey: this._imodelAccess.key }).getHiliteSet({ selectables }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (set) => {\n this.addHiliteSet(set);\n },\n });\n case \"remove\":\n return void from(this._imodelHiliteSetProvider.getHiliteSetProvider({ imodelKey: this._imodelAccess.key }).getHiliteSet({ selectables }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (set) => {\n this.removeHiliteSet(set);\n },\n complete: () => {\n this.applyCurrentHiliteSet({ activeSelectionAction: \"keep\" });\n },\n });\n }\n }\n\n private onUnifiedSelectionChanged = (args: StorageSelectionChangeEventArgs) => {\n // iModels are only interested in top-level selection changes\n if (args.imodelKey !== this._imodelAccess.key || args.level !== 0) {\n return;\n }\n\n if (args.changeType === \"replace\" || args.changeType === \"clear\") {\n this._cancelOngoingChanges.next();\n }\n this.handleUnifiedSelectionChange(args.changeType, args.selectables, args.source);\n };\n\n private applyCurrentHiliteSet({ activeSelectionAction }: { activeSelectionAction: \"clearAll\" | \"clearHilited\" | \"keep\" }) {\n if (activeSelectionAction !== \"keep\") {\n using _dispose = this.suspendIModelToolSelectionSync();\n if (!is5xSelectionSet(this._imodelAccess.selectionSet)) {\n this._imodelAccess.hiliteSet.clear();\n }\n if (activeSelectionAction === \"clearAll\") {\n this._imodelAccess.selectionSet.emptyAll();\n }\n }\n\n from(this._imodelHiliteSetProvider.getCurrentHiliteSet({ imodelKey: this._imodelAccess.key }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (ids) => {\n this.addHiliteSet(ids);\n },\n });\n }\n\n private addHiliteSet(set: HiliteSet) {\n using _dispose = this.suspendIModelToolSelectionSync();\n if (is5xSelectionSet(this._imodelAccess.selectionSet)) {\n // with 5.x core we can simply add the set as a whole\n this._imodelAccess.selectionSet.add({\n models: set.models,\n subcategories: set.subCategories,\n elements: set.elements,\n });\n } else {\n // pre-5.0 core requires adding models and subcategories to hilite set separately\n if (set.models.length) {\n this._imodelAccess.hiliteSet.models.addIds(set.models);\n }\n if (set.subCategories.length) {\n this._imodelAccess.hiliteSet.subcategories.addIds(set.subCategories);\n }\n if (set.elements.length) {\n this._imodelAccess.hiliteSet.elements.addIds(set.elements);\n this._imodelAccess.selectionSet.add(set.elements);\n }\n }\n }\n\n private removeHiliteSet(set: HiliteSet) {\n using _dispose = this.suspendIModelToolSelectionSync();\n if (is5xSelectionSet(this._imodelAccess.selectionSet)) {\n // with 5.x core we can simply remove the set as a whole\n this._imodelAccess.selectionSet.remove({\n models: set.models,\n subcategories: set.subCategories,\n elements: set.elements,\n });\n } else {\n if (set.models.length) {\n this._imodelAccess.hiliteSet.models.deleteIds(set.models);\n }\n if (set.subCategories.length) {\n this._imodelAccess.hiliteSet.subcategories.deleteIds(set.subCategories);\n }\n if (set.elements.length) {\n this._imodelAccess.hiliteSet.elements.deleteIds(set.elements);\n this._imodelAccess.selectionSet.remove(set.elements);\n }\n }\n }\n\n private onIModelSelectionChanged = async (event: CoreSelectionSetEventUnsafe): Promise<void> => {\n if (this._isSuspended) {\n return;\n }\n\n if (CoreSelectionSetEventType.Clear === event.type) {\n this._selectionStorage.clearSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName });\n return;\n }\n\n const ids = this.getSelectionSetChangeIds(event);\n const scopedSelection = merge(\n ids.elements\n ? from(computeSelection({ queryExecutor: this._imodelAccess, elementIds: ids.elements, scope: this._activeScopeProvider() }))\n : /* c8 ignore next */ EMPTY,\n ids.models ? from(ids.models).pipe(map((id) => ({ className: \"BisCore.Model\", id }))) : /* c8 ignore next */ EMPTY,\n ids.subcategories ? from(ids.subcategories).pipe(map((id) => ({ className: \"BisCore.SubCategory\", id }))) : /* c8 ignore next */ EMPTY,\n );\n await this.handleIModelSelectionChange(event.type, scopedSelection);\n };\n\n private async handleIModelSelectionChange(type: CoreSelectionSetEventType, keys: Observable<SelectableInstanceKey>) {\n const selectables = await firstValueFrom(keys.pipe(toArray()));\n const props = {\n imodelKey: this._imodelAccess.key,\n source: this._selectionSourceName,\n selectables,\n };\n switch (type) {\n case CoreSelectionSetEventType.Add:\n return this._selectionStorage.addToSelection(props);\n case CoreSelectionSetEventType.Remove:\n return this._selectionStorage.removeFromSelection(props);\n case CoreSelectionSetEventType.Replace:\n return this._selectionStorage.replaceSelection(props);\n }\n }\n\n private getSelectionSetChangeIds(\n event: Omit<CoreSelectionSetEventUnsafe, \"type\"> & {\n type: CoreSelectionSetEventType.Add | CoreSelectionSetEventType.Remove | CoreSelectionSetEventType.Replace;\n },\n ): CoreSelectableIds {\n switch (event.type) {\n case CoreSelectionSetEventType.Add:\n return event.additions ?? (event.added ? { elements: event.added } : /* c8 ignore next */ {});\n case CoreSelectionSetEventType.Remove:\n return event.removals ?? (event.removed ? { elements: event.removed } : /* c8 ignore next */ {});\n case CoreSelectionSetEventType.Replace:\n return \"active\" in event.set ? event.set.active : { elements: event.set.elements };\n }\n }\n}\n\nfunction is5xSelectionSet(selectionSet: CoreIModelSelectionSet): selectionSet is Omit<CoreIModelSelectionSet, \"add\" | \"remove\"> & {\n readonly active: { [P in keyof CoreSelectableIds]-?: Id64Set };\n add: (ids: Id64Arg | CoreSelectableIds) => boolean;\n remove: (ids: Id64Arg | CoreSelectableIds) => boolean;\n} {\n return \"active\" in selectionSet;\n}\n\n/* c8 ignore start */\nfunction createIModelHiliteSetProviderFromCachingProvider(\n cachingHiliteSetProvider: NonNullable<EnableUnifiedSelectionSyncWithIModelProps[\"cachingHiliteSetProvider\"]>,\n hiliteSetProvider: HiliteSetProvider,\n): IModelHiliteSetProvider {\n return {\n getHiliteSetProvider: () => hiliteSetProvider,\n getCurrentHiliteSet: (props) => cachingHiliteSetProvider.getHiliteSet(props),\n [Symbol.dispose]: () => {},\n };\n}\n/* c8 ignore end */\n"]}
|
|
1
|
+
{"version":3,"file":"EnableUnifiedSelectionSyncWithIModel.js","sourceRoot":"","sources":["../../../src/unified-selection/EnableUnifiedSelectionSyncWithIModel.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./DisposePolyfill.js\";\nimport { EMPTY, firstValueFrom, from, map, merge, Subject, takeUntil, toArray } from \"rxjs\";\nimport { Id64Arg, Id64Set } from \"@itwin/core-bentley\";\nimport { ECClassHierarchyInspector, ECSqlQueryExecutor } from \"@itwin/presentation-shared\";\nimport { CachingHiliteSetProvider } from \"./CachingHiliteSetProvider.js\";\nimport { createHiliteSetProvider, HiliteSet, HiliteSetProvider } from \"./HiliteSetProvider.js\";\nimport { createIModelHiliteSetProvider, IModelHiliteSetProvider } from \"./IModelHiliteSetProvider.js\";\nimport { SelectableInstanceKey, Selectables } from \"./Selectable.js\";\nimport { StorageSelectionChangeEventArgs, StorageSelectionChangeType } from \"./SelectionChangeEvent.js\";\nimport { computeSelection, SelectionScope } from \"./SelectionScope.js\";\nimport { SelectionStorage } from \"./SelectionStorage.js\";\nimport { CoreIModelHiliteSet, CoreIModelSelectionSet, CoreSelectableIds, CoreSelectionSetEventType, CoreSelectionSetEventUnsafe } from \"./types/IModel.js\";\nimport { safeDispose } from \"./Utils.js\";\n\n/**\n * Props for `enableUnifiedSelectionSyncWithIModel`.\n * @public\n */\nexport interface EnableUnifiedSelectionSyncWithIModelProps {\n /**\n * Provides access to different iModel's features: query executing, class hierarchy, selection and hilite sets.\n *\n * It's recommended to use `@itwin/presentation-core-interop` to create `key`, `ECSqlQueryExecutor` and `ECSchemaProvider` from\n * [IModelConnection](https://www.itwinjs.org/reference/core-frontend/imodelconnection/imodelconnection/), and map its\n * `hilited` and `selectionSet` attributes like this:\n *\n * ```ts\n * import { createECSqlQueryExecutor, createECSchemaProvider, createIModelKey } from \"@itwin/presentation-core-interop\";\n * import { createCachingECClassHierarchyInspector } from \"@itwin/presentation-shared\";\n * import { IModelConnection } from \"@itwin/core-frontend\";\n *\n * const imodel: IModelConnection = ...\n * const imodelAccess = {\n * ...createECSqlQueryExecutor(imodel),\n * ...createCachingECClassHierarchyInspector({ schemaProvider: createECSchemaProvider(MyAppFrontend.getSchemaContext(imodel)) }),\n * key: createIModelKey(imodel),\n * hiliteSet: imodel.hilited,\n * selectionSet: imodel.selectionSet,\n * };\n * ```\n */\n imodelAccess: ECSqlQueryExecutor &\n ECClassHierarchyInspector & {\n /** Key of the iModel. Generally taken from `IModelConnection.key`. */\n readonly key: string;\n /** The set of currently hilited elements taken from `IModelConnection.hilited`. */\n readonly hiliteSet: CoreIModelHiliteSet;\n /** The set of currently selected elements taken from `IModelConnection.selectionSet`. */\n readonly selectionSet: CoreIModelSelectionSet;\n };\n\n /**\n * Unified selection storage to synchronize IModel's tool selection with. The storage should be shared\n * across all components in the application to ensure unified selection experience.\n */\n selectionStorage: SelectionStorage;\n\n /** Active selection scope provider. */\n activeScopeProvider: () => SelectionScope;\n\n /**\n * An iModel hilite set provider used to retrieve hilite sets for different iModels. If not provided, a new `IModelHiliteSetProvider`\n * will be created for the given iModel using the provided `imodelAccess`.\n * If the consuming application already has a `IModelHiliteSetProvider` defined, it should be provided instead\n * to reuse the cache and avoid creating new providers for each iModel.\n *\n * @see `createIModelHiliteSetProvider`\n */\n imodelHiliteSetProvider?: IModelHiliteSetProvider;\n\n /**\n * A caching hilite set provider used to retrieve hilite sets for an iModel. If not provided, a new `CachingHiliteSetProvider`\n * will be created for the given iModel using the provided `imodelAccess`.\n * If the consuming application already has a `CachingHiliteSetProvider` defined, it should be provided instead\n * to reuse the cache and avoid creating new providers for each iModel.\n *\n * The type is defined in a way that makes it required for provider to have either the deprecated `dispose` or the\n * new `Symbol.dispose` method.\n *\n * **Warning:** When the given `CachingHiliteSetProvider` internally uses a custom `HiliteSetProvider`, the synchronization has\n * no access to it, and thus uses its own, default, `HiliteSetProvider`. As a result, the synchronization may not work as expected.\n * To alleviate this, the `imodelHiliteSetProvider` prop should be used instead.\n *\n * @deprecated in 1.5. Use `imodelHiliteSetProvider` prop instead.\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n cachingHiliteSetProvider?: CachingHiliteSetProvider | (Omit<CachingHiliteSetProvider, \"dispose\"> & { [Symbol.dispose]: () => void });\n}\n\n/**\n * Enables synchronization between iModel selection and unified selection.\n * @returns function for disposing the synchronization.\n * @public\n */\nexport function enableUnifiedSelectionSyncWithIModel(props: EnableUnifiedSelectionSyncWithIModelProps): () => void {\n const selectionHandler = new IModelSelectionHandler(props);\n return () => selectionHandler[Symbol.dispose]();\n}\n\n/**\n * A handler that syncs selection between unified selection storage (`SelectionStorage`) and\n * an iModel (`iModel.selectionSet`, `iModel.hilited`).\n *\n * @internal\n */\nexport class IModelSelectionHandler {\n private _selectionSourceName = \"Tool\";\n\n private _imodelAccess: EnableUnifiedSelectionSyncWithIModelProps[\"imodelAccess\"];\n private _selectionStorage: SelectionStorage;\n private _imodelHiliteSetProvider: NonNullable<EnableUnifiedSelectionSyncWithIModelProps[\"imodelHiliteSetProvider\"]>;\n private _activeScopeProvider: () => SelectionScope;\n\n private _isSuspended: boolean;\n private _selectionStorageChangeTracker = 0;\n private _cancelOngoingChanges = new Subject<void>();\n private _unregisterUnifiedSelectionListener: () => void;\n private _unregisterIModelSelectionSetListener: () => void;\n private _disposeInternalHiliteSetProvider: () => void;\n\n public constructor(props: EnableUnifiedSelectionSyncWithIModelProps & { hiliteSetProvider?: HiliteSetProvider }) {\n this._imodelAccess = props.imodelAccess;\n this._selectionStorage = props.selectionStorage;\n this._activeScopeProvider = props.activeScopeProvider;\n this._isSuspended = false;\n\n [this._imodelHiliteSetProvider, this._disposeInternalHiliteSetProvider] = (() => {\n if (props.imodelHiliteSetProvider) {\n return [props.imodelHiliteSetProvider, () => {}];\n }\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n if (props.cachingHiliteSetProvider) {\n return [\n createIModelHiliteSetProviderFromCachingProvider(\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n props.cachingHiliteSetProvider,\n props.hiliteSetProvider ?? createHiliteSetProvider({ imodelAccess: props.imodelAccess }),\n ),\n // don't need to dispose anything, because our wrapper has no dispose logic, and `cachingHiliteSetProvider` should be disposed\n // by whoever owns it\n () => {},\n ];\n }\n /* c8 ignore start */\n const internalProvider = createIModelHiliteSetProvider({\n selectionStorage: this._selectionStorage,\n imodelProvider: () => this._imodelAccess,\n createHiliteSetProvider: () => props.hiliteSetProvider ?? createHiliteSetProvider({ imodelAccess: props.imodelAccess }),\n });\n return [internalProvider, () => safeDispose(internalProvider)];\n /* c8 ignore end */\n })();\n\n this._unregisterIModelSelectionSetListener = this._imodelAccess.selectionSet.onChanged.addListener(this.onIModelSelectionChanged);\n this._unregisterUnifiedSelectionListener = this._selectionStorage.selectionChangeEvent.addListener(this.onUnifiedSelectionChanged);\n\n if (!is5xSelectionSet(this._imodelAccess.selectionSet)) {\n // itwinjs-core@4: stop imodel from syncing tool selection with hilited list - we want to manage that sync ourselves\n this._imodelAccess.hiliteSet.wantSyncWithSelectionSet = false;\n }\n\n this.applyCurrentHiliteSet({ activeSelectionAction: \"clearAll\" });\n }\n\n public [Symbol.dispose]() {\n this._cancelOngoingChanges.next();\n this._unregisterIModelSelectionSetListener();\n this._unregisterUnifiedSelectionListener();\n this._disposeInternalHiliteSetProvider();\n }\n\n /** Temporarily suspends tool selection synchronization until the returned disposable object is disposed. */\n public suspendIModelToolSelectionSync() {\n const wasSuspended = this._isSuspended;\n this._isSuspended = true;\n return {\n [Symbol.dispose]: () => {\n this._isSuspended = wasSuspended;\n },\n };\n }\n\n private syncHiliteSet(props: { changeType: StorageSelectionChangeType; selectables: Selectables; source: string }): void {\n const { changeType, selectables, source } = props;\n switch (changeType) {\n case \"clear\":\n return this.applyCurrentHiliteSet({ activeSelectionAction: \"clearAll\" });\n case \"replace\":\n return this.applyCurrentHiliteSet({\n activeSelectionAction:\n source === this._selectionSourceName\n ? is5xSelectionSet(this._imodelAccess.selectionSet)\n ? // with 5x core we don't need to clear anything when event is triggered by a Tool (hilite and selection sets are in sync already)\n \"keep\"\n : // with 4x core we need to clear hilite set, because it's not synced with selection set\n \"clearHilited\"\n : // when event is triggered not by a Tool, we need to clear everything\n \"clearAll\",\n });\n case \"add\":\n return void from(this._imodelHiliteSetProvider.getHiliteSetProvider({ imodelKey: this._imodelAccess.key }).getHiliteSet({ selectables }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (set) => {\n this.addHiliteSet(set);\n },\n });\n case \"remove\":\n return void from(this._imodelHiliteSetProvider.getHiliteSetProvider({ imodelKey: this._imodelAccess.key }).getHiliteSet({ selectables }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (set) => {\n this.removeHiliteSet(set);\n },\n complete: () => {\n this.applyCurrentHiliteSet({ activeSelectionAction: \"keep\" });\n },\n });\n }\n }\n\n private onUnifiedSelectionChanged = (args: StorageSelectionChangeEventArgs) => {\n // iModels are only interested in top-level selection changes\n if (args.imodelKey !== this._imodelAccess.key || args.level !== 0) {\n return;\n }\n\n // update the selection storage change tracker so we know the selection storage changed\n this._selectionStorageChangeTracker = (this._selectionStorageChangeTracker + 1) % Number.MAX_SAFE_INTEGER;\n\n if (args.changeType === \"replace\" || args.changeType === \"clear\") {\n this._cancelOngoingChanges.next();\n }\n this.syncHiliteSet(args);\n };\n\n private applyCurrentHiliteSet({ activeSelectionAction }: { activeSelectionAction: \"clearAll\" | \"clearHilited\" | \"keep\" }) {\n if (activeSelectionAction !== \"keep\") {\n using _dispose = this.suspendIModelToolSelectionSync();\n if (!is5xSelectionSet(this._imodelAccess.selectionSet)) {\n this._imodelAccess.hiliteSet.clear();\n }\n if (activeSelectionAction === \"clearAll\") {\n this._imodelAccess.selectionSet.emptyAll();\n }\n }\n\n from(this._imodelHiliteSetProvider.getCurrentHiliteSet({ imodelKey: this._imodelAccess.key }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (ids) => {\n this.addHiliteSet(ids);\n },\n });\n }\n\n private addHiliteSet(set: HiliteSet) {\n using _dispose = this.suspendIModelToolSelectionSync();\n if (is5xSelectionSet(this._imodelAccess.selectionSet)) {\n // with 5.x core we can simply add the set as a whole\n this._imodelAccess.selectionSet.add({\n models: set.models,\n subcategories: set.subCategories,\n elements: set.elements,\n });\n } else {\n // pre-5.0 core requires adding models and subcategories to hilite set separately\n if (set.models.length) {\n this._imodelAccess.hiliteSet.models.addIds(set.models);\n }\n if (set.subCategories.length) {\n this._imodelAccess.hiliteSet.subcategories.addIds(set.subCategories);\n }\n if (set.elements.length) {\n this._imodelAccess.hiliteSet.elements.addIds(set.elements);\n this._imodelAccess.selectionSet.add(set.elements);\n }\n }\n }\n\n private removeHiliteSet(set: HiliteSet) {\n using _dispose = this.suspendIModelToolSelectionSync();\n if (is5xSelectionSet(this._imodelAccess.selectionSet)) {\n // with 5.x core we can simply remove the set as a whole\n this._imodelAccess.selectionSet.remove({\n models: set.models,\n subcategories: set.subCategories,\n elements: set.elements,\n });\n } else {\n if (set.models.length) {\n this._imodelAccess.hiliteSet.models.deleteIds(set.models);\n }\n if (set.subCategories.length) {\n this._imodelAccess.hiliteSet.subcategories.deleteIds(set.subCategories);\n }\n if (set.elements.length) {\n this._imodelAccess.hiliteSet.elements.deleteIds(set.elements);\n this._imodelAccess.selectionSet.remove(set.elements);\n }\n }\n }\n\n private onIModelSelectionChanged = async (event: CoreSelectionSetEventUnsafe): Promise<void> => {\n if (this._isSuspended) {\n return;\n }\n\n if (CoreSelectionSetEventType.Clear === event.type) {\n this._selectionStorage.clearSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName });\n return;\n }\n\n const ids = getSelectionSetChangeIds(event);\n const scopedSelection = merge(\n ids.elements\n ? from(computeSelection({ queryExecutor: this._imodelAccess, elementIds: ids.elements, scope: this._activeScopeProvider() }))\n : /* c8 ignore next */ EMPTY,\n ids.models ? from(ids.models).pipe(map((id): SelectableInstanceKey => ({ className: \"BisCore.Model\", id }))) : /* c8 ignore next */ EMPTY,\n ids.subcategories\n ? from(ids.subcategories).pipe(map((id): SelectableInstanceKey => ({ className: \"BisCore.SubCategory\", id })))\n : /* c8 ignore next */ EMPTY,\n );\n\n const selectionStorageVersion = this._selectionStorageChangeTracker;\n const changeSelectionStorageProps = {\n imodelKey: this._imodelAccess.key,\n source: this._selectionSourceName,\n selectables: await firstValueFrom(scopedSelection.pipe(toArray())),\n };\n try {\n switch (event.type) {\n case CoreSelectionSetEventType.Add:\n return this._selectionStorage.addToSelection(changeSelectionStorageProps);\n case CoreSelectionSetEventType.Remove:\n return this._selectionStorage.removeFromSelection(changeSelectionStorageProps);\n case CoreSelectionSetEventType.Replace:\n return this._selectionStorage.replaceSelection(changeSelectionStorageProps);\n }\n } finally {\n if (this._selectionStorageChangeTracker === selectionStorageVersion) {\n // if the storage wasn't changed while we were processing the selection change, we have to re-sync the\n // hilite set (otherwise it's done by the selection storage change handler)\n this.syncHiliteSet({\n ...changeSelectionStorageProps,\n selectables: Selectables.create(changeSelectionStorageProps.selectables),\n changeType: getUnifiedSelectionChangeType(event.type),\n });\n }\n }\n };\n}\n\nfunction getSelectionSetChangeIds(\n event: Omit<CoreSelectionSetEventUnsafe, \"type\"> & {\n type: CoreSelectionSetEventType.Add | CoreSelectionSetEventType.Remove | CoreSelectionSetEventType.Replace;\n },\n): CoreSelectableIds {\n switch (event.type) {\n case CoreSelectionSetEventType.Add:\n return event.additions ?? (event.added ? { elements: event.added } : /* c8 ignore next */ {});\n case CoreSelectionSetEventType.Remove:\n return event.removals ?? (event.removed ? { elements: event.removed } : /* c8 ignore next */ {});\n case CoreSelectionSetEventType.Replace:\n return \"active\" in event.set ? event.set.active : { elements: event.set.elements };\n }\n}\n\nfunction getUnifiedSelectionChangeType(coreChangeType: CoreSelectionSetEventType): StorageSelectionChangeType {\n switch (coreChangeType) {\n case CoreSelectionSetEventType.Add:\n return \"add\";\n case CoreSelectionSetEventType.Remove:\n return \"remove\";\n case CoreSelectionSetEventType.Replace:\n return \"replace\";\n case CoreSelectionSetEventType.Clear:\n return \"clear\";\n }\n}\n\nfunction is5xSelectionSet(selectionSet: CoreIModelSelectionSet): selectionSet is Omit<CoreIModelSelectionSet, \"add\" | \"remove\"> & {\n readonly active: { [P in keyof CoreSelectableIds]-?: Id64Set };\n add: (ids: Id64Arg | CoreSelectableIds) => boolean;\n remove: (ids: Id64Arg | CoreSelectableIds) => boolean;\n} {\n return \"active\" in selectionSet;\n}\n\n/* c8 ignore start */\nfunction createIModelHiliteSetProviderFromCachingProvider(\n cachingHiliteSetProvider: NonNullable<EnableUnifiedSelectionSyncWithIModelProps[\"cachingHiliteSetProvider\"]>,\n hiliteSetProvider: HiliteSetProvider,\n): IModelHiliteSetProvider {\n return {\n getHiliteSetProvider: () => hiliteSetProvider,\n getCurrentHiliteSet: (props) => cachingHiliteSetProvider.getHiliteSet(props),\n [Symbol.dispose]: () => {},\n };\n}\n/* c8 ignore end */\n"]}
|
|
@@ -52,9 +52,9 @@ var Selectables;
|
|
|
52
52
|
* @public
|
|
53
53
|
*/
|
|
54
54
|
function size(selectables) {
|
|
55
|
-
let
|
|
56
|
-
selectables.instanceKeys.forEach((set) => (
|
|
57
|
-
return
|
|
55
|
+
let instanceCount = 0;
|
|
56
|
+
selectables.instanceKeys.forEach((set) => (instanceCount += set.size));
|
|
57
|
+
return instanceCount + selectables.custom.size;
|
|
58
58
|
}
|
|
59
59
|
Selectables.size = size;
|
|
60
60
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Selectable.js","sourceRoot":"","sources":["../../../src/unified-selection/Selectable.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAEhG,+BAAkD;AAClD,mDAA+C;AAE/C,oEAAoE;AA6CpE,cAAc;AACd,2DAA2D;AAC3D,IAAiB,UAAU,CAW1B;AAXD,WAAiB,UAAU;IACzB,oEAAoE;IACpE,SAAgB,aAAa,CAAC,UAA6C;QACzE,MAAM,WAAW,GAAG,UAAmC,CAAC;QACxD,OAAO,CAAC,CAAC,WAAW,CAAC,SAAS,IAAI,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC;IACrD,CAAC;IAHe,wBAAa,gBAG5B,CAAA;IAED,+DAA+D;IAC/D,SAAgB,QAAQ,CAAC,UAAsB;QAC7C,OAAO,CAAC,CAAE,UAA+B,CAAC,UAAU,CAAC;IACvD,CAAC;IAFe,mBAAQ,WAEvB,CAAA;AACH,CAAC,EAXgB,UAAU,0BAAV,UAAU,QAW1B;AAiBD;;;GAGG;AACU,QAAA,2BAA2B,GAAG,YAAY,CAAC;AAExD,cAAc;AACd,IAAiB,WAAW,CAyM3B;AAzMD,WAAiB,WAAW;IAC1B;;;;OAIG;IACH,SAAgB,MAAM,CAAC,MAAoB;QACzC,MAAM,cAAc,GAAG;YACrB,YAAY,EAAE,IAAI,GAAG,EAAuB;YAC5C,MAAM,EAAE,IAAI,GAAG,EAA4B;SAC5C,CAAC;QACF,WAAW,CAAC,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QACxC,OAAO,cAAc,CAAC;IACxB,CAAC;IAPe,kBAAM,SAOrB,CAAA;IAED;;;;OAIG;IACH,SAAgB,IAAI,CAAC,WAAwB;QAC3C,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,WAAW,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAgB,EAAE,EAAE,CAAC,CAAC,cAAc,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACrF,OAAO,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC;IAClD,CAAC;IAJe,gBAAI,OAInB,CAAA;IAED;;;;OAIG;IACH,SAAgB,OAAO,CAAC,WAAwB;QAC9C,OAAO,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IAFe,mBAAO,UAEtB,CAAA;IAED;;;;;OAKG;IACH,SAAgB,GAAG,CAAC,WAAwB,EAAE,KAA2B;QACvE,IAAI,UAAU,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YACpC,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAChE,MAAM,GAAG,GAAG,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;YAC9D,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAClD,CAAC;IAPe,eAAG,MAOlB,CAAA;IAED;;;;;OAKG;IACH,SAAgB,MAAM,CAAC,WAAwB,EAAE,MAA8B;QAC7E,IAAI,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;YAClD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,KAAK,MAAM,UAAU,IAAI,MAAM,EAAE,CAAC;YAChC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,CAAC;gBAC9C,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAVe,kBAAM,SAUrB,CAAA;IAED;;;;;OAKG;IACH,SAAgB,MAAM,CAAC,WAAwB,EAAE,MAA8B;QAC7E,KAAK,MAAM,UAAU,IAAI,MAAM,EAAE,CAAC;YAChC,IAAI,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,CAAC;gBAC7C,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAPe,kBAAM,SAOrB,CAAA;IAED;;;;;OAKG;IACH,SAAgB,GAAG,CAAC,WAAwB,EAAE,MAAoB;QAChE,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,KAAK,MAAM,UAAU,IAAI,MAAM,EAAE,CAAC;YAChC,IAAI,UAAU,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;gBACzC,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;gBACrE,IAAI,GAAG,GAAG,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;gBAC5D,IAAI,CAAC,GAAG,EAAE,CAAC;oBACT,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;gBAC1B,CAAC;gBACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC5B,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBACvB,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;oBACvD,UAAU,GAAG,IAAI,CAAC;gBACpB,CAAC;YACH,CAAC;iBAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC1D,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;gBAC1D,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;QACH,CAAC;QACD,OAAO,UAAU,CAAC;IACpB,CAAC;IApBe,eAAG,MAoBlB,CAAA;IAED;;;;;OAKG;IACH,SAAgB,MAAM,CAAC,WAAwB,EAAE,MAAoB;QACnE,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,KAAK,MAAM,UAAU,IAAI,MAAM,EAAE,CAAC;YAChC,IAAI,UAAU,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;gBACzC,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;gBACrE,MAAM,GAAG,GAAG,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;gBAC9D,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;oBAClC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBAC1B,UAAU,GAAG,IAAI,CAAC;oBAClB,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;wBACnB,WAAW,CAAC,YAAY,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;oBACvD,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBACzD,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;gBACjD,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;QACH,CAAC;QACD,OAAO,UAAU,CAAC;IACpB,CAAC;IAnBe,kBAAM,SAmBrB,CAAA;IAED;;;;OAIG;IACH,SAAgB,KAAK,CAAC,WAAwB;QAC5C,IAAI,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,WAAW,CAAC,YAAY,GAAG,IAAI,GAAG,EAAuB,CAAC;QAC1D,WAAW,CAAC,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IAPe,iBAAK,QAOpB,CAAA;IAED;;;;OAIG;IACH,SAAgB,IAAI,CAAC,WAAwB,EAAE,QAA6C;QAC1F,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,YAAY,EAAE,CAAC;YAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5B,IAAI,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;oBAChD,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACvC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvB,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAde,gBAAI,OAcnB,CAAA;IAED;;;;OAIG;IACH,SAAgB,OAAO,CAAC,WAAwB,EAAE,QAAyD;QACzG,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,WAAW,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAgB,EAAE,SAAiB,EAAE,EAAE;YACvE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QACH,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAClC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IARe,mBAAO,UAQtB,CAAA;IAED;;;;OAIG;IACH,SAAgB,IAAI,CAAC,WAAwB;QAC3C,OAAO,IAAA,8BAAa,EAClB,IAAA,YAAK,EACH,IAAA,WAAI,EAAC,WAAW,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAA,eAAQ,EAAC,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,IAAA,WAAI,EAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAA,UAAG,EAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EACrH,IAAA,WAAI,EAAC,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAA,eAAQ,EAAC,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,IAAA,WAAI,EAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAClG,CACF,CAAC;IACJ,CAAC;IAPe,gBAAI,OAOnB,CAAA;AACH,CAAC,EAzMgB,WAAW,2BAAX,WAAW,QAyM3B;AAED,SAAS,kBAAkB,CAAC,aAAqB;IAC/C,OAAO,aAAa,KAAK,mCAA2B,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAA,4CAAsB,EAAC,aAAa,CAAC,CAAC;AAC/G,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { from, map, merge, mergeMap } from \"rxjs\";\nimport { eachValueFrom } from \"rxjs-for-await\";\nimport { Id64String } from \"@itwin/core-bentley\";\nimport { normalizeFullClassName } from \"@itwin/presentation-shared\";\n\n/**\n * ECInstance selectable\n * @public\n */\nexport interface SelectableInstanceKey {\n /** Full class name in format `SchemaName:ClassName` or `SchemaName.ClassName`. */\n className: string;\n /** ECInstance ID */\n id: string;\n}\n\n/**\n * A custom selectable, which has an identifier, knows how to loads its associated selectable instance keys\n * and has custom data associated with it.\n *\n * An example of such selectable could be an instance grouping node:\n * - `identifier` could be a GUID, associated with the node,\n * - `loadInstanceKeys` would know how to load grouped instance keys from the node,\n * - `data` could be set to the node itself.\n *\n * @public\n */\nexport interface CustomSelectable {\n /** Unique identifier of the selectable. */\n identifier: string;\n /** Asynchronous function for loading instance keys associated with this selectable. */\n loadInstanceKeys: () => AsyncIterableIterator<SelectableInstanceKey>;\n /** Custom data associated with the selectable. */\n data: unknown;\n}\n\n/**\n * A single selectable that identifies something that can be selected in an iTwin.js application.\n * @public\n */\nexport type Selectable = SelectableInstanceKey | CustomSelectable;\n\n/**\n * A type of identifier that can be used to identify a selectable in selection storage.\n * @public\n */\nexport type SelectableIdentifier = SelectableInstanceKey | Pick<CustomSelectable, \"identifier\">;\n\n/** @public */\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace Selectable {\n /** Check if the supplied selectable is a `SelectableInstanceKey` */\n export function isInstanceKey(selectable: Selectable | SelectableIdentifier): selectable is SelectableInstanceKey {\n const instanceKey = selectable as SelectableInstanceKey;\n return !!instanceKey.className && !!instanceKey.id;\n }\n\n /** Check if the supplied selectable is a `CustomSelectable` */\n export function isCustom(selectable: Selectable): selectable is CustomSelectable {\n return !!(selectable as CustomSelectable).identifier;\n }\n}\n\n/**\n * A collection of selectables that identify something that can be selected in an iTwin.js application\n * @public\n */\nexport interface Selectables {\n /**\n * A map between `SelectableInstanceKey.className` and a set of selected instance IDs.\n */\n instanceKeys: Map<string, Set<Id64String>>;\n /**\n * A map between `CustomSelectable.identifier` and the selectable itself.\n */\n custom: Map<string, CustomSelectable>;\n}\n\n/**\n * Class name used to create `SelectableInstanceKey` for transient elements.\n * @public\n */\nexport const TRANSIENT_ELEMENT_CLASSNAME = \"/TRANSIENT\";\n\n/** @public */\nexport namespace Selectables {\n /**\n * Creates `Selectables` from array of selectable\n * @param source Source to create selectables from\n * @public\n */\n export function create(source: Selectable[]): Selectables {\n const newSelectables = {\n instanceKeys: new Map<string, Set<string>>(),\n custom: new Map<string, CustomSelectable>(),\n };\n Selectables.add(newSelectables, source);\n return newSelectables;\n }\n\n /**\n * Get the number of selectables stored in a `Selectables` object.\n * @param selectables `Selectables` object to get size for\n * @public\n */\n export function size(selectables: Selectables): number {\n let insatanceCount = 0;\n selectables.instanceKeys.forEach((set: Set<string>) => (insatanceCount += set.size));\n return insatanceCount + selectables.custom.size;\n }\n\n /**\n * Is a `Selectables` object currently empty.\n * @param selectables `Selectables` object to check\n * @public\n */\n export function isEmpty(selectables: Selectables): boolean {\n return Selectables.size(selectables) === 0;\n }\n\n /**\n * Check if a `Selectables` object contains the specified selectable.\n * @param selectables `Selectables` object to check\n * @param value The selectable to check for.\n * @public\n */\n export function has(selectables: Selectables, value: SelectableIdentifier): boolean {\n if (Selectable.isInstanceKey(value)) {\n const normalizedClassName = normalizeClassName(value.className);\n const set = selectables.instanceKeys.get(normalizedClassName);\n return !!(set && set.has(value.id));\n }\n return selectables.custom.has(value.identifier);\n }\n\n /**\n * Check if a `Selectables` object contains all the specified selectables.\n * @param selectables `Selectables` object to check\n * @param values The selectables to check for.\n * @public\n */\n export function hasAll(selectables: Selectables, values: SelectableIdentifier[]): boolean {\n if (Selectables.size(selectables) < values.length) {\n return false;\n }\n for (const selectable of values) {\n if (!Selectables.has(selectables, selectable)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Check if a `Selectables` object contains any of the specified selectables.\n * @param selectables `Selectables` object to check\n * @param values The selectables to check for.\n * @public\n */\n export function hasAny(selectables: Selectables, values: SelectableIdentifier[]): boolean {\n for (const selectable of values) {\n if (Selectables.has(selectables, selectable)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Add a one or more selectables to a `Selectables`\n * @param selectables `Selectables` object to add selectables for\n * @param values Selectables to add.\n * @public\n */\n export function add(selectables: Selectables, values: Selectable[]): boolean {\n let hasChanged = false;\n for (const selectable of values) {\n if (Selectable.isInstanceKey(selectable)) {\n const normalizedClassName = normalizeClassName(selectable.className);\n let set = selectables.instanceKeys.get(normalizedClassName);\n if (!set) {\n set = new Set<string>();\n }\n if (!set.has(selectable.id)) {\n set.add(selectable.id);\n selectables.instanceKeys.set(normalizedClassName, set);\n hasChanged = true;\n }\n } else if (!selectables.custom.has(selectable.identifier)) {\n selectables.custom.set(selectable.identifier, selectable);\n hasChanged = true;\n }\n }\n return hasChanged;\n }\n\n /**\n * Removes one or more selectables from a `Selectables` object.\n * @param selectables `Selectables` object to remove selectables for\n * @param values Selectables to remove.\n * @public\n */\n export function remove(selectables: Selectables, values: Selectable[]): boolean {\n let hasChanged = false;\n for (const selectable of values) {\n if (Selectable.isInstanceKey(selectable)) {\n const normalizedClassName = normalizeClassName(selectable.className);\n const set = selectables.instanceKeys.get(normalizedClassName);\n if (set && set.has(selectable.id)) {\n set.delete(selectable.id);\n hasChanged = true;\n if (set.size === 0) {\n selectables.instanceKeys.delete(normalizedClassName);\n }\n }\n } else if (selectables.custom.has(selectable.identifier)) {\n selectables.custom.delete(selectable.identifier);\n hasChanged = true;\n }\n }\n return hasChanged;\n }\n\n /**\n * Clear a `Selectables` object.\n * @param selectables `Selectables` object to clear selectables for\n * @public\n */\n export function clear(selectables: Selectables): boolean {\n if (Selectables.size(selectables) === 0) {\n return false;\n }\n selectables.instanceKeys = new Map<string, Set<string>>();\n selectables.custom = new Map<string, CustomSelectable>();\n return true;\n }\n\n /**\n * Check whether at least one selectable passes a condition in a `Selectables` object.\n * @param selectables `Selectables` object to check\n * @public\n */\n export function some(selectables: Selectables, callback: (selectable: Selectable) => boolean) {\n for (const entry of selectables.instanceKeys) {\n for (const item of entry[1]) {\n if (callback({ className: entry[0], id: item })) {\n return true;\n }\n }\n }\n for (const entry of selectables.custom) {\n if (callback(entry[1])) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Iterate over all keys in a `Selectables` object.\n * @param selectables `Selectables` object to iterate over\n * @public\n */\n export function forEach(selectables: Selectables, callback: (selectable: Selectable, index: number) => void) {\n let index = 0;\n selectables.instanceKeys.forEach((ids: Set<string>, className: string) => {\n ids.forEach((id: string) => callback({ className, id }, index++));\n });\n selectables.custom.forEach((data) => {\n callback(data, index++);\n });\n }\n\n /**\n * Load all instance keys from the given `Selectables` object.\n * @param selectables `Selectables` object to load instance keys from\n * @public\n */\n export function load(selectables: Selectables): AsyncIterableIterator<SelectableInstanceKey> {\n return eachValueFrom(\n merge(\n from(selectables.instanceKeys).pipe(mergeMap(([className, ids]) => from(ids).pipe(map((id) => ({ className, id }))))),\n from(selectables.custom).pipe(mergeMap(([_, selectable]) => from(selectable.loadInstanceKeys()))),\n ),\n );\n }\n}\n\nfunction normalizeClassName(fullClassName: string) {\n return fullClassName === TRANSIENT_ELEMENT_CLASSNAME ? fullClassName : normalizeFullClassName(fullClassName);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Selectable.js","sourceRoot":"","sources":["../../../src/unified-selection/Selectable.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { from, map, merge, mergeMap } from \"rxjs\";\nimport { eachValueFrom } from \"rxjs-for-await\";\nimport { Id64String } from \"@itwin/core-bentley\";\nimport { normalizeFullClassName } from \"@itwin/presentation-shared\";\n\n/**\n * ECInstance selectable\n * @public\n */\nexport interface SelectableInstanceKey {\n /** Full class name in format `SchemaName:ClassName` or `SchemaName.ClassName`. */\n className: string;\n /** ECInstance ID */\n id: string;\n}\n\n/**\n * A custom selectable, which has an identifier, knows how to loads its associated selectable instance keys\n * and has custom data associated with it.\n *\n * An example of such selectable could be an instance grouping node:\n * - `identifier` could be a GUID, associated with the node,\n * - `loadInstanceKeys` would know how to load grouped instance keys from the node,\n * - `data` could be set to the node itself.\n *\n * @public\n */\nexport interface CustomSelectable {\n /** Unique identifier of the selectable. */\n identifier: string;\n /** Asynchronous function for loading instance keys associated with this selectable. */\n loadInstanceKeys: () => AsyncIterableIterator<SelectableInstanceKey>;\n /** Custom data associated with the selectable. */\n data: unknown;\n}\n\n/**\n * A single selectable that identifies something that can be selected in an iTwin.js application.\n * @public\n */\nexport type Selectable = SelectableInstanceKey | CustomSelectable;\n\n/**\n * A type of identifier that can be used to identify a selectable in selection storage.\n * @public\n */\nexport type SelectableIdentifier = SelectableInstanceKey | Pick<CustomSelectable, \"identifier\">;\n\n/** @public */\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace Selectable {\n /** Check if the supplied selectable is a `SelectableInstanceKey` */\n export function isInstanceKey(selectable: Selectable | SelectableIdentifier): selectable is SelectableInstanceKey {\n const instanceKey = selectable as SelectableInstanceKey;\n return !!instanceKey.className && !!instanceKey.id;\n }\n\n /** Check if the supplied selectable is a `CustomSelectable` */\n export function isCustom(selectable: Selectable): selectable is CustomSelectable {\n return !!(selectable as CustomSelectable).identifier;\n }\n}\n\n/**\n * A collection of selectables that identify something that can be selected in an iTwin.js application\n * @public\n */\nexport interface Selectables {\n /**\n * A map between `SelectableInstanceKey.className` and a set of selected instance IDs.\n */\n instanceKeys: Map<string, Set<Id64String>>;\n /**\n * A map between `CustomSelectable.identifier` and the selectable itself.\n */\n custom: Map<string, CustomSelectable>;\n}\n\n/**\n * Class name used to create `SelectableInstanceKey` for transient elements.\n * @public\n */\nexport const TRANSIENT_ELEMENT_CLASSNAME = \"/TRANSIENT\";\n\n/** @public */\nexport namespace Selectables {\n /**\n * Creates `Selectables` from array of selectable\n * @param source Source to create selectables from\n * @public\n */\n export function create(source: Selectable[]): Selectables {\n const newSelectables = {\n instanceKeys: new Map<string, Set<string>>(),\n custom: new Map<string, CustomSelectable>(),\n };\n Selectables.add(newSelectables, source);\n return newSelectables;\n }\n\n /**\n * Get the number of selectables stored in a `Selectables` object.\n * @param selectables `Selectables` object to get size for\n * @public\n */\n export function size(selectables: Selectables): number {\n let instanceCount = 0;\n selectables.instanceKeys.forEach((set: Set<string>) => (instanceCount += set.size));\n return instanceCount + selectables.custom.size;\n }\n\n /**\n * Is a `Selectables` object currently empty.\n * @param selectables `Selectables` object to check\n * @public\n */\n export function isEmpty(selectables: Selectables): boolean {\n return Selectables.size(selectables) === 0;\n }\n\n /**\n * Check if a `Selectables` object contains the specified selectable.\n * @param selectables `Selectables` object to check\n * @param value The selectable to check for.\n * @public\n */\n export function has(selectables: Selectables, value: SelectableIdentifier): boolean {\n if (Selectable.isInstanceKey(value)) {\n const normalizedClassName = normalizeClassName(value.className);\n const set = selectables.instanceKeys.get(normalizedClassName);\n return !!(set && set.has(value.id));\n }\n return selectables.custom.has(value.identifier);\n }\n\n /**\n * Check if a `Selectables` object contains all the specified selectables.\n * @param selectables `Selectables` object to check\n * @param values The selectables to check for.\n * @public\n */\n export function hasAll(selectables: Selectables, values: SelectableIdentifier[]): boolean {\n if (Selectables.size(selectables) < values.length) {\n return false;\n }\n for (const selectable of values) {\n if (!Selectables.has(selectables, selectable)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Check if a `Selectables` object contains any of the specified selectables.\n * @param selectables `Selectables` object to check\n * @param values The selectables to check for.\n * @public\n */\n export function hasAny(selectables: Selectables, values: SelectableIdentifier[]): boolean {\n for (const selectable of values) {\n if (Selectables.has(selectables, selectable)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Add a one or more selectables to a `Selectables`\n * @param selectables `Selectables` object to add selectables for\n * @param values Selectables to add.\n * @public\n */\n export function add(selectables: Selectables, values: Selectable[]): boolean {\n let hasChanged = false;\n for (const selectable of values) {\n if (Selectable.isInstanceKey(selectable)) {\n const normalizedClassName = normalizeClassName(selectable.className);\n let set = selectables.instanceKeys.get(normalizedClassName);\n if (!set) {\n set = new Set<string>();\n }\n if (!set.has(selectable.id)) {\n set.add(selectable.id);\n selectables.instanceKeys.set(normalizedClassName, set);\n hasChanged = true;\n }\n } else if (!selectables.custom.has(selectable.identifier)) {\n selectables.custom.set(selectable.identifier, selectable);\n hasChanged = true;\n }\n }\n return hasChanged;\n }\n\n /**\n * Removes one or more selectables from a `Selectables` object.\n * @param selectables `Selectables` object to remove selectables for\n * @param values Selectables to remove.\n * @public\n */\n export function remove(selectables: Selectables, values: Selectable[]): boolean {\n let hasChanged = false;\n for (const selectable of values) {\n if (Selectable.isInstanceKey(selectable)) {\n const normalizedClassName = normalizeClassName(selectable.className);\n const set = selectables.instanceKeys.get(normalizedClassName);\n if (set && set.has(selectable.id)) {\n set.delete(selectable.id);\n hasChanged = true;\n if (set.size === 0) {\n selectables.instanceKeys.delete(normalizedClassName);\n }\n }\n } else if (selectables.custom.has(selectable.identifier)) {\n selectables.custom.delete(selectable.identifier);\n hasChanged = true;\n }\n }\n return hasChanged;\n }\n\n /**\n * Clear a `Selectables` object.\n * @param selectables `Selectables` object to clear selectables for\n * @public\n */\n export function clear(selectables: Selectables): boolean {\n if (Selectables.size(selectables) === 0) {\n return false;\n }\n selectables.instanceKeys = new Map<string, Set<string>>();\n selectables.custom = new Map<string, CustomSelectable>();\n return true;\n }\n\n /**\n * Check whether at least one selectable passes a condition in a `Selectables` object.\n * @param selectables `Selectables` object to check\n * @public\n */\n export function some(selectables: Selectables, callback: (selectable: Selectable) => boolean) {\n for (const entry of selectables.instanceKeys) {\n for (const item of entry[1]) {\n if (callback({ className: entry[0], id: item })) {\n return true;\n }\n }\n }\n for (const entry of selectables.custom) {\n if (callback(entry[1])) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Iterate over all keys in a `Selectables` object.\n * @param selectables `Selectables` object to iterate over\n * @public\n */\n export function forEach(selectables: Selectables, callback: (selectable: Selectable, index: number) => void) {\n let index = 0;\n selectables.instanceKeys.forEach((ids: Set<string>, className: string) => {\n ids.forEach((id: string) => callback({ className, id }, index++));\n });\n selectables.custom.forEach((data) => {\n callback(data, index++);\n });\n }\n\n /**\n * Load all instance keys from the given `Selectables` object.\n * @param selectables `Selectables` object to load instance keys from\n * @public\n */\n export function load(selectables: Selectables): AsyncIterableIterator<SelectableInstanceKey> {\n return eachValueFrom(\n merge(\n from(selectables.instanceKeys).pipe(mergeMap(([className, ids]) => from(ids).pipe(map((id) => ({ className, id }))))),\n from(selectables.custom).pipe(mergeMap(([_, selectable]) => from(selectable.loadInstanceKeys()))),\n ),\n );\n }\n}\n\nfunction normalizeClassName(fullClassName: string) {\n return fullClassName === TRANSIENT_ELEMENT_CLASSNAME ? fullClassName : normalizeFullClassName(fullClassName);\n}\n"]}
|
|
@@ -93,6 +93,7 @@ async function* computeModelSelection(queryExecutor, ids) {
|
|
|
93
93
|
async function* computeFunctionalElementSelection(queryExecutor, ids, ancestorLevel) {
|
|
94
94
|
const bindings = [];
|
|
95
95
|
const recurseUntilRoot = ancestorLevel < 0;
|
|
96
|
+
// cspell:disable
|
|
96
97
|
const ctes = [
|
|
97
98
|
`
|
|
98
99
|
Elements2dOrNearestFunctionalElements(OriginalECInstanceId, OriginalECClassId, ECInstanceId, ECClassId, ParentId) AS (
|
|
@@ -179,6 +180,7 @@ async function* computeFunctionalElementSelection(queryExecutor, ids, ancestorLe
|
|
|
179
180
|
SELECT DISTINCT ECInstanceId, ClassName FROM Element3dAncestorRelatedFunctionalElement
|
|
180
181
|
`,
|
|
181
182
|
].join(" UNION ");
|
|
183
|
+
// cspell:enable
|
|
182
184
|
yield* executeQuery(queryExecutor, { ctes, ecsql, bindings });
|
|
183
185
|
}
|
|
184
186
|
function formAncestorLevelBinding(ancestorLevel, bindings) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectionScope.js","sourceRoot":"","sources":["../../../src/unified-selection/SelectionScope.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Id64, Id64Arg, Id64Array } from \"@itwin/core-bentley\";\nimport { ECSqlBinding, ECSqlQueryDef, ECSqlQueryExecutor, ECSqlQueryRow } from \"@itwin/presentation-shared\";\nimport { SelectableInstanceKey } from \"./Selectable.js\";\nimport { formIdBindings, genericExecuteQuery } from \"./Utils.js\";\n\n/**\n * Available selection scopes.\n * @public\n */\ntype SelectionScopeIdentifier = \"element\" | \"model\" | \"category\" | \"functional\";\n\n/**\n * Props for computing element selection.\n * @public\n */\nexport interface ElementSelectionScopeProps {\n /** Identifies this as either \"element\" or \"functional\" selection scope */\n id: \"element\" | \"functional\";\n /**\n * Specifies how far \"up\" we should walk to find the target element. When not specified or `0`,\n * the target element matches the request element. When set to `1`, the target element matches the direct parent element.\n * When set to `2`, the target element is parent of the parent element and so on. In all situations when this is `> 0`,\n * we're not walking further than the last existing element, for example when `ancestorLevel = 1` (direct parent\n * element is requested), but the request element doesn't have a parent, the request element is returned as the result.\n * A negative value would result in the top-most element to be returned.\n */\n ancestorLevel?: number;\n}\n\n/**\n * A union of types that can be used to define a selection scope.\n * @public\n * @since 1.4.0\n */\nexport type SelectionScope = ElementSelectionScopeProps | { id: SelectionScopeIdentifier } | SelectionScopeIdentifier;\n\n/**\n * Props for `computeSelection`.\n * @public\n */\nexport interface ComputeSelectionProps {\n /** iModel query executor. */\n queryExecutor: ECSqlQueryExecutor;\n /** IDs of elements to compute selection for. */\n elementIds: Id64Arg;\n /** Selection scope to compute selection with. */\n scope: SelectionScope;\n}\n\n/**\n * Computes selection from given element IDs.\n * @public\n */\nexport async function* computeSelection(props: ComputeSelectionProps): AsyncIterableIterator<SelectableInstanceKey> {\n const { queryExecutor, elementIds, scope } = props;\n\n if (typeof scope === \"string\") {\n yield* computeSelection({ queryExecutor, elementIds, scope: { id: scope } });\n return;\n }\n\n const nonTransientIds: Id64Array = [];\n for (const id of Id64.iterable(elementIds)) {\n if (!Id64.isTransient(id)) {\n nonTransientIds.push(id);\n }\n }\n\n switch (scope.id) {\n case \"element\":\n yield* computeElementSelection(queryExecutor, nonTransientIds, (scope as ElementSelectionScopeProps).ancestorLevel ?? 0);\n return;\n case \"category\":\n yield* computeCategorySelection(queryExecutor, nonTransientIds);\n return;\n case \"model\":\n yield* computeModelSelection(queryExecutor, nonTransientIds);\n return;\n case \"functional\":\n yield* computeFunctionalElementSelection(queryExecutor, nonTransientIds, (scope as ElementSelectionScopeProps).ancestorLevel ?? 0);\n return;\n }\n}\n\nasync function* computeElementSelection(\n queryExecutor: ECSqlQueryExecutor,\n elementIds: string[],\n ancestorLevel: number,\n): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const recurseUntilRoot = ancestorLevel < 0;\n const ctes = [\n `\n AncestorElements(ECInstanceId, ECClassId, Depth, ParentId) AS (\n SELECT ECInstanceId, ECClassId, ${formAncestorLevelBinding(ancestorLevel, bindings)}, Parent.Id\n FROM BisCore.Element\n WHERE ${formIdBindings(\"ECInstanceId\", elementIds, bindings)}\n UNION ALL\n SELECT pe.ECInstanceId, pe.ECClassId, a.Depth - 1, pe.Parent.Id\n FROM AncestorElements a\n JOIN BisCore.Element pe ON pe.ECInstanceId = a.ParentId\n WHERE ${recurseUntilRoot ? \"\" : \"Depth > 0 AND\"} ParentId IS NOT NULL\n )\n `,\n ];\n const ecsql = `\n SELECT DISTINCT ECInstanceId, ec_classname(ECClassId, 's.c') AS ClassName\n FROM AncestorElements\n WHERE ${recurseUntilRoot ? \"\" : \"Depth = 0 OR\"} ParentId IS NULL\n `;\n yield* executeQuery(queryExecutor, { ctes, ecsql, bindings });\n}\n\nasync function* computeCategorySelection(queryExecutor: ECSqlQueryExecutor, ids: string[]): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const ecsql = [\n `\n SELECT DISTINCT c.ECInstanceId, ec_classname(c.ECClassId, 's.c') AS ClassName\n FROM BisCore.Category c\n JOIN BisCore.GeometricElement2d ge ON ge.Category.Id = c.ECInstanceId\n WHERE ${formIdBindings(\"ge.ECInstanceId\", ids, bindings)}\n `,\n `\n SELECT DISTINCT c.ECInstanceId, ec_classname(c.ECClassId, 's.c') AS ClassName\n FROM BisCore.Category c\n JOIN BisCore.GeometricElement3d ge ON ge.Category.Id = c.ECInstanceId\n WHERE ${formIdBindings(\"ge.ECInstanceId\", ids, bindings)}\n `,\n ].join(\" UNION ALL \");\n yield* executeQuery(queryExecutor, { ecsql, bindings });\n}\n\nasync function* computeModelSelection(queryExecutor: ECSqlQueryExecutor, ids: string[]): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const ecsql = `\n SELECT DISTINCT m.ECInstanceId, ec_classname(m.ECClassId, 's.c') AS ClassName\n FROM BisCore.Model m\n JOIN BisCore.Element e ON e.Model.Id = m.ECInstanceId\n WHERE ${formIdBindings(\"e.ECInstanceId\", ids, bindings)}\n `;\n yield* executeQuery(queryExecutor, { ecsql, bindings });\n}\n\nasync function* computeFunctionalElementSelection(\n queryExecutor: ECSqlQueryExecutor,\n ids: string[],\n ancestorLevel: number,\n): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const recurseUntilRoot = ancestorLevel < 0;\n const ctes = [\n `\n Elements2dOrNearestFunctionalElements(OriginalECInstanceId, OriginalECClassId, ECInstanceId, ECClassId, ParentId) AS (\n SELECT ECInstanceId, ECClassId, ECInstanceId, ECClassId, Parent.Id\n FROM BisCore.Element\n WHERE ${formIdBindings(\"ECInstanceId\", ids, bindings)} AND ECClassId IS NOT (BisCore.GeometricElement3d)\n UNION ALL\n SELECT\n e2onfe.OriginalECInstanceId,\n e2onfe.OriginalECClassId,\n COALESCE(dgrfe.TargetECInstanceId, pe.ECInstanceId),\n COALESCE(dgrfe.TargetECClassId, pe.ECClassId),\n pe.Parent.Id\n FROM Elements2dOrNearestFunctionalElements e2onfe\n LEFT JOIN BisCore.Element pe ON pe.ECInstanceId = e2onfe.ParentId\n LEFT JOIN Functional.DrawingGraphicRepresentsFunctionalElement dgrfe ON dgrfe.SourceECInstanceId = e2onfe.ECInstanceId\n WHERE e2onfe.ECClassId IS NOT (Functional.FunctionalElement) AND (e2onfe.ParentId IS NOT NULL OR dgrfe.TargetECInstanceId IS NOT NULL)\n )\n `,\n `\n Element2dNearestFunctionalElements(OriginalECInstanceId, ECInstanceId, ECClassId) AS (\n SELECT OriginalECInstanceId, ECInstanceId, ECClassId\n FROM Elements2dOrNearestFunctionalElements\n WHERE ECClassId IS (Functional.FunctionalElement)\n )\n `,\n `\n Elements2dWithoutFunctionalElement(ECInstanceId, ECClassId) AS (\n SELECT e2wfe.OriginalECInstanceId, OriginalECClassId\n FROM Elements2dOrNearestFunctionalElements e2wfe\n LEFT JOIN Element2dNearestFunctionalElements e2nfe ON e2nfe.OriginalECInstanceId = e2wfe.OriginalECInstanceId\n WHERE e2wfe.ParentId IS NULL AND e2nfe.ECInstanceId IS NULL\n )\n `,\n `\n Elements2d(ECInstanceId, ECClassId) AS (\n SELECT ECInstanceId, ECClassId FROM Element2dNearestFunctionalElements\n UNION\n SELECT ECInstanceId, ECClassId FROM Elements2dWithoutFunctionalElement\n )\n `,\n `\n Element2dAncestorElements(ECInstanceId, ECClassId, Depth, ParentId) AS (\n SELECT e.ECInstanceId, e.ECClassId, ${formAncestorLevelBinding(ancestorLevel, bindings)}, e.Parent.Id\n FROM BisCore.Element e\n JOIN Elements2d e2d ON e2d.ECInstanceId = e.ECInstanceId\n UNION ALL\n SELECT pe.ECInstanceId, pe.ECClassId, e2ae.Depth - 1, pe.Parent.Id\n FROM Element2dAncestorElements e2ae\n JOIN BisCore.Element pe ON pe.ECInstanceId = e2ae.ParentId\n WHERE ${recurseUntilRoot ? \"\" : \"Depth > 0 AND\"} ParentId IS NOT NULL\n )\n `,\n `\n Element3dAncestorElements(ECInstanceId, ECClassId, Depth, ParentId) AS (\n SELECT ge.ECInstanceId, ge.ECClassId, ${formAncestorLevelBinding(ancestorLevel, bindings)}, ge.Parent.Id\n FROM BisCore.GeometricElement3d ge\n WHERE ${formIdBindings(\"ge.ECInstanceId\", ids, bindings)}\n UNION ALL\n SELECT pe.ECInstanceId, pe.ECClassId, e3ae.Depth - 1, pe.Parent.Id\n FROM Element3dAncestorElements e3ae\n JOIN BisCore.Element pe ON pe.ECInstanceId = e3ae.ParentId\n WHERE ${recurseUntilRoot ? \"\" : \"Depth > 0 AND\"} ParentId IS NOT NULL\n )\n `,\n `\n Element3dAncestorRelatedFunctionalElement(ECInstanceId, ClassName) AS (\n SELECT\n COALESCE(peff.TargetECInstanceId, e3ae.ECInstanceId),\n ec_classname(COALESCE(peff.TargetECClassId, e3ae.ECClassId), 's.c')\n FROM Element3dAncestorElements e3ae\n LEFT JOIN Functional.PhysicalElementFulfillsFunction peff ON peff.SourceECInstanceId = e3ae.ECInstanceId\n WHERE ${recurseUntilRoot ? \"\" : \"e3ae.Depth = 0 OR\"} e3ae.ParentId IS NULL\n )\n `,\n ];\n const ecsql = [\n `\n SELECT DISTINCT ECInstanceId, ec_classname(ECClassId, 's.c') AS ClassName\n FROM Element2dAncestorElements\n WHERE ${recurseUntilRoot ? \"\" : \"Depth = 0 OR\"} ParentId IS NULL\n `,\n `\n SELECT DISTINCT ECInstanceId, ClassName FROM Element3dAncestorRelatedFunctionalElement\n `,\n ].join(\" UNION \");\n yield* executeQuery(queryExecutor, { ctes, ecsql, bindings });\n}\n\nfunction formAncestorLevelBinding(ancestorLevel: number, bindings: ECSqlBinding[]) {\n bindings.push({ type: \"int\", value: ancestorLevel });\n return \"?\";\n}\n\nasync function* executeQuery(queryExecutor: ECSqlQueryExecutor, query: ECSqlQueryDef): AsyncIterableIterator<SelectableInstanceKey> {\n yield* genericExecuteQuery(queryExecutor, query, (row: ECSqlQueryRow) => ({\n className: row.ClassName,\n id: row.ECInstanceId,\n }));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SelectionScope.js","sourceRoot":"","sources":["../../../src/unified-selection/SelectionScope.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;AAuDhG,4CA6BC;AAlFD,sDAA+D;AAG/D,yCAAiE;AA8CjE;;;GAGG;AACI,KAAK,SAAS,CAAC,CAAC,gBAAgB,CAAC,KAA4B;IAClE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAEnD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,KAAK,CAAC,CAAC,gBAAgB,CAAC,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7E,OAAO;IACT,CAAC;IAED,MAAM,eAAe,GAAc,EAAE,CAAC;IACtC,KAAK,MAAM,EAAE,IAAI,mBAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3C,IAAI,CAAC,mBAAI,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC;YAC1B,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,QAAQ,KAAK,CAAC,EAAE,EAAE,CAAC;QACjB,KAAK,SAAS;YACZ,KAAK,CAAC,CAAC,uBAAuB,CAAC,aAAa,EAAE,eAAe,EAAG,KAAoC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC;YACzH,OAAO;QACT,KAAK,UAAU;YACb,KAAK,CAAC,CAAC,wBAAwB,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;YAChE,OAAO;QACT,KAAK,OAAO;YACV,KAAK,CAAC,CAAC,qBAAqB,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;YAC7D,OAAO;QACT,KAAK,YAAY;YACf,KAAK,CAAC,CAAC,iCAAiC,CAAC,aAAa,EAAE,eAAe,EAAG,KAAoC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC;YACnI,OAAO;IACX,CAAC;AACH,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,uBAAuB,CACrC,aAAiC,EACjC,UAAoB,EACpB,aAAqB;IAErB,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,MAAM,gBAAgB,GAAG,aAAa,GAAG,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG;QACX;;0CAEsC,wBAAwB,CAAC,aAAa,EAAE,QAAQ,CAAC;;gBAE3E,IAAA,yBAAc,EAAC,cAAc,EAAE,UAAU,EAAE,QAAQ,CAAC;;;;;gBAKpD,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe;;KAElD;KACF,CAAC;IACF,MAAM,KAAK,GAAG;;;YAGJ,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc;GAC/C,CAAC;IACF,KAAK,CAAC,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,wBAAwB,CAAC,aAAiC,EAAE,GAAa;IACvF,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG;QACZ;;;;cAIU,IAAA,yBAAc,EAAC,iBAAiB,EAAE,GAAG,EAAE,QAAQ,CAAC;KACzD;QACD;;;;cAIU,IAAA,yBAAc,EAAC,iBAAiB,EAAE,GAAG,EAAE,QAAQ,CAAC;KACzD;KACF,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACtB,KAAK,CAAC,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,qBAAqB,CAAC,aAAiC,EAAE,GAAa;IACpF,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG;;;;YAIJ,IAAA,yBAAc,EAAC,gBAAgB,EAAE,GAAG,EAAE,QAAQ,CAAC;GACxD,CAAC;IACF,KAAK,CAAC,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,iCAAiC,CAC/C,aAAiC,EACjC,GAAa,EACb,aAAqB;IAErB,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,MAAM,gBAAgB,GAAG,aAAa,GAAG,CAAC,CAAC;IAC3C,iBAAiB;IACjB,MAAM,IAAI,GAAG;QACX;;;;gBAIY,IAAA,yBAAc,EAAC,cAAc,EAAE,GAAG,EAAE,QAAQ,CAAC;;;;;;;;;;;;;KAaxD;QACD;;;;;;KAMC;QACD;;;;;;;KAOC;QACD;;;;;;KAMC;QACD;;8CAE0C,wBAAwB,CAAC,aAAa,EAAE,QAAQ,CAAC;;;;;;;gBAO/E,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe;;KAElD;QACD;;gDAE4C,wBAAwB,CAAC,aAAa,EAAE,QAAQ,CAAC;;gBAEjF,IAAA,yBAAc,EAAC,iBAAiB,EAAE,GAAG,EAAE,QAAQ,CAAC;;;;;gBAKhD,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe;;KAElD;QACD;;;;;;;gBAOY,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB;;KAEtD;KACF,CAAC;IACF,MAAM,KAAK,GAAG;QACZ;;;eAGW,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc;KAChD;QACD;;KAEC;KACF,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAClB,gBAAgB;IAChB,KAAK,CAAC,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,wBAAwB,CAAC,aAAqB,EAAE,QAAwB;IAC/E,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;IACrD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,YAAY,CAAC,aAAiC,EAAE,KAAoB;IAClF,KAAK,CAAC,CAAC,IAAA,8BAAmB,EAAC,aAAa,EAAE,KAAK,EAAE,CAAC,GAAkB,EAAE,EAAE,CAAC,CAAC;QACxE,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,EAAE,EAAE,GAAG,CAAC,YAAY;KACrB,CAAC,CAAC,CAAC;AACN,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Id64, Id64Arg, Id64Array } from \"@itwin/core-bentley\";\nimport { ECSqlBinding, ECSqlQueryDef, ECSqlQueryExecutor, ECSqlQueryRow } from \"@itwin/presentation-shared\";\nimport { SelectableInstanceKey } from \"./Selectable.js\";\nimport { formIdBindings, genericExecuteQuery } from \"./Utils.js\";\n\n/**\n * Available selection scopes.\n * @public\n */\ntype SelectionScopeIdentifier = \"element\" | \"model\" | \"category\" | \"functional\";\n\n/**\n * Props for computing element selection.\n * @public\n */\nexport interface ElementSelectionScopeProps {\n /** Identifies this as either \"element\" or \"functional\" selection scope */\n id: \"element\" | \"functional\";\n /**\n * Specifies how far \"up\" we should walk to find the target element. When not specified or `0`,\n * the target element matches the request element. When set to `1`, the target element matches the direct parent element.\n * When set to `2`, the target element is parent of the parent element and so on. In all situations when this is `> 0`,\n * we're not walking further than the last existing element, for example when `ancestorLevel = 1` (direct parent\n * element is requested), but the request element doesn't have a parent, the request element is returned as the result.\n * A negative value would result in the top-most element to be returned.\n */\n ancestorLevel?: number;\n}\n\n/**\n * A union of types that can be used to define a selection scope.\n * @public\n * @since 1.4.0\n */\nexport type SelectionScope = ElementSelectionScopeProps | { id: SelectionScopeIdentifier } | SelectionScopeIdentifier;\n\n/**\n * Props for `computeSelection`.\n * @public\n */\nexport interface ComputeSelectionProps {\n /** iModel query executor. */\n queryExecutor: ECSqlQueryExecutor;\n /** IDs of elements to compute selection for. */\n elementIds: Id64Arg;\n /** Selection scope to compute selection with. */\n scope: SelectionScope;\n}\n\n/**\n * Computes selection from given element IDs.\n * @public\n */\nexport async function* computeSelection(props: ComputeSelectionProps): AsyncIterableIterator<SelectableInstanceKey> {\n const { queryExecutor, elementIds, scope } = props;\n\n if (typeof scope === \"string\") {\n yield* computeSelection({ queryExecutor, elementIds, scope: { id: scope } });\n return;\n }\n\n const nonTransientIds: Id64Array = [];\n for (const id of Id64.iterable(elementIds)) {\n if (!Id64.isTransient(id)) {\n nonTransientIds.push(id);\n }\n }\n\n switch (scope.id) {\n case \"element\":\n yield* computeElementSelection(queryExecutor, nonTransientIds, (scope as ElementSelectionScopeProps).ancestorLevel ?? 0);\n return;\n case \"category\":\n yield* computeCategorySelection(queryExecutor, nonTransientIds);\n return;\n case \"model\":\n yield* computeModelSelection(queryExecutor, nonTransientIds);\n return;\n case \"functional\":\n yield* computeFunctionalElementSelection(queryExecutor, nonTransientIds, (scope as ElementSelectionScopeProps).ancestorLevel ?? 0);\n return;\n }\n}\n\nasync function* computeElementSelection(\n queryExecutor: ECSqlQueryExecutor,\n elementIds: string[],\n ancestorLevel: number,\n): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const recurseUntilRoot = ancestorLevel < 0;\n const ctes = [\n `\n AncestorElements(ECInstanceId, ECClassId, Depth, ParentId) AS (\n SELECT ECInstanceId, ECClassId, ${formAncestorLevelBinding(ancestorLevel, bindings)}, Parent.Id\n FROM BisCore.Element\n WHERE ${formIdBindings(\"ECInstanceId\", elementIds, bindings)}\n UNION ALL\n SELECT pe.ECInstanceId, pe.ECClassId, a.Depth - 1, pe.Parent.Id\n FROM AncestorElements a\n JOIN BisCore.Element pe ON pe.ECInstanceId = a.ParentId\n WHERE ${recurseUntilRoot ? \"\" : \"Depth > 0 AND\"} ParentId IS NOT NULL\n )\n `,\n ];\n const ecsql = `\n SELECT DISTINCT ECInstanceId, ec_classname(ECClassId, 's.c') AS ClassName\n FROM AncestorElements\n WHERE ${recurseUntilRoot ? \"\" : \"Depth = 0 OR\"} ParentId IS NULL\n `;\n yield* executeQuery(queryExecutor, { ctes, ecsql, bindings });\n}\n\nasync function* computeCategorySelection(queryExecutor: ECSqlQueryExecutor, ids: string[]): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const ecsql = [\n `\n SELECT DISTINCT c.ECInstanceId, ec_classname(c.ECClassId, 's.c') AS ClassName\n FROM BisCore.Category c\n JOIN BisCore.GeometricElement2d ge ON ge.Category.Id = c.ECInstanceId\n WHERE ${formIdBindings(\"ge.ECInstanceId\", ids, bindings)}\n `,\n `\n SELECT DISTINCT c.ECInstanceId, ec_classname(c.ECClassId, 's.c') AS ClassName\n FROM BisCore.Category c\n JOIN BisCore.GeometricElement3d ge ON ge.Category.Id = c.ECInstanceId\n WHERE ${formIdBindings(\"ge.ECInstanceId\", ids, bindings)}\n `,\n ].join(\" UNION ALL \");\n yield* executeQuery(queryExecutor, { ecsql, bindings });\n}\n\nasync function* computeModelSelection(queryExecutor: ECSqlQueryExecutor, ids: string[]): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const ecsql = `\n SELECT DISTINCT m.ECInstanceId, ec_classname(m.ECClassId, 's.c') AS ClassName\n FROM BisCore.Model m\n JOIN BisCore.Element e ON e.Model.Id = m.ECInstanceId\n WHERE ${formIdBindings(\"e.ECInstanceId\", ids, bindings)}\n `;\n yield* executeQuery(queryExecutor, { ecsql, bindings });\n}\n\nasync function* computeFunctionalElementSelection(\n queryExecutor: ECSqlQueryExecutor,\n ids: string[],\n ancestorLevel: number,\n): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const recurseUntilRoot = ancestorLevel < 0;\n // cspell:disable\n const ctes = [\n `\n Elements2dOrNearestFunctionalElements(OriginalECInstanceId, OriginalECClassId, ECInstanceId, ECClassId, ParentId) AS (\n SELECT ECInstanceId, ECClassId, ECInstanceId, ECClassId, Parent.Id\n FROM BisCore.Element\n WHERE ${formIdBindings(\"ECInstanceId\", ids, bindings)} AND ECClassId IS NOT (BisCore.GeometricElement3d)\n UNION ALL\n SELECT\n e2onfe.OriginalECInstanceId,\n e2onfe.OriginalECClassId,\n COALESCE(dgrfe.TargetECInstanceId, pe.ECInstanceId),\n COALESCE(dgrfe.TargetECClassId, pe.ECClassId),\n pe.Parent.Id\n FROM Elements2dOrNearestFunctionalElements e2onfe\n LEFT JOIN BisCore.Element pe ON pe.ECInstanceId = e2onfe.ParentId\n LEFT JOIN Functional.DrawingGraphicRepresentsFunctionalElement dgrfe ON dgrfe.SourceECInstanceId = e2onfe.ECInstanceId\n WHERE e2onfe.ECClassId IS NOT (Functional.FunctionalElement) AND (e2onfe.ParentId IS NOT NULL OR dgrfe.TargetECInstanceId IS NOT NULL)\n )\n `,\n `\n Element2dNearestFunctionalElements(OriginalECInstanceId, ECInstanceId, ECClassId) AS (\n SELECT OriginalECInstanceId, ECInstanceId, ECClassId\n FROM Elements2dOrNearestFunctionalElements\n WHERE ECClassId IS (Functional.FunctionalElement)\n )\n `,\n `\n Elements2dWithoutFunctionalElement(ECInstanceId, ECClassId) AS (\n SELECT e2wfe.OriginalECInstanceId, OriginalECClassId\n FROM Elements2dOrNearestFunctionalElements e2wfe\n LEFT JOIN Element2dNearestFunctionalElements e2nfe ON e2nfe.OriginalECInstanceId = e2wfe.OriginalECInstanceId\n WHERE e2wfe.ParentId IS NULL AND e2nfe.ECInstanceId IS NULL\n )\n `,\n `\n Elements2d(ECInstanceId, ECClassId) AS (\n SELECT ECInstanceId, ECClassId FROM Element2dNearestFunctionalElements\n UNION\n SELECT ECInstanceId, ECClassId FROM Elements2dWithoutFunctionalElement\n )\n `,\n `\n Element2dAncestorElements(ECInstanceId, ECClassId, Depth, ParentId) AS (\n SELECT e.ECInstanceId, e.ECClassId, ${formAncestorLevelBinding(ancestorLevel, bindings)}, e.Parent.Id\n FROM BisCore.Element e\n JOIN Elements2d e2d ON e2d.ECInstanceId = e.ECInstanceId\n UNION ALL\n SELECT pe.ECInstanceId, pe.ECClassId, e2ae.Depth - 1, pe.Parent.Id\n FROM Element2dAncestorElements e2ae\n JOIN BisCore.Element pe ON pe.ECInstanceId = e2ae.ParentId\n WHERE ${recurseUntilRoot ? \"\" : \"Depth > 0 AND\"} ParentId IS NOT NULL\n )\n `,\n `\n Element3dAncestorElements(ECInstanceId, ECClassId, Depth, ParentId) AS (\n SELECT ge.ECInstanceId, ge.ECClassId, ${formAncestorLevelBinding(ancestorLevel, bindings)}, ge.Parent.Id\n FROM BisCore.GeometricElement3d ge\n WHERE ${formIdBindings(\"ge.ECInstanceId\", ids, bindings)}\n UNION ALL\n SELECT pe.ECInstanceId, pe.ECClassId, e3ae.Depth - 1, pe.Parent.Id\n FROM Element3dAncestorElements e3ae\n JOIN BisCore.Element pe ON pe.ECInstanceId = e3ae.ParentId\n WHERE ${recurseUntilRoot ? \"\" : \"Depth > 0 AND\"} ParentId IS NOT NULL\n )\n `,\n `\n Element3dAncestorRelatedFunctionalElement(ECInstanceId, ClassName) AS (\n SELECT\n COALESCE(peff.TargetECInstanceId, e3ae.ECInstanceId),\n ec_classname(COALESCE(peff.TargetECClassId, e3ae.ECClassId), 's.c')\n FROM Element3dAncestorElements e3ae\n LEFT JOIN Functional.PhysicalElementFulfillsFunction peff ON peff.SourceECInstanceId = e3ae.ECInstanceId\n WHERE ${recurseUntilRoot ? \"\" : \"e3ae.Depth = 0 OR\"} e3ae.ParentId IS NULL\n )\n `,\n ];\n const ecsql = [\n `\n SELECT DISTINCT ECInstanceId, ec_classname(ECClassId, 's.c') AS ClassName\n FROM Element2dAncestorElements\n WHERE ${recurseUntilRoot ? \"\" : \"Depth = 0 OR\"} ParentId IS NULL\n `,\n `\n SELECT DISTINCT ECInstanceId, ClassName FROM Element3dAncestorRelatedFunctionalElement\n `,\n ].join(\" UNION \");\n // cspell:enable\n yield* executeQuery(queryExecutor, { ctes, ecsql, bindings });\n}\n\nfunction formAncestorLevelBinding(ancestorLevel: number, bindings: ECSqlBinding[]) {\n bindings.push({ type: \"int\", value: ancestorLevel });\n return \"?\";\n}\n\nasync function* executeQuery(queryExecutor: ECSqlQueryExecutor, query: ECSqlQueryDef): AsyncIterableIterator<SelectableInstanceKey> {\n yield* genericExecuteQuery(queryExecutor, query, (row: ECSqlQueryRow) => ({\n className: row.ClassName,\n id: row.ECInstanceId,\n }));\n}\n"]}
|
|
@@ -95,6 +95,7 @@ export declare class IModelSelectionHandler {
|
|
|
95
95
|
private _imodelHiliteSetProvider;
|
|
96
96
|
private _activeScopeProvider;
|
|
97
97
|
private _isSuspended;
|
|
98
|
+
private _selectionStorageChangeTracker;
|
|
98
99
|
private _cancelOngoingChanges;
|
|
99
100
|
private _unregisterUnifiedSelectionListener;
|
|
100
101
|
private _unregisterIModelSelectionSetListener;
|
|
@@ -107,13 +108,11 @@ export declare class IModelSelectionHandler {
|
|
|
107
108
|
suspendIModelToolSelectionSync(): {
|
|
108
109
|
[Symbol.dispose]: () => void;
|
|
109
110
|
};
|
|
110
|
-
private
|
|
111
|
+
private syncHiliteSet;
|
|
111
112
|
private onUnifiedSelectionChanged;
|
|
112
113
|
private applyCurrentHiliteSet;
|
|
113
114
|
private addHiliteSet;
|
|
114
115
|
private removeHiliteSet;
|
|
115
116
|
private onIModelSelectionChanged;
|
|
116
|
-
private handleIModelSelectionChange;
|
|
117
|
-
private getSelectionSetChangeIds;
|
|
118
117
|
}
|
|
119
118
|
//# sourceMappingURL=EnableUnifiedSelectionSyncWithIModel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnableUnifiedSelectionSyncWithIModel.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/EnableUnifiedSelectionSyncWithIModel.ts"],"names":[],"mappings":"AAKA,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC3F,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAsC,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC/F,OAAO,EAAiC,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAGtG,OAAO,EAAoB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAA6E,MAAM,mBAAmB,CAAC;AAG3J;;;GAGG;AACH,MAAM,WAAW,yCAAyC;IACxD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,YAAY,EAAE,kBAAkB,GAC9B,yBAAyB,GAAG;QAC1B,sEAAsE;QACtE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,mFAAmF;QACnF,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;QACxC,yFAAyF;QACzF,QAAQ,CAAC,YAAY,EAAE,sBAAsB,CAAC;KAC/C,CAAC;IAEJ;;;OAGG;IACH,gBAAgB,EAAE,gBAAgB,CAAC;IAEnC,uCAAuC;IACvC,mBAAmB,EAAE,MAAM,cAAc,CAAC;IAE1C;;;;;;;OAOG;IACH,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAElD;;;;;;;;;;;;;;OAcG;IAEH,wBAAwB,CAAC,EAAE,wBAAwB,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,SAAS,CAAC,GAAG;QAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAC;CACtI;AAED;;;;GAIG;AACH,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,yCAAyC,GAAG,MAAM,IAAI,CAGjH;AAED;;;;;GAKG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,oBAAoB,CAAU;IAEtC,OAAO,CAAC,aAAa,CAA4D;IACjF,OAAO,CAAC,iBAAiB,CAAmB;IAC5C,OAAO,CAAC,wBAAwB,CAAoF;IACpH,OAAO,CAAC,oBAAoB,CAAuB;IAEnD,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,mCAAmC,CAAa;IACxD,OAAO,CAAC,qCAAqC,CAAa;IAC1D,OAAO,CAAC,iCAAiC,CAAa;gBAEnC,KAAK,EAAE,yCAAyC,GAAG;QAAE,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;KAAE;IA4CxG,CAAC,MAAM,CAAC,OAAO,CAAC;IAOvB,4GAA4G;IACrG,8BAA8B;;;IAUrC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"EnableUnifiedSelectionSyncWithIModel.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/EnableUnifiedSelectionSyncWithIModel.ts"],"names":[],"mappings":"AAKA,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC3F,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAsC,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC/F,OAAO,EAAiC,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAGtG,OAAO,EAAoB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAA6E,MAAM,mBAAmB,CAAC;AAG3J;;;GAGG;AACH,MAAM,WAAW,yCAAyC;IACxD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,YAAY,EAAE,kBAAkB,GAC9B,yBAAyB,GAAG;QAC1B,sEAAsE;QACtE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,mFAAmF;QACnF,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;QACxC,yFAAyF;QACzF,QAAQ,CAAC,YAAY,EAAE,sBAAsB,CAAC;KAC/C,CAAC;IAEJ;;;OAGG;IACH,gBAAgB,EAAE,gBAAgB,CAAC;IAEnC,uCAAuC;IACvC,mBAAmB,EAAE,MAAM,cAAc,CAAC;IAE1C;;;;;;;OAOG;IACH,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAElD;;;;;;;;;;;;;;OAcG;IAEH,wBAAwB,CAAC,EAAE,wBAAwB,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,SAAS,CAAC,GAAG;QAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAC;CACtI;AAED;;;;GAIG;AACH,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,yCAAyC,GAAG,MAAM,IAAI,CAGjH;AAED;;;;;GAKG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,oBAAoB,CAAU;IAEtC,OAAO,CAAC,aAAa,CAA4D;IACjF,OAAO,CAAC,iBAAiB,CAAmB;IAC5C,OAAO,CAAC,wBAAwB,CAAoF;IACpH,OAAO,CAAC,oBAAoB,CAAuB;IAEnD,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,8BAA8B,CAAK;IAC3C,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,mCAAmC,CAAa;IACxD,OAAO,CAAC,qCAAqC,CAAa;IAC1D,OAAO,CAAC,iCAAiC,CAAa;gBAEnC,KAAK,EAAE,yCAAyC,GAAG;QAAE,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;KAAE;IA4CxG,CAAC,MAAM,CAAC,OAAO,CAAC;IAOvB,4GAA4G;IACrG,8BAA8B;;;IAUrC,OAAO,CAAC,aAAa;IAuCrB,OAAO,CAAC,yBAAyB,CAa/B;IAEF,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,YAAY;IAwBpB,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,wBAAwB,CA+C9B;CACH"}
|
|
@@ -58,6 +58,7 @@ import "./DisposePolyfill.js";
|
|
|
58
58
|
import { EMPTY, firstValueFrom, from, map, merge, Subject, takeUntil, toArray } from "rxjs";
|
|
59
59
|
import { createHiliteSetProvider } from "./HiliteSetProvider.js";
|
|
60
60
|
import { createIModelHiliteSetProvider } from "./IModelHiliteSetProvider.js";
|
|
61
|
+
import { Selectables } from "./Selectable.js";
|
|
61
62
|
import { computeSelection } from "./SelectionScope.js";
|
|
62
63
|
import { CoreSelectionSetEventType } from "./types/IModel.js";
|
|
63
64
|
import { safeDispose } from "./Utils.js";
|
|
@@ -83,6 +84,7 @@ export class IModelSelectionHandler {
|
|
|
83
84
|
_imodelHiliteSetProvider;
|
|
84
85
|
_activeScopeProvider;
|
|
85
86
|
_isSuspended;
|
|
87
|
+
_selectionStorageChangeTracker = 0;
|
|
86
88
|
_cancelOngoingChanges = new Subject();
|
|
87
89
|
_unregisterUnifiedSelectionListener;
|
|
88
90
|
_unregisterIModelSelectionSetListener;
|
|
@@ -140,7 +142,8 @@ export class IModelSelectionHandler {
|
|
|
140
142
|
},
|
|
141
143
|
};
|
|
142
144
|
}
|
|
143
|
-
|
|
145
|
+
syncHiliteSet(props) {
|
|
146
|
+
const { changeType, selectables, source } = props;
|
|
144
147
|
switch (changeType) {
|
|
145
148
|
case "clear":
|
|
146
149
|
return this.applyCurrentHiliteSet({ activeSelectionAction: "clearAll" });
|
|
@@ -181,10 +184,12 @@ export class IModelSelectionHandler {
|
|
|
181
184
|
if (args.imodelKey !== this._imodelAccess.key || args.level !== 0) {
|
|
182
185
|
return;
|
|
183
186
|
}
|
|
187
|
+
// update the selection storage change tracker so we know the selection storage changed
|
|
188
|
+
this._selectionStorageChangeTracker = (this._selectionStorageChangeTracker + 1) % Number.MAX_SAFE_INTEGER;
|
|
184
189
|
if (args.changeType === "replace" || args.changeType === "clear") {
|
|
185
190
|
this._cancelOngoingChanges.next();
|
|
186
191
|
}
|
|
187
|
-
this.
|
|
192
|
+
this.syncHiliteSet(args);
|
|
188
193
|
};
|
|
189
194
|
applyCurrentHiliteSet({ activeSelectionAction }) {
|
|
190
195
|
if (activeSelectionAction !== "keep") {
|
|
@@ -289,37 +294,61 @@ export class IModelSelectionHandler {
|
|
|
289
294
|
this._selectionStorage.clearSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName });
|
|
290
295
|
return;
|
|
291
296
|
}
|
|
292
|
-
const ids =
|
|
297
|
+
const ids = getSelectionSetChangeIds(event);
|
|
293
298
|
const scopedSelection = merge(ids.elements
|
|
294
299
|
? from(computeSelection({ queryExecutor: this._imodelAccess, elementIds: ids.elements, scope: this._activeScopeProvider() }))
|
|
295
|
-
: /* c8 ignore next */ EMPTY, ids.models ? from(ids.models).pipe(map((id) => ({ className: "BisCore.Model", id }))) : /* c8 ignore next */ EMPTY, ids.subcategories
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
const
|
|
300
|
-
const props = {
|
|
300
|
+
: /* c8 ignore next */ EMPTY, ids.models ? from(ids.models).pipe(map((id) => ({ className: "BisCore.Model", id }))) : /* c8 ignore next */ EMPTY, ids.subcategories
|
|
301
|
+
? from(ids.subcategories).pipe(map((id) => ({ className: "BisCore.SubCategory", id })))
|
|
302
|
+
: /* c8 ignore next */ EMPTY);
|
|
303
|
+
const selectionStorageVersion = this._selectionStorageChangeTracker;
|
|
304
|
+
const changeSelectionStorageProps = {
|
|
301
305
|
imodelKey: this._imodelAccess.key,
|
|
302
306
|
source: this._selectionSourceName,
|
|
303
|
-
selectables,
|
|
307
|
+
selectables: await firstValueFrom(scopedSelection.pipe(toArray())),
|
|
304
308
|
};
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
309
|
+
try {
|
|
310
|
+
switch (event.type) {
|
|
311
|
+
case CoreSelectionSetEventType.Add:
|
|
312
|
+
return this._selectionStorage.addToSelection(changeSelectionStorageProps);
|
|
313
|
+
case CoreSelectionSetEventType.Remove:
|
|
314
|
+
return this._selectionStorage.removeFromSelection(changeSelectionStorageProps);
|
|
315
|
+
case CoreSelectionSetEventType.Replace:
|
|
316
|
+
return this._selectionStorage.replaceSelection(changeSelectionStorageProps);
|
|
317
|
+
}
|
|
312
318
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
319
|
+
finally {
|
|
320
|
+
if (this._selectionStorageChangeTracker === selectionStorageVersion) {
|
|
321
|
+
// if the storage wasn't changed while we were processing the selection change, we have to re-sync the
|
|
322
|
+
// hilite set (otherwise it's done by the selection storage change handler)
|
|
323
|
+
this.syncHiliteSet({
|
|
324
|
+
...changeSelectionStorageProps,
|
|
325
|
+
selectables: Selectables.create(changeSelectionStorageProps.selectables),
|
|
326
|
+
changeType: getUnifiedSelectionChangeType(event.type),
|
|
327
|
+
});
|
|
328
|
+
}
|
|
322
329
|
}
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
function getSelectionSetChangeIds(event) {
|
|
333
|
+
switch (event.type) {
|
|
334
|
+
case CoreSelectionSetEventType.Add:
|
|
335
|
+
return event.additions ?? (event.added ? { elements: event.added } : /* c8 ignore next */ {});
|
|
336
|
+
case CoreSelectionSetEventType.Remove:
|
|
337
|
+
return event.removals ?? (event.removed ? { elements: event.removed } : /* c8 ignore next */ {});
|
|
338
|
+
case CoreSelectionSetEventType.Replace:
|
|
339
|
+
return "active" in event.set ? event.set.active : { elements: event.set.elements };
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
function getUnifiedSelectionChangeType(coreChangeType) {
|
|
343
|
+
switch (coreChangeType) {
|
|
344
|
+
case CoreSelectionSetEventType.Add:
|
|
345
|
+
return "add";
|
|
346
|
+
case CoreSelectionSetEventType.Remove:
|
|
347
|
+
return "remove";
|
|
348
|
+
case CoreSelectionSetEventType.Replace:
|
|
349
|
+
return "replace";
|
|
350
|
+
case CoreSelectionSetEventType.Clear:
|
|
351
|
+
return "clear";
|
|
323
352
|
}
|
|
324
353
|
}
|
|
325
354
|
function is5xSelectionSet(selectionSet) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnableUnifiedSelectionSyncWithIModel.js","sourceRoot":"","sources":["../../../src/unified-selection/EnableUnifiedSelectionSyncWithIModel.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./DisposePolyfill.js\";\nimport { EMPTY, firstValueFrom, from, map, merge, Observable, Subject, takeUntil, toArray } from \"rxjs\";\nimport { Id64Arg, Id64Set } from \"@itwin/core-bentley\";\nimport { ECClassHierarchyInspector, ECSqlQueryExecutor } from \"@itwin/presentation-shared\";\nimport { CachingHiliteSetProvider } from \"./CachingHiliteSetProvider.js\";\nimport { createHiliteSetProvider, HiliteSet, HiliteSetProvider } from \"./HiliteSetProvider.js\";\nimport { createIModelHiliteSetProvider, IModelHiliteSetProvider } from \"./IModelHiliteSetProvider.js\";\nimport { SelectableInstanceKey, Selectables } from \"./Selectable.js\";\nimport { StorageSelectionChangeEventArgs, StorageSelectionChangeType } from \"./SelectionChangeEvent.js\";\nimport { computeSelection, SelectionScope } from \"./SelectionScope.js\";\nimport { SelectionStorage } from \"./SelectionStorage.js\";\nimport { CoreIModelHiliteSet, CoreIModelSelectionSet, CoreSelectableIds, CoreSelectionSetEventType, CoreSelectionSetEventUnsafe } from \"./types/IModel.js\";\nimport { safeDispose } from \"./Utils.js\";\n\n/**\n * Props for `enableUnifiedSelectionSyncWithIModel`.\n * @public\n */\nexport interface EnableUnifiedSelectionSyncWithIModelProps {\n /**\n * Provides access to different iModel's features: query executing, class hierarchy, selection and hilite sets.\n *\n * It's recommended to use `@itwin/presentation-core-interop` to create `key`, `ECSqlQueryExecutor` and `ECSchemaProvider` from\n * [IModelConnection](https://www.itwinjs.org/reference/core-frontend/imodelconnection/imodelconnection/), and map its\n * `hilited` and `selectionSet` attributes like this:\n *\n * ```ts\n * import { createECSqlQueryExecutor, createECSchemaProvider, createIModelKey } from \"@itwin/presentation-core-interop\";\n * import { createCachingECClassHierarchyInspector } from \"@itwin/presentation-shared\";\n * import { IModelConnection } from \"@itwin/core-frontend\";\n *\n * const imodel: IModelConnection = ...\n * const imodelAccess = {\n * ...createECSqlQueryExecutor(imodel),\n * ...createCachingECClassHierarchyInspector({ schemaProvider: createECSchemaProvider(MyAppFrontend.getSchemaContext(imodel)) }),\n * key: createIModelKey(imodel),\n * hiliteSet: imodel.hilited,\n * selectionSet: imodel.selectionSet,\n * };\n * ```\n */\n imodelAccess: ECSqlQueryExecutor &\n ECClassHierarchyInspector & {\n /** Key of the iModel. Generally taken from `IModelConnection.key`. */\n readonly key: string;\n /** The set of currently hilited elements taken from `IModelConnection.hilited`. */\n readonly hiliteSet: CoreIModelHiliteSet;\n /** The set of currently selected elements taken from `IModelConnection.selectionSet`. */\n readonly selectionSet: CoreIModelSelectionSet;\n };\n\n /**\n * Unified selection storage to synchronize IModel's tool selection with. The storage should be shared\n * across all components in the application to ensure unified selection experience.\n */\n selectionStorage: SelectionStorage;\n\n /** Active selection scope provider. */\n activeScopeProvider: () => SelectionScope;\n\n /**\n * An iModel hilite set provider used to retrieve hilite sets for different iModels. If not provided, a new `IModelHiliteSetProvider`\n * will be created for the given iModel using the provided `imodelAccess`.\n * If the consuming application already has a `IModelHiliteSetProvider` defined, it should be provided instead\n * to reuse the cache and avoid creating new providers for each iModel.\n *\n * @see `createIModelHiliteSetProvider`\n */\n imodelHiliteSetProvider?: IModelHiliteSetProvider;\n\n /**\n * A caching hilite set provider used to retrieve hilite sets for an iModel. If not provided, a new `CachingHiliteSetProvider`\n * will be created for the given iModel using the provided `imodelAccess`.\n * If the consuming application already has a `CachingHiliteSetProvider` defined, it should be provided instead\n * to reuse the cache and avoid creating new providers for each iModel.\n *\n * The type is defined in a way that makes it required for provider to have either the deprecated `dispose` or the\n * new `Symbol.dispose` method.\n *\n * **Warning:** When the given `CachingHiliteSetProvider` internally uses a custom `HiliteSetProvider`, the synchronization has\n * no access to it, and thus uses its own, default, `HiliteSetProvider`. As a result, the synchronization may not work as expected.\n * To alleviate this, the `imodelHiliteSetProvider` prop should be used instead.\n *\n * @deprecated in 1.5. Use `imodelHiliteSetProvider` prop instead.\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n cachingHiliteSetProvider?: CachingHiliteSetProvider | (Omit<CachingHiliteSetProvider, \"dispose\"> & { [Symbol.dispose]: () => void });\n}\n\n/**\n * Enables synchronization between iModel selection and unified selection.\n * @returns function for disposing the synchronization.\n * @public\n */\nexport function enableUnifiedSelectionSyncWithIModel(props: EnableUnifiedSelectionSyncWithIModelProps): () => void {\n const selectionHandler = new IModelSelectionHandler(props);\n return () => selectionHandler[Symbol.dispose]();\n}\n\n/**\n * A handler that syncs selection between unified selection storage (`SelectionStorage`) and\n * an iModel (`iModel.selectionSet`, `iModel.hilited`).\n *\n * @internal\n */\nexport class IModelSelectionHandler {\n private _selectionSourceName = \"Tool\";\n\n private _imodelAccess: EnableUnifiedSelectionSyncWithIModelProps[\"imodelAccess\"];\n private _selectionStorage: SelectionStorage;\n private _imodelHiliteSetProvider: NonNullable<EnableUnifiedSelectionSyncWithIModelProps[\"imodelHiliteSetProvider\"]>;\n private _activeScopeProvider: () => SelectionScope;\n\n private _isSuspended: boolean;\n private _cancelOngoingChanges = new Subject<void>();\n private _unregisterUnifiedSelectionListener: () => void;\n private _unregisterIModelSelectionSetListener: () => void;\n private _disposeInternalHiliteSetProvider: () => void;\n\n public constructor(props: EnableUnifiedSelectionSyncWithIModelProps & { hiliteSetProvider?: HiliteSetProvider }) {\n this._imodelAccess = props.imodelAccess;\n this._selectionStorage = props.selectionStorage;\n this._activeScopeProvider = props.activeScopeProvider;\n this._isSuspended = false;\n\n [this._imodelHiliteSetProvider, this._disposeInternalHiliteSetProvider] = (() => {\n if (props.imodelHiliteSetProvider) {\n return [props.imodelHiliteSetProvider, () => {}];\n }\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n if (props.cachingHiliteSetProvider) {\n return [\n createIModelHiliteSetProviderFromCachingProvider(\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n props.cachingHiliteSetProvider,\n props.hiliteSetProvider ?? createHiliteSetProvider({ imodelAccess: props.imodelAccess }),\n ),\n // don't need to dispose anything, because our wrapper has no dispose logic, and `cachingHiliteSetProvider` should be disposed\n // by whoever owns it\n () => {},\n ];\n }\n /* c8 ignore start */\n const internalProvider = createIModelHiliteSetProvider({\n selectionStorage: this._selectionStorage,\n imodelProvider: () => this._imodelAccess,\n createHiliteSetProvider: () => props.hiliteSetProvider ?? createHiliteSetProvider({ imodelAccess: props.imodelAccess }),\n });\n return [internalProvider, () => safeDispose(internalProvider)];\n /* c8 ignore end */\n })();\n\n this._unregisterIModelSelectionSetListener = this._imodelAccess.selectionSet.onChanged.addListener(this.onIModelSelectionChanged);\n this._unregisterUnifiedSelectionListener = this._selectionStorage.selectionChangeEvent.addListener(this.onUnifiedSelectionChanged);\n\n if (!is5xSelectionSet(this._imodelAccess.selectionSet)) {\n // itwinjs-core@4: stop imodel from syncing tool selection with hilited list - we want to manage that sync ourselves\n this._imodelAccess.hiliteSet.wantSyncWithSelectionSet = false;\n }\n\n this.applyCurrentHiliteSet({ activeSelectionAction: \"clearAll\" });\n }\n\n public [Symbol.dispose]() {\n this._cancelOngoingChanges.next();\n this._unregisterIModelSelectionSetListener();\n this._unregisterUnifiedSelectionListener();\n this._disposeInternalHiliteSetProvider();\n }\n\n /** Temporarily suspends tool selection synchronization until the returned disposable object is disposed. */\n public suspendIModelToolSelectionSync() {\n const wasSuspended = this._isSuspended;\n this._isSuspended = true;\n return {\n [Symbol.dispose]: () => {\n this._isSuspended = wasSuspended;\n },\n };\n }\n\n private handleUnifiedSelectionChange(changeType: StorageSelectionChangeType, selectables: Selectables, source: string): void {\n switch (changeType) {\n case \"clear\":\n return this.applyCurrentHiliteSet({ activeSelectionAction: \"clearAll\" });\n case \"replace\":\n return this.applyCurrentHiliteSet({\n activeSelectionAction:\n source === this._selectionSourceName\n ? is5xSelectionSet(this._imodelAccess.selectionSet)\n ? // with 5x core we don't need to clear anything when event is triggered by a Tool (hilite and selection sets are in sync already)\n \"keep\"\n : // with 4x core we need to clear hilite set, because it's not synced with selection set\n \"clearHilited\"\n : // when event is triggered not by a Tool, we need to clear everything\n \"clearAll\",\n });\n case \"add\":\n return void from(this._imodelHiliteSetProvider.getHiliteSetProvider({ imodelKey: this._imodelAccess.key }).getHiliteSet({ selectables }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (set) => {\n this.addHiliteSet(set);\n },\n });\n case \"remove\":\n return void from(this._imodelHiliteSetProvider.getHiliteSetProvider({ imodelKey: this._imodelAccess.key }).getHiliteSet({ selectables }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (set) => {\n this.removeHiliteSet(set);\n },\n complete: () => {\n this.applyCurrentHiliteSet({ activeSelectionAction: \"keep\" });\n },\n });\n }\n }\n\n private onUnifiedSelectionChanged = (args: StorageSelectionChangeEventArgs) => {\n // iModels are only interested in top-level selection changes\n if (args.imodelKey !== this._imodelAccess.key || args.level !== 0) {\n return;\n }\n\n if (args.changeType === \"replace\" || args.changeType === \"clear\") {\n this._cancelOngoingChanges.next();\n }\n this.handleUnifiedSelectionChange(args.changeType, args.selectables, args.source);\n };\n\n private applyCurrentHiliteSet({ activeSelectionAction }: { activeSelectionAction: \"clearAll\" | \"clearHilited\" | \"keep\" }) {\n if (activeSelectionAction !== \"keep\") {\n using _dispose = this.suspendIModelToolSelectionSync();\n if (!is5xSelectionSet(this._imodelAccess.selectionSet)) {\n this._imodelAccess.hiliteSet.clear();\n }\n if (activeSelectionAction === \"clearAll\") {\n this._imodelAccess.selectionSet.emptyAll();\n }\n }\n\n from(this._imodelHiliteSetProvider.getCurrentHiliteSet({ imodelKey: this._imodelAccess.key }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (ids) => {\n this.addHiliteSet(ids);\n },\n });\n }\n\n private addHiliteSet(set: HiliteSet) {\n using _dispose = this.suspendIModelToolSelectionSync();\n if (is5xSelectionSet(this._imodelAccess.selectionSet)) {\n // with 5.x core we can simply add the set as a whole\n this._imodelAccess.selectionSet.add({\n models: set.models,\n subcategories: set.subCategories,\n elements: set.elements,\n });\n } else {\n // pre-5.0 core requires adding models and subcategories to hilite set separately\n if (set.models.length) {\n this._imodelAccess.hiliteSet.models.addIds(set.models);\n }\n if (set.subCategories.length) {\n this._imodelAccess.hiliteSet.subcategories.addIds(set.subCategories);\n }\n if (set.elements.length) {\n this._imodelAccess.hiliteSet.elements.addIds(set.elements);\n this._imodelAccess.selectionSet.add(set.elements);\n }\n }\n }\n\n private removeHiliteSet(set: HiliteSet) {\n using _dispose = this.suspendIModelToolSelectionSync();\n if (is5xSelectionSet(this._imodelAccess.selectionSet)) {\n // with 5.x core we can simply remove the set as a whole\n this._imodelAccess.selectionSet.remove({\n models: set.models,\n subcategories: set.subCategories,\n elements: set.elements,\n });\n } else {\n if (set.models.length) {\n this._imodelAccess.hiliteSet.models.deleteIds(set.models);\n }\n if (set.subCategories.length) {\n this._imodelAccess.hiliteSet.subcategories.deleteIds(set.subCategories);\n }\n if (set.elements.length) {\n this._imodelAccess.hiliteSet.elements.deleteIds(set.elements);\n this._imodelAccess.selectionSet.remove(set.elements);\n }\n }\n }\n\n private onIModelSelectionChanged = async (event: CoreSelectionSetEventUnsafe): Promise<void> => {\n if (this._isSuspended) {\n return;\n }\n\n if (CoreSelectionSetEventType.Clear === event.type) {\n this._selectionStorage.clearSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName });\n return;\n }\n\n const ids = this.getSelectionSetChangeIds(event);\n const scopedSelection = merge(\n ids.elements\n ? from(computeSelection({ queryExecutor: this._imodelAccess, elementIds: ids.elements, scope: this._activeScopeProvider() }))\n : /* c8 ignore next */ EMPTY,\n ids.models ? from(ids.models).pipe(map((id) => ({ className: \"BisCore.Model\", id }))) : /* c8 ignore next */ EMPTY,\n ids.subcategories ? from(ids.subcategories).pipe(map((id) => ({ className: \"BisCore.SubCategory\", id }))) : /* c8 ignore next */ EMPTY,\n );\n await this.handleIModelSelectionChange(event.type, scopedSelection);\n };\n\n private async handleIModelSelectionChange(type: CoreSelectionSetEventType, keys: Observable<SelectableInstanceKey>) {\n const selectables = await firstValueFrom(keys.pipe(toArray()));\n const props = {\n imodelKey: this._imodelAccess.key,\n source: this._selectionSourceName,\n selectables,\n };\n switch (type) {\n case CoreSelectionSetEventType.Add:\n return this._selectionStorage.addToSelection(props);\n case CoreSelectionSetEventType.Remove:\n return this._selectionStorage.removeFromSelection(props);\n case CoreSelectionSetEventType.Replace:\n return this._selectionStorage.replaceSelection(props);\n }\n }\n\n private getSelectionSetChangeIds(\n event: Omit<CoreSelectionSetEventUnsafe, \"type\"> & {\n type: CoreSelectionSetEventType.Add | CoreSelectionSetEventType.Remove | CoreSelectionSetEventType.Replace;\n },\n ): CoreSelectableIds {\n switch (event.type) {\n case CoreSelectionSetEventType.Add:\n return event.additions ?? (event.added ? { elements: event.added } : /* c8 ignore next */ {});\n case CoreSelectionSetEventType.Remove:\n return event.removals ?? (event.removed ? { elements: event.removed } : /* c8 ignore next */ {});\n case CoreSelectionSetEventType.Replace:\n return \"active\" in event.set ? event.set.active : { elements: event.set.elements };\n }\n }\n}\n\nfunction is5xSelectionSet(selectionSet: CoreIModelSelectionSet): selectionSet is Omit<CoreIModelSelectionSet, \"add\" | \"remove\"> & {\n readonly active: { [P in keyof CoreSelectableIds]-?: Id64Set };\n add: (ids: Id64Arg | CoreSelectableIds) => boolean;\n remove: (ids: Id64Arg | CoreSelectableIds) => boolean;\n} {\n return \"active\" in selectionSet;\n}\n\n/* c8 ignore start */\nfunction createIModelHiliteSetProviderFromCachingProvider(\n cachingHiliteSetProvider: NonNullable<EnableUnifiedSelectionSyncWithIModelProps[\"cachingHiliteSetProvider\"]>,\n hiliteSetProvider: HiliteSetProvider,\n): IModelHiliteSetProvider {\n return {\n getHiliteSetProvider: () => hiliteSetProvider,\n getCurrentHiliteSet: (props) => cachingHiliteSetProvider.getHiliteSet(props),\n [Symbol.dispose]: () => {},\n };\n}\n/* c8 ignore end */\n"]}
|
|
1
|
+
{"version":3,"file":"EnableUnifiedSelectionSyncWithIModel.js","sourceRoot":"","sources":["../../../src/unified-selection/EnableUnifiedSelectionSyncWithIModel.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./DisposePolyfill.js\";\nimport { EMPTY, firstValueFrom, from, map, merge, Subject, takeUntil, toArray } from \"rxjs\";\nimport { Id64Arg, Id64Set } from \"@itwin/core-bentley\";\nimport { ECClassHierarchyInspector, ECSqlQueryExecutor } from \"@itwin/presentation-shared\";\nimport { CachingHiliteSetProvider } from \"./CachingHiliteSetProvider.js\";\nimport { createHiliteSetProvider, HiliteSet, HiliteSetProvider } from \"./HiliteSetProvider.js\";\nimport { createIModelHiliteSetProvider, IModelHiliteSetProvider } from \"./IModelHiliteSetProvider.js\";\nimport { SelectableInstanceKey, Selectables } from \"./Selectable.js\";\nimport { StorageSelectionChangeEventArgs, StorageSelectionChangeType } from \"./SelectionChangeEvent.js\";\nimport { computeSelection, SelectionScope } from \"./SelectionScope.js\";\nimport { SelectionStorage } from \"./SelectionStorage.js\";\nimport { CoreIModelHiliteSet, CoreIModelSelectionSet, CoreSelectableIds, CoreSelectionSetEventType, CoreSelectionSetEventUnsafe } from \"./types/IModel.js\";\nimport { safeDispose } from \"./Utils.js\";\n\n/**\n * Props for `enableUnifiedSelectionSyncWithIModel`.\n * @public\n */\nexport interface EnableUnifiedSelectionSyncWithIModelProps {\n /**\n * Provides access to different iModel's features: query executing, class hierarchy, selection and hilite sets.\n *\n * It's recommended to use `@itwin/presentation-core-interop` to create `key`, `ECSqlQueryExecutor` and `ECSchemaProvider` from\n * [IModelConnection](https://www.itwinjs.org/reference/core-frontend/imodelconnection/imodelconnection/), and map its\n * `hilited` and `selectionSet` attributes like this:\n *\n * ```ts\n * import { createECSqlQueryExecutor, createECSchemaProvider, createIModelKey } from \"@itwin/presentation-core-interop\";\n * import { createCachingECClassHierarchyInspector } from \"@itwin/presentation-shared\";\n * import { IModelConnection } from \"@itwin/core-frontend\";\n *\n * const imodel: IModelConnection = ...\n * const imodelAccess = {\n * ...createECSqlQueryExecutor(imodel),\n * ...createCachingECClassHierarchyInspector({ schemaProvider: createECSchemaProvider(MyAppFrontend.getSchemaContext(imodel)) }),\n * key: createIModelKey(imodel),\n * hiliteSet: imodel.hilited,\n * selectionSet: imodel.selectionSet,\n * };\n * ```\n */\n imodelAccess: ECSqlQueryExecutor &\n ECClassHierarchyInspector & {\n /** Key of the iModel. Generally taken from `IModelConnection.key`. */\n readonly key: string;\n /** The set of currently hilited elements taken from `IModelConnection.hilited`. */\n readonly hiliteSet: CoreIModelHiliteSet;\n /** The set of currently selected elements taken from `IModelConnection.selectionSet`. */\n readonly selectionSet: CoreIModelSelectionSet;\n };\n\n /**\n * Unified selection storage to synchronize IModel's tool selection with. The storage should be shared\n * across all components in the application to ensure unified selection experience.\n */\n selectionStorage: SelectionStorage;\n\n /** Active selection scope provider. */\n activeScopeProvider: () => SelectionScope;\n\n /**\n * An iModel hilite set provider used to retrieve hilite sets for different iModels. If not provided, a new `IModelHiliteSetProvider`\n * will be created for the given iModel using the provided `imodelAccess`.\n * If the consuming application already has a `IModelHiliteSetProvider` defined, it should be provided instead\n * to reuse the cache and avoid creating new providers for each iModel.\n *\n * @see `createIModelHiliteSetProvider`\n */\n imodelHiliteSetProvider?: IModelHiliteSetProvider;\n\n /**\n * A caching hilite set provider used to retrieve hilite sets for an iModel. If not provided, a new `CachingHiliteSetProvider`\n * will be created for the given iModel using the provided `imodelAccess`.\n * If the consuming application already has a `CachingHiliteSetProvider` defined, it should be provided instead\n * to reuse the cache and avoid creating new providers for each iModel.\n *\n * The type is defined in a way that makes it required for provider to have either the deprecated `dispose` or the\n * new `Symbol.dispose` method.\n *\n * **Warning:** When the given `CachingHiliteSetProvider` internally uses a custom `HiliteSetProvider`, the synchronization has\n * no access to it, and thus uses its own, default, `HiliteSetProvider`. As a result, the synchronization may not work as expected.\n * To alleviate this, the `imodelHiliteSetProvider` prop should be used instead.\n *\n * @deprecated in 1.5. Use `imodelHiliteSetProvider` prop instead.\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n cachingHiliteSetProvider?: CachingHiliteSetProvider | (Omit<CachingHiliteSetProvider, \"dispose\"> & { [Symbol.dispose]: () => void });\n}\n\n/**\n * Enables synchronization between iModel selection and unified selection.\n * @returns function for disposing the synchronization.\n * @public\n */\nexport function enableUnifiedSelectionSyncWithIModel(props: EnableUnifiedSelectionSyncWithIModelProps): () => void {\n const selectionHandler = new IModelSelectionHandler(props);\n return () => selectionHandler[Symbol.dispose]();\n}\n\n/**\n * A handler that syncs selection between unified selection storage (`SelectionStorage`) and\n * an iModel (`iModel.selectionSet`, `iModel.hilited`).\n *\n * @internal\n */\nexport class IModelSelectionHandler {\n private _selectionSourceName = \"Tool\";\n\n private _imodelAccess: EnableUnifiedSelectionSyncWithIModelProps[\"imodelAccess\"];\n private _selectionStorage: SelectionStorage;\n private _imodelHiliteSetProvider: NonNullable<EnableUnifiedSelectionSyncWithIModelProps[\"imodelHiliteSetProvider\"]>;\n private _activeScopeProvider: () => SelectionScope;\n\n private _isSuspended: boolean;\n private _selectionStorageChangeTracker = 0;\n private _cancelOngoingChanges = new Subject<void>();\n private _unregisterUnifiedSelectionListener: () => void;\n private _unregisterIModelSelectionSetListener: () => void;\n private _disposeInternalHiliteSetProvider: () => void;\n\n public constructor(props: EnableUnifiedSelectionSyncWithIModelProps & { hiliteSetProvider?: HiliteSetProvider }) {\n this._imodelAccess = props.imodelAccess;\n this._selectionStorage = props.selectionStorage;\n this._activeScopeProvider = props.activeScopeProvider;\n this._isSuspended = false;\n\n [this._imodelHiliteSetProvider, this._disposeInternalHiliteSetProvider] = (() => {\n if (props.imodelHiliteSetProvider) {\n return [props.imodelHiliteSetProvider, () => {}];\n }\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n if (props.cachingHiliteSetProvider) {\n return [\n createIModelHiliteSetProviderFromCachingProvider(\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n props.cachingHiliteSetProvider,\n props.hiliteSetProvider ?? createHiliteSetProvider({ imodelAccess: props.imodelAccess }),\n ),\n // don't need to dispose anything, because our wrapper has no dispose logic, and `cachingHiliteSetProvider` should be disposed\n // by whoever owns it\n () => {},\n ];\n }\n /* c8 ignore start */\n const internalProvider = createIModelHiliteSetProvider({\n selectionStorage: this._selectionStorage,\n imodelProvider: () => this._imodelAccess,\n createHiliteSetProvider: () => props.hiliteSetProvider ?? createHiliteSetProvider({ imodelAccess: props.imodelAccess }),\n });\n return [internalProvider, () => safeDispose(internalProvider)];\n /* c8 ignore end */\n })();\n\n this._unregisterIModelSelectionSetListener = this._imodelAccess.selectionSet.onChanged.addListener(this.onIModelSelectionChanged);\n this._unregisterUnifiedSelectionListener = this._selectionStorage.selectionChangeEvent.addListener(this.onUnifiedSelectionChanged);\n\n if (!is5xSelectionSet(this._imodelAccess.selectionSet)) {\n // itwinjs-core@4: stop imodel from syncing tool selection with hilited list - we want to manage that sync ourselves\n this._imodelAccess.hiliteSet.wantSyncWithSelectionSet = false;\n }\n\n this.applyCurrentHiliteSet({ activeSelectionAction: \"clearAll\" });\n }\n\n public [Symbol.dispose]() {\n this._cancelOngoingChanges.next();\n this._unregisterIModelSelectionSetListener();\n this._unregisterUnifiedSelectionListener();\n this._disposeInternalHiliteSetProvider();\n }\n\n /** Temporarily suspends tool selection synchronization until the returned disposable object is disposed. */\n public suspendIModelToolSelectionSync() {\n const wasSuspended = this._isSuspended;\n this._isSuspended = true;\n return {\n [Symbol.dispose]: () => {\n this._isSuspended = wasSuspended;\n },\n };\n }\n\n private syncHiliteSet(props: { changeType: StorageSelectionChangeType; selectables: Selectables; source: string }): void {\n const { changeType, selectables, source } = props;\n switch (changeType) {\n case \"clear\":\n return this.applyCurrentHiliteSet({ activeSelectionAction: \"clearAll\" });\n case \"replace\":\n return this.applyCurrentHiliteSet({\n activeSelectionAction:\n source === this._selectionSourceName\n ? is5xSelectionSet(this._imodelAccess.selectionSet)\n ? // with 5x core we don't need to clear anything when event is triggered by a Tool (hilite and selection sets are in sync already)\n \"keep\"\n : // with 4x core we need to clear hilite set, because it's not synced with selection set\n \"clearHilited\"\n : // when event is triggered not by a Tool, we need to clear everything\n \"clearAll\",\n });\n case \"add\":\n return void from(this._imodelHiliteSetProvider.getHiliteSetProvider({ imodelKey: this._imodelAccess.key }).getHiliteSet({ selectables }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (set) => {\n this.addHiliteSet(set);\n },\n });\n case \"remove\":\n return void from(this._imodelHiliteSetProvider.getHiliteSetProvider({ imodelKey: this._imodelAccess.key }).getHiliteSet({ selectables }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (set) => {\n this.removeHiliteSet(set);\n },\n complete: () => {\n this.applyCurrentHiliteSet({ activeSelectionAction: \"keep\" });\n },\n });\n }\n }\n\n private onUnifiedSelectionChanged = (args: StorageSelectionChangeEventArgs) => {\n // iModels are only interested in top-level selection changes\n if (args.imodelKey !== this._imodelAccess.key || args.level !== 0) {\n return;\n }\n\n // update the selection storage change tracker so we know the selection storage changed\n this._selectionStorageChangeTracker = (this._selectionStorageChangeTracker + 1) % Number.MAX_SAFE_INTEGER;\n\n if (args.changeType === \"replace\" || args.changeType === \"clear\") {\n this._cancelOngoingChanges.next();\n }\n this.syncHiliteSet(args);\n };\n\n private applyCurrentHiliteSet({ activeSelectionAction }: { activeSelectionAction: \"clearAll\" | \"clearHilited\" | \"keep\" }) {\n if (activeSelectionAction !== \"keep\") {\n using _dispose = this.suspendIModelToolSelectionSync();\n if (!is5xSelectionSet(this._imodelAccess.selectionSet)) {\n this._imodelAccess.hiliteSet.clear();\n }\n if (activeSelectionAction === \"clearAll\") {\n this._imodelAccess.selectionSet.emptyAll();\n }\n }\n\n from(this._imodelHiliteSetProvider.getCurrentHiliteSet({ imodelKey: this._imodelAccess.key }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (ids) => {\n this.addHiliteSet(ids);\n },\n });\n }\n\n private addHiliteSet(set: HiliteSet) {\n using _dispose = this.suspendIModelToolSelectionSync();\n if (is5xSelectionSet(this._imodelAccess.selectionSet)) {\n // with 5.x core we can simply add the set as a whole\n this._imodelAccess.selectionSet.add({\n models: set.models,\n subcategories: set.subCategories,\n elements: set.elements,\n });\n } else {\n // pre-5.0 core requires adding models and subcategories to hilite set separately\n if (set.models.length) {\n this._imodelAccess.hiliteSet.models.addIds(set.models);\n }\n if (set.subCategories.length) {\n this._imodelAccess.hiliteSet.subcategories.addIds(set.subCategories);\n }\n if (set.elements.length) {\n this._imodelAccess.hiliteSet.elements.addIds(set.elements);\n this._imodelAccess.selectionSet.add(set.elements);\n }\n }\n }\n\n private removeHiliteSet(set: HiliteSet) {\n using _dispose = this.suspendIModelToolSelectionSync();\n if (is5xSelectionSet(this._imodelAccess.selectionSet)) {\n // with 5.x core we can simply remove the set as a whole\n this._imodelAccess.selectionSet.remove({\n models: set.models,\n subcategories: set.subCategories,\n elements: set.elements,\n });\n } else {\n if (set.models.length) {\n this._imodelAccess.hiliteSet.models.deleteIds(set.models);\n }\n if (set.subCategories.length) {\n this._imodelAccess.hiliteSet.subcategories.deleteIds(set.subCategories);\n }\n if (set.elements.length) {\n this._imodelAccess.hiliteSet.elements.deleteIds(set.elements);\n this._imodelAccess.selectionSet.remove(set.elements);\n }\n }\n }\n\n private onIModelSelectionChanged = async (event: CoreSelectionSetEventUnsafe): Promise<void> => {\n if (this._isSuspended) {\n return;\n }\n\n if (CoreSelectionSetEventType.Clear === event.type) {\n this._selectionStorage.clearSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName });\n return;\n }\n\n const ids = getSelectionSetChangeIds(event);\n const scopedSelection = merge(\n ids.elements\n ? from(computeSelection({ queryExecutor: this._imodelAccess, elementIds: ids.elements, scope: this._activeScopeProvider() }))\n : /* c8 ignore next */ EMPTY,\n ids.models ? from(ids.models).pipe(map((id): SelectableInstanceKey => ({ className: \"BisCore.Model\", id }))) : /* c8 ignore next */ EMPTY,\n ids.subcategories\n ? from(ids.subcategories).pipe(map((id): SelectableInstanceKey => ({ className: \"BisCore.SubCategory\", id })))\n : /* c8 ignore next */ EMPTY,\n );\n\n const selectionStorageVersion = this._selectionStorageChangeTracker;\n const changeSelectionStorageProps = {\n imodelKey: this._imodelAccess.key,\n source: this._selectionSourceName,\n selectables: await firstValueFrom(scopedSelection.pipe(toArray())),\n };\n try {\n switch (event.type) {\n case CoreSelectionSetEventType.Add:\n return this._selectionStorage.addToSelection(changeSelectionStorageProps);\n case CoreSelectionSetEventType.Remove:\n return this._selectionStorage.removeFromSelection(changeSelectionStorageProps);\n case CoreSelectionSetEventType.Replace:\n return this._selectionStorage.replaceSelection(changeSelectionStorageProps);\n }\n } finally {\n if (this._selectionStorageChangeTracker === selectionStorageVersion) {\n // if the storage wasn't changed while we were processing the selection change, we have to re-sync the\n // hilite set (otherwise it's done by the selection storage change handler)\n this.syncHiliteSet({\n ...changeSelectionStorageProps,\n selectables: Selectables.create(changeSelectionStorageProps.selectables),\n changeType: getUnifiedSelectionChangeType(event.type),\n });\n }\n }\n };\n}\n\nfunction getSelectionSetChangeIds(\n event: Omit<CoreSelectionSetEventUnsafe, \"type\"> & {\n type: CoreSelectionSetEventType.Add | CoreSelectionSetEventType.Remove | CoreSelectionSetEventType.Replace;\n },\n): CoreSelectableIds {\n switch (event.type) {\n case CoreSelectionSetEventType.Add:\n return event.additions ?? (event.added ? { elements: event.added } : /* c8 ignore next */ {});\n case CoreSelectionSetEventType.Remove:\n return event.removals ?? (event.removed ? { elements: event.removed } : /* c8 ignore next */ {});\n case CoreSelectionSetEventType.Replace:\n return \"active\" in event.set ? event.set.active : { elements: event.set.elements };\n }\n}\n\nfunction getUnifiedSelectionChangeType(coreChangeType: CoreSelectionSetEventType): StorageSelectionChangeType {\n switch (coreChangeType) {\n case CoreSelectionSetEventType.Add:\n return \"add\";\n case CoreSelectionSetEventType.Remove:\n return \"remove\";\n case CoreSelectionSetEventType.Replace:\n return \"replace\";\n case CoreSelectionSetEventType.Clear:\n return \"clear\";\n }\n}\n\nfunction is5xSelectionSet(selectionSet: CoreIModelSelectionSet): selectionSet is Omit<CoreIModelSelectionSet, \"add\" | \"remove\"> & {\n readonly active: { [P in keyof CoreSelectableIds]-?: Id64Set };\n add: (ids: Id64Arg | CoreSelectableIds) => boolean;\n remove: (ids: Id64Arg | CoreSelectableIds) => boolean;\n} {\n return \"active\" in selectionSet;\n}\n\n/* c8 ignore start */\nfunction createIModelHiliteSetProviderFromCachingProvider(\n cachingHiliteSetProvider: NonNullable<EnableUnifiedSelectionSyncWithIModelProps[\"cachingHiliteSetProvider\"]>,\n hiliteSetProvider: HiliteSetProvider,\n): IModelHiliteSetProvider {\n return {\n getHiliteSetProvider: () => hiliteSetProvider,\n getCurrentHiliteSet: (props) => cachingHiliteSetProvider.getHiliteSet(props),\n [Symbol.dispose]: () => {},\n };\n}\n/* c8 ignore end */\n"]}
|
|
@@ -49,9 +49,9 @@ export var Selectables;
|
|
|
49
49
|
* @public
|
|
50
50
|
*/
|
|
51
51
|
function size(selectables) {
|
|
52
|
-
let
|
|
53
|
-
selectables.instanceKeys.forEach((set) => (
|
|
54
|
-
return
|
|
52
|
+
let instanceCount = 0;
|
|
53
|
+
selectables.instanceKeys.forEach((set) => (instanceCount += set.size));
|
|
54
|
+
return instanceCount + selectables.custom.size;
|
|
55
55
|
}
|
|
56
56
|
Selectables.size = size;
|
|
57
57
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Selectable.js","sourceRoot":"","sources":["../../../src/unified-selection/Selectable.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { from, map, merge, mergeMap } from \"rxjs\";\nimport { eachValueFrom } from \"rxjs-for-await\";\nimport { Id64String } from \"@itwin/core-bentley\";\nimport { normalizeFullClassName } from \"@itwin/presentation-shared\";\n\n/**\n * ECInstance selectable\n * @public\n */\nexport interface SelectableInstanceKey {\n /** Full class name in format `SchemaName:ClassName` or `SchemaName.ClassName`. */\n className: string;\n /** ECInstance ID */\n id: string;\n}\n\n/**\n * A custom selectable, which has an identifier, knows how to loads its associated selectable instance keys\n * and has custom data associated with it.\n *\n * An example of such selectable could be an instance grouping node:\n * - `identifier` could be a GUID, associated with the node,\n * - `loadInstanceKeys` would know how to load grouped instance keys from the node,\n * - `data` could be set to the node itself.\n *\n * @public\n */\nexport interface CustomSelectable {\n /** Unique identifier of the selectable. */\n identifier: string;\n /** Asynchronous function for loading instance keys associated with this selectable. */\n loadInstanceKeys: () => AsyncIterableIterator<SelectableInstanceKey>;\n /** Custom data associated with the selectable. */\n data: unknown;\n}\n\n/**\n * A single selectable that identifies something that can be selected in an iTwin.js application.\n * @public\n */\nexport type Selectable = SelectableInstanceKey | CustomSelectable;\n\n/**\n * A type of identifier that can be used to identify a selectable in selection storage.\n * @public\n */\nexport type SelectableIdentifier = SelectableInstanceKey | Pick<CustomSelectable, \"identifier\">;\n\n/** @public */\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace Selectable {\n /** Check if the supplied selectable is a `SelectableInstanceKey` */\n export function isInstanceKey(selectable: Selectable | SelectableIdentifier): selectable is SelectableInstanceKey {\n const instanceKey = selectable as SelectableInstanceKey;\n return !!instanceKey.className && !!instanceKey.id;\n }\n\n /** Check if the supplied selectable is a `CustomSelectable` */\n export function isCustom(selectable: Selectable): selectable is CustomSelectable {\n return !!(selectable as CustomSelectable).identifier;\n }\n}\n\n/**\n * A collection of selectables that identify something that can be selected in an iTwin.js application\n * @public\n */\nexport interface Selectables {\n /**\n * A map between `SelectableInstanceKey.className` and a set of selected instance IDs.\n */\n instanceKeys: Map<string, Set<Id64String>>;\n /**\n * A map between `CustomSelectable.identifier` and the selectable itself.\n */\n custom: Map<string, CustomSelectable>;\n}\n\n/**\n * Class name used to create `SelectableInstanceKey` for transient elements.\n * @public\n */\nexport const TRANSIENT_ELEMENT_CLASSNAME = \"/TRANSIENT\";\n\n/** @public */\nexport namespace Selectables {\n /**\n * Creates `Selectables` from array of selectable\n * @param source Source to create selectables from\n * @public\n */\n export function create(source: Selectable[]): Selectables {\n const newSelectables = {\n instanceKeys: new Map<string, Set<string>>(),\n custom: new Map<string, CustomSelectable>(),\n };\n Selectables.add(newSelectables, source);\n return newSelectables;\n }\n\n /**\n * Get the number of selectables stored in a `Selectables` object.\n * @param selectables `Selectables` object to get size for\n * @public\n */\n export function size(selectables: Selectables): number {\n let insatanceCount = 0;\n selectables.instanceKeys.forEach((set: Set<string>) => (insatanceCount += set.size));\n return insatanceCount + selectables.custom.size;\n }\n\n /**\n * Is a `Selectables` object currently empty.\n * @param selectables `Selectables` object to check\n * @public\n */\n export function isEmpty(selectables: Selectables): boolean {\n return Selectables.size(selectables) === 0;\n }\n\n /**\n * Check if a `Selectables` object contains the specified selectable.\n * @param selectables `Selectables` object to check\n * @param value The selectable to check for.\n * @public\n */\n export function has(selectables: Selectables, value: SelectableIdentifier): boolean {\n if (Selectable.isInstanceKey(value)) {\n const normalizedClassName = normalizeClassName(value.className);\n const set = selectables.instanceKeys.get(normalizedClassName);\n return !!(set && set.has(value.id));\n }\n return selectables.custom.has(value.identifier);\n }\n\n /**\n * Check if a `Selectables` object contains all the specified selectables.\n * @param selectables `Selectables` object to check\n * @param values The selectables to check for.\n * @public\n */\n export function hasAll(selectables: Selectables, values: SelectableIdentifier[]): boolean {\n if (Selectables.size(selectables) < values.length) {\n return false;\n }\n for (const selectable of values) {\n if (!Selectables.has(selectables, selectable)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Check if a `Selectables` object contains any of the specified selectables.\n * @param selectables `Selectables` object to check\n * @param values The selectables to check for.\n * @public\n */\n export function hasAny(selectables: Selectables, values: SelectableIdentifier[]): boolean {\n for (const selectable of values) {\n if (Selectables.has(selectables, selectable)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Add a one or more selectables to a `Selectables`\n * @param selectables `Selectables` object to add selectables for\n * @param values Selectables to add.\n * @public\n */\n export function add(selectables: Selectables, values: Selectable[]): boolean {\n let hasChanged = false;\n for (const selectable of values) {\n if (Selectable.isInstanceKey(selectable)) {\n const normalizedClassName = normalizeClassName(selectable.className);\n let set = selectables.instanceKeys.get(normalizedClassName);\n if (!set) {\n set = new Set<string>();\n }\n if (!set.has(selectable.id)) {\n set.add(selectable.id);\n selectables.instanceKeys.set(normalizedClassName, set);\n hasChanged = true;\n }\n } else if (!selectables.custom.has(selectable.identifier)) {\n selectables.custom.set(selectable.identifier, selectable);\n hasChanged = true;\n }\n }\n return hasChanged;\n }\n\n /**\n * Removes one or more selectables from a `Selectables` object.\n * @param selectables `Selectables` object to remove selectables for\n * @param values Selectables to remove.\n * @public\n */\n export function remove(selectables: Selectables, values: Selectable[]): boolean {\n let hasChanged = false;\n for (const selectable of values) {\n if (Selectable.isInstanceKey(selectable)) {\n const normalizedClassName = normalizeClassName(selectable.className);\n const set = selectables.instanceKeys.get(normalizedClassName);\n if (set && set.has(selectable.id)) {\n set.delete(selectable.id);\n hasChanged = true;\n if (set.size === 0) {\n selectables.instanceKeys.delete(normalizedClassName);\n }\n }\n } else if (selectables.custom.has(selectable.identifier)) {\n selectables.custom.delete(selectable.identifier);\n hasChanged = true;\n }\n }\n return hasChanged;\n }\n\n /**\n * Clear a `Selectables` object.\n * @param selectables `Selectables` object to clear selectables for\n * @public\n */\n export function clear(selectables: Selectables): boolean {\n if (Selectables.size(selectables) === 0) {\n return false;\n }\n selectables.instanceKeys = new Map<string, Set<string>>();\n selectables.custom = new Map<string, CustomSelectable>();\n return true;\n }\n\n /**\n * Check whether at least one selectable passes a condition in a `Selectables` object.\n * @param selectables `Selectables` object to check\n * @public\n */\n export function some(selectables: Selectables, callback: (selectable: Selectable) => boolean) {\n for (const entry of selectables.instanceKeys) {\n for (const item of entry[1]) {\n if (callback({ className: entry[0], id: item })) {\n return true;\n }\n }\n }\n for (const entry of selectables.custom) {\n if (callback(entry[1])) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Iterate over all keys in a `Selectables` object.\n * @param selectables `Selectables` object to iterate over\n * @public\n */\n export function forEach(selectables: Selectables, callback: (selectable: Selectable, index: number) => void) {\n let index = 0;\n selectables.instanceKeys.forEach((ids: Set<string>, className: string) => {\n ids.forEach((id: string) => callback({ className, id }, index++));\n });\n selectables.custom.forEach((data) => {\n callback(data, index++);\n });\n }\n\n /**\n * Load all instance keys from the given `Selectables` object.\n * @param selectables `Selectables` object to load instance keys from\n * @public\n */\n export function load(selectables: Selectables): AsyncIterableIterator<SelectableInstanceKey> {\n return eachValueFrom(\n merge(\n from(selectables.instanceKeys).pipe(mergeMap(([className, ids]) => from(ids).pipe(map((id) => ({ className, id }))))),\n from(selectables.custom).pipe(mergeMap(([_, selectable]) => from(selectable.loadInstanceKeys()))),\n ),\n );\n }\n}\n\nfunction normalizeClassName(fullClassName: string) {\n return fullClassName === TRANSIENT_ELEMENT_CLASSNAME ? fullClassName : normalizeFullClassName(fullClassName);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Selectable.js","sourceRoot":"","sources":["../../../src/unified-selection/Selectable.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { from, map, merge, mergeMap } from \"rxjs\";\nimport { eachValueFrom } from \"rxjs-for-await\";\nimport { Id64String } from \"@itwin/core-bentley\";\nimport { normalizeFullClassName } from \"@itwin/presentation-shared\";\n\n/**\n * ECInstance selectable\n * @public\n */\nexport interface SelectableInstanceKey {\n /** Full class name in format `SchemaName:ClassName` or `SchemaName.ClassName`. */\n className: string;\n /** ECInstance ID */\n id: string;\n}\n\n/**\n * A custom selectable, which has an identifier, knows how to loads its associated selectable instance keys\n * and has custom data associated with it.\n *\n * An example of such selectable could be an instance grouping node:\n * - `identifier` could be a GUID, associated with the node,\n * - `loadInstanceKeys` would know how to load grouped instance keys from the node,\n * - `data` could be set to the node itself.\n *\n * @public\n */\nexport interface CustomSelectable {\n /** Unique identifier of the selectable. */\n identifier: string;\n /** Asynchronous function for loading instance keys associated with this selectable. */\n loadInstanceKeys: () => AsyncIterableIterator<SelectableInstanceKey>;\n /** Custom data associated with the selectable. */\n data: unknown;\n}\n\n/**\n * A single selectable that identifies something that can be selected in an iTwin.js application.\n * @public\n */\nexport type Selectable = SelectableInstanceKey | CustomSelectable;\n\n/**\n * A type of identifier that can be used to identify a selectable in selection storage.\n * @public\n */\nexport type SelectableIdentifier = SelectableInstanceKey | Pick<CustomSelectable, \"identifier\">;\n\n/** @public */\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace Selectable {\n /** Check if the supplied selectable is a `SelectableInstanceKey` */\n export function isInstanceKey(selectable: Selectable | SelectableIdentifier): selectable is SelectableInstanceKey {\n const instanceKey = selectable as SelectableInstanceKey;\n return !!instanceKey.className && !!instanceKey.id;\n }\n\n /** Check if the supplied selectable is a `CustomSelectable` */\n export function isCustom(selectable: Selectable): selectable is CustomSelectable {\n return !!(selectable as CustomSelectable).identifier;\n }\n}\n\n/**\n * A collection of selectables that identify something that can be selected in an iTwin.js application\n * @public\n */\nexport interface Selectables {\n /**\n * A map between `SelectableInstanceKey.className` and a set of selected instance IDs.\n */\n instanceKeys: Map<string, Set<Id64String>>;\n /**\n * A map between `CustomSelectable.identifier` and the selectable itself.\n */\n custom: Map<string, CustomSelectable>;\n}\n\n/**\n * Class name used to create `SelectableInstanceKey` for transient elements.\n * @public\n */\nexport const TRANSIENT_ELEMENT_CLASSNAME = \"/TRANSIENT\";\n\n/** @public */\nexport namespace Selectables {\n /**\n * Creates `Selectables` from array of selectable\n * @param source Source to create selectables from\n * @public\n */\n export function create(source: Selectable[]): Selectables {\n const newSelectables = {\n instanceKeys: new Map<string, Set<string>>(),\n custom: new Map<string, CustomSelectable>(),\n };\n Selectables.add(newSelectables, source);\n return newSelectables;\n }\n\n /**\n * Get the number of selectables stored in a `Selectables` object.\n * @param selectables `Selectables` object to get size for\n * @public\n */\n export function size(selectables: Selectables): number {\n let instanceCount = 0;\n selectables.instanceKeys.forEach((set: Set<string>) => (instanceCount += set.size));\n return instanceCount + selectables.custom.size;\n }\n\n /**\n * Is a `Selectables` object currently empty.\n * @param selectables `Selectables` object to check\n * @public\n */\n export function isEmpty(selectables: Selectables): boolean {\n return Selectables.size(selectables) === 0;\n }\n\n /**\n * Check if a `Selectables` object contains the specified selectable.\n * @param selectables `Selectables` object to check\n * @param value The selectable to check for.\n * @public\n */\n export function has(selectables: Selectables, value: SelectableIdentifier): boolean {\n if (Selectable.isInstanceKey(value)) {\n const normalizedClassName = normalizeClassName(value.className);\n const set = selectables.instanceKeys.get(normalizedClassName);\n return !!(set && set.has(value.id));\n }\n return selectables.custom.has(value.identifier);\n }\n\n /**\n * Check if a `Selectables` object contains all the specified selectables.\n * @param selectables `Selectables` object to check\n * @param values The selectables to check for.\n * @public\n */\n export function hasAll(selectables: Selectables, values: SelectableIdentifier[]): boolean {\n if (Selectables.size(selectables) < values.length) {\n return false;\n }\n for (const selectable of values) {\n if (!Selectables.has(selectables, selectable)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Check if a `Selectables` object contains any of the specified selectables.\n * @param selectables `Selectables` object to check\n * @param values The selectables to check for.\n * @public\n */\n export function hasAny(selectables: Selectables, values: SelectableIdentifier[]): boolean {\n for (const selectable of values) {\n if (Selectables.has(selectables, selectable)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Add a one or more selectables to a `Selectables`\n * @param selectables `Selectables` object to add selectables for\n * @param values Selectables to add.\n * @public\n */\n export function add(selectables: Selectables, values: Selectable[]): boolean {\n let hasChanged = false;\n for (const selectable of values) {\n if (Selectable.isInstanceKey(selectable)) {\n const normalizedClassName = normalizeClassName(selectable.className);\n let set = selectables.instanceKeys.get(normalizedClassName);\n if (!set) {\n set = new Set<string>();\n }\n if (!set.has(selectable.id)) {\n set.add(selectable.id);\n selectables.instanceKeys.set(normalizedClassName, set);\n hasChanged = true;\n }\n } else if (!selectables.custom.has(selectable.identifier)) {\n selectables.custom.set(selectable.identifier, selectable);\n hasChanged = true;\n }\n }\n return hasChanged;\n }\n\n /**\n * Removes one or more selectables from a `Selectables` object.\n * @param selectables `Selectables` object to remove selectables for\n * @param values Selectables to remove.\n * @public\n */\n export function remove(selectables: Selectables, values: Selectable[]): boolean {\n let hasChanged = false;\n for (const selectable of values) {\n if (Selectable.isInstanceKey(selectable)) {\n const normalizedClassName = normalizeClassName(selectable.className);\n const set = selectables.instanceKeys.get(normalizedClassName);\n if (set && set.has(selectable.id)) {\n set.delete(selectable.id);\n hasChanged = true;\n if (set.size === 0) {\n selectables.instanceKeys.delete(normalizedClassName);\n }\n }\n } else if (selectables.custom.has(selectable.identifier)) {\n selectables.custom.delete(selectable.identifier);\n hasChanged = true;\n }\n }\n return hasChanged;\n }\n\n /**\n * Clear a `Selectables` object.\n * @param selectables `Selectables` object to clear selectables for\n * @public\n */\n export function clear(selectables: Selectables): boolean {\n if (Selectables.size(selectables) === 0) {\n return false;\n }\n selectables.instanceKeys = new Map<string, Set<string>>();\n selectables.custom = new Map<string, CustomSelectable>();\n return true;\n }\n\n /**\n * Check whether at least one selectable passes a condition in a `Selectables` object.\n * @param selectables `Selectables` object to check\n * @public\n */\n export function some(selectables: Selectables, callback: (selectable: Selectable) => boolean) {\n for (const entry of selectables.instanceKeys) {\n for (const item of entry[1]) {\n if (callback({ className: entry[0], id: item })) {\n return true;\n }\n }\n }\n for (const entry of selectables.custom) {\n if (callback(entry[1])) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Iterate over all keys in a `Selectables` object.\n * @param selectables `Selectables` object to iterate over\n * @public\n */\n export function forEach(selectables: Selectables, callback: (selectable: Selectable, index: number) => void) {\n let index = 0;\n selectables.instanceKeys.forEach((ids: Set<string>, className: string) => {\n ids.forEach((id: string) => callback({ className, id }, index++));\n });\n selectables.custom.forEach((data) => {\n callback(data, index++);\n });\n }\n\n /**\n * Load all instance keys from the given `Selectables` object.\n * @param selectables `Selectables` object to load instance keys from\n * @public\n */\n export function load(selectables: Selectables): AsyncIterableIterator<SelectableInstanceKey> {\n return eachValueFrom(\n merge(\n from(selectables.instanceKeys).pipe(mergeMap(([className, ids]) => from(ids).pipe(map((id) => ({ className, id }))))),\n from(selectables.custom).pipe(mergeMap(([_, selectable]) => from(selectable.loadInstanceKeys()))),\n ),\n );\n }\n}\n\nfunction normalizeClassName(fullClassName: string) {\n return fullClassName === TRANSIENT_ELEMENT_CLASSNAME ? fullClassName : normalizeFullClassName(fullClassName);\n}\n"]}
|
|
@@ -90,6 +90,7 @@ async function* computeModelSelection(queryExecutor, ids) {
|
|
|
90
90
|
async function* computeFunctionalElementSelection(queryExecutor, ids, ancestorLevel) {
|
|
91
91
|
const bindings = [];
|
|
92
92
|
const recurseUntilRoot = ancestorLevel < 0;
|
|
93
|
+
// cspell:disable
|
|
93
94
|
const ctes = [
|
|
94
95
|
`
|
|
95
96
|
Elements2dOrNearestFunctionalElements(OriginalECInstanceId, OriginalECClassId, ECInstanceId, ECClassId, ParentId) AS (
|
|
@@ -176,6 +177,7 @@ async function* computeFunctionalElementSelection(queryExecutor, ids, ancestorLe
|
|
|
176
177
|
SELECT DISTINCT ECInstanceId, ClassName FROM Element3dAncestorRelatedFunctionalElement
|
|
177
178
|
`,
|
|
178
179
|
].join(" UNION ");
|
|
180
|
+
// cspell:enable
|
|
179
181
|
yield* executeQuery(queryExecutor, { ctes, ecsql, bindings });
|
|
180
182
|
}
|
|
181
183
|
function formAncestorLevelBinding(ancestorLevel, bindings) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectionScope.js","sourceRoot":"","sources":["../../../src/unified-selection/SelectionScope.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Id64, Id64Arg, Id64Array } from \"@itwin/core-bentley\";\nimport { ECSqlBinding, ECSqlQueryDef, ECSqlQueryExecutor, ECSqlQueryRow } from \"@itwin/presentation-shared\";\nimport { SelectableInstanceKey } from \"./Selectable.js\";\nimport { formIdBindings, genericExecuteQuery } from \"./Utils.js\";\n\n/**\n * Available selection scopes.\n * @public\n */\ntype SelectionScopeIdentifier = \"element\" | \"model\" | \"category\" | \"functional\";\n\n/**\n * Props for computing element selection.\n * @public\n */\nexport interface ElementSelectionScopeProps {\n /** Identifies this as either \"element\" or \"functional\" selection scope */\n id: \"element\" | \"functional\";\n /**\n * Specifies how far \"up\" we should walk to find the target element. When not specified or `0`,\n * the target element matches the request element. When set to `1`, the target element matches the direct parent element.\n * When set to `2`, the target element is parent of the parent element and so on. In all situations when this is `> 0`,\n * we're not walking further than the last existing element, for example when `ancestorLevel = 1` (direct parent\n * element is requested), but the request element doesn't have a parent, the request element is returned as the result.\n * A negative value would result in the top-most element to be returned.\n */\n ancestorLevel?: number;\n}\n\n/**\n * A union of types that can be used to define a selection scope.\n * @public\n * @since 1.4.0\n */\nexport type SelectionScope = ElementSelectionScopeProps | { id: SelectionScopeIdentifier } | SelectionScopeIdentifier;\n\n/**\n * Props for `computeSelection`.\n * @public\n */\nexport interface ComputeSelectionProps {\n /** iModel query executor. */\n queryExecutor: ECSqlQueryExecutor;\n /** IDs of elements to compute selection for. */\n elementIds: Id64Arg;\n /** Selection scope to compute selection with. */\n scope: SelectionScope;\n}\n\n/**\n * Computes selection from given element IDs.\n * @public\n */\nexport async function* computeSelection(props: ComputeSelectionProps): AsyncIterableIterator<SelectableInstanceKey> {\n const { queryExecutor, elementIds, scope } = props;\n\n if (typeof scope === \"string\") {\n yield* computeSelection({ queryExecutor, elementIds, scope: { id: scope } });\n return;\n }\n\n const nonTransientIds: Id64Array = [];\n for (const id of Id64.iterable(elementIds)) {\n if (!Id64.isTransient(id)) {\n nonTransientIds.push(id);\n }\n }\n\n switch (scope.id) {\n case \"element\":\n yield* computeElementSelection(queryExecutor, nonTransientIds, (scope as ElementSelectionScopeProps).ancestorLevel ?? 0);\n return;\n case \"category\":\n yield* computeCategorySelection(queryExecutor, nonTransientIds);\n return;\n case \"model\":\n yield* computeModelSelection(queryExecutor, nonTransientIds);\n return;\n case \"functional\":\n yield* computeFunctionalElementSelection(queryExecutor, nonTransientIds, (scope as ElementSelectionScopeProps).ancestorLevel ?? 0);\n return;\n }\n}\n\nasync function* computeElementSelection(\n queryExecutor: ECSqlQueryExecutor,\n elementIds: string[],\n ancestorLevel: number,\n): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const recurseUntilRoot = ancestorLevel < 0;\n const ctes = [\n `\n AncestorElements(ECInstanceId, ECClassId, Depth, ParentId) AS (\n SELECT ECInstanceId, ECClassId, ${formAncestorLevelBinding(ancestorLevel, bindings)}, Parent.Id\n FROM BisCore.Element\n WHERE ${formIdBindings(\"ECInstanceId\", elementIds, bindings)}\n UNION ALL\n SELECT pe.ECInstanceId, pe.ECClassId, a.Depth - 1, pe.Parent.Id\n FROM AncestorElements a\n JOIN BisCore.Element pe ON pe.ECInstanceId = a.ParentId\n WHERE ${recurseUntilRoot ? \"\" : \"Depth > 0 AND\"} ParentId IS NOT NULL\n )\n `,\n ];\n const ecsql = `\n SELECT DISTINCT ECInstanceId, ec_classname(ECClassId, 's.c') AS ClassName\n FROM AncestorElements\n WHERE ${recurseUntilRoot ? \"\" : \"Depth = 0 OR\"} ParentId IS NULL\n `;\n yield* executeQuery(queryExecutor, { ctes, ecsql, bindings });\n}\n\nasync function* computeCategorySelection(queryExecutor: ECSqlQueryExecutor, ids: string[]): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const ecsql = [\n `\n SELECT DISTINCT c.ECInstanceId, ec_classname(c.ECClassId, 's.c') AS ClassName\n FROM BisCore.Category c\n JOIN BisCore.GeometricElement2d ge ON ge.Category.Id = c.ECInstanceId\n WHERE ${formIdBindings(\"ge.ECInstanceId\", ids, bindings)}\n `,\n `\n SELECT DISTINCT c.ECInstanceId, ec_classname(c.ECClassId, 's.c') AS ClassName\n FROM BisCore.Category c\n JOIN BisCore.GeometricElement3d ge ON ge.Category.Id = c.ECInstanceId\n WHERE ${formIdBindings(\"ge.ECInstanceId\", ids, bindings)}\n `,\n ].join(\" UNION ALL \");\n yield* executeQuery(queryExecutor, { ecsql, bindings });\n}\n\nasync function* computeModelSelection(queryExecutor: ECSqlQueryExecutor, ids: string[]): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const ecsql = `\n SELECT DISTINCT m.ECInstanceId, ec_classname(m.ECClassId, 's.c') AS ClassName\n FROM BisCore.Model m\n JOIN BisCore.Element e ON e.Model.Id = m.ECInstanceId\n WHERE ${formIdBindings(\"e.ECInstanceId\", ids, bindings)}\n `;\n yield* executeQuery(queryExecutor, { ecsql, bindings });\n}\n\nasync function* computeFunctionalElementSelection(\n queryExecutor: ECSqlQueryExecutor,\n ids: string[],\n ancestorLevel: number,\n): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const recurseUntilRoot = ancestorLevel < 0;\n const ctes = [\n `\n Elements2dOrNearestFunctionalElements(OriginalECInstanceId, OriginalECClassId, ECInstanceId, ECClassId, ParentId) AS (\n SELECT ECInstanceId, ECClassId, ECInstanceId, ECClassId, Parent.Id\n FROM BisCore.Element\n WHERE ${formIdBindings(\"ECInstanceId\", ids, bindings)} AND ECClassId IS NOT (BisCore.GeometricElement3d)\n UNION ALL\n SELECT\n e2onfe.OriginalECInstanceId,\n e2onfe.OriginalECClassId,\n COALESCE(dgrfe.TargetECInstanceId, pe.ECInstanceId),\n COALESCE(dgrfe.TargetECClassId, pe.ECClassId),\n pe.Parent.Id\n FROM Elements2dOrNearestFunctionalElements e2onfe\n LEFT JOIN BisCore.Element pe ON pe.ECInstanceId = e2onfe.ParentId\n LEFT JOIN Functional.DrawingGraphicRepresentsFunctionalElement dgrfe ON dgrfe.SourceECInstanceId = e2onfe.ECInstanceId\n WHERE e2onfe.ECClassId IS NOT (Functional.FunctionalElement) AND (e2onfe.ParentId IS NOT NULL OR dgrfe.TargetECInstanceId IS NOT NULL)\n )\n `,\n `\n Element2dNearestFunctionalElements(OriginalECInstanceId, ECInstanceId, ECClassId) AS (\n SELECT OriginalECInstanceId, ECInstanceId, ECClassId\n FROM Elements2dOrNearestFunctionalElements\n WHERE ECClassId IS (Functional.FunctionalElement)\n )\n `,\n `\n Elements2dWithoutFunctionalElement(ECInstanceId, ECClassId) AS (\n SELECT e2wfe.OriginalECInstanceId, OriginalECClassId\n FROM Elements2dOrNearestFunctionalElements e2wfe\n LEFT JOIN Element2dNearestFunctionalElements e2nfe ON e2nfe.OriginalECInstanceId = e2wfe.OriginalECInstanceId\n WHERE e2wfe.ParentId IS NULL AND e2nfe.ECInstanceId IS NULL\n )\n `,\n `\n Elements2d(ECInstanceId, ECClassId) AS (\n SELECT ECInstanceId, ECClassId FROM Element2dNearestFunctionalElements\n UNION\n SELECT ECInstanceId, ECClassId FROM Elements2dWithoutFunctionalElement\n )\n `,\n `\n Element2dAncestorElements(ECInstanceId, ECClassId, Depth, ParentId) AS (\n SELECT e.ECInstanceId, e.ECClassId, ${formAncestorLevelBinding(ancestorLevel, bindings)}, e.Parent.Id\n FROM BisCore.Element e\n JOIN Elements2d e2d ON e2d.ECInstanceId = e.ECInstanceId\n UNION ALL\n SELECT pe.ECInstanceId, pe.ECClassId, e2ae.Depth - 1, pe.Parent.Id\n FROM Element2dAncestorElements e2ae\n JOIN BisCore.Element pe ON pe.ECInstanceId = e2ae.ParentId\n WHERE ${recurseUntilRoot ? \"\" : \"Depth > 0 AND\"} ParentId IS NOT NULL\n )\n `,\n `\n Element3dAncestorElements(ECInstanceId, ECClassId, Depth, ParentId) AS (\n SELECT ge.ECInstanceId, ge.ECClassId, ${formAncestorLevelBinding(ancestorLevel, bindings)}, ge.Parent.Id\n FROM BisCore.GeometricElement3d ge\n WHERE ${formIdBindings(\"ge.ECInstanceId\", ids, bindings)}\n UNION ALL\n SELECT pe.ECInstanceId, pe.ECClassId, e3ae.Depth - 1, pe.Parent.Id\n FROM Element3dAncestorElements e3ae\n JOIN BisCore.Element pe ON pe.ECInstanceId = e3ae.ParentId\n WHERE ${recurseUntilRoot ? \"\" : \"Depth > 0 AND\"} ParentId IS NOT NULL\n )\n `,\n `\n Element3dAncestorRelatedFunctionalElement(ECInstanceId, ClassName) AS (\n SELECT\n COALESCE(peff.TargetECInstanceId, e3ae.ECInstanceId),\n ec_classname(COALESCE(peff.TargetECClassId, e3ae.ECClassId), 's.c')\n FROM Element3dAncestorElements e3ae\n LEFT JOIN Functional.PhysicalElementFulfillsFunction peff ON peff.SourceECInstanceId = e3ae.ECInstanceId\n WHERE ${recurseUntilRoot ? \"\" : \"e3ae.Depth = 0 OR\"} e3ae.ParentId IS NULL\n )\n `,\n ];\n const ecsql = [\n `\n SELECT DISTINCT ECInstanceId, ec_classname(ECClassId, 's.c') AS ClassName\n FROM Element2dAncestorElements\n WHERE ${recurseUntilRoot ? \"\" : \"Depth = 0 OR\"} ParentId IS NULL\n `,\n `\n SELECT DISTINCT ECInstanceId, ClassName FROM Element3dAncestorRelatedFunctionalElement\n `,\n ].join(\" UNION \");\n yield* executeQuery(queryExecutor, { ctes, ecsql, bindings });\n}\n\nfunction formAncestorLevelBinding(ancestorLevel: number, bindings: ECSqlBinding[]) {\n bindings.push({ type: \"int\", value: ancestorLevel });\n return \"?\";\n}\n\nasync function* executeQuery(queryExecutor: ECSqlQueryExecutor, query: ECSqlQueryDef): AsyncIterableIterator<SelectableInstanceKey> {\n yield* genericExecuteQuery(queryExecutor, query, (row: ECSqlQueryRow) => ({\n className: row.ClassName,\n id: row.ECInstanceId,\n }));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SelectionScope.js","sourceRoot":"","sources":["../../../src/unified-selection/SelectionScope.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Id64, Id64Arg, Id64Array } from \"@itwin/core-bentley\";\nimport { ECSqlBinding, ECSqlQueryDef, ECSqlQueryExecutor, ECSqlQueryRow } from \"@itwin/presentation-shared\";\nimport { SelectableInstanceKey } from \"./Selectable.js\";\nimport { formIdBindings, genericExecuteQuery } from \"./Utils.js\";\n\n/**\n * Available selection scopes.\n * @public\n */\ntype SelectionScopeIdentifier = \"element\" | \"model\" | \"category\" | \"functional\";\n\n/**\n * Props for computing element selection.\n * @public\n */\nexport interface ElementSelectionScopeProps {\n /** Identifies this as either \"element\" or \"functional\" selection scope */\n id: \"element\" | \"functional\";\n /**\n * Specifies how far \"up\" we should walk to find the target element. When not specified or `0`,\n * the target element matches the request element. When set to `1`, the target element matches the direct parent element.\n * When set to `2`, the target element is parent of the parent element and so on. In all situations when this is `> 0`,\n * we're not walking further than the last existing element, for example when `ancestorLevel = 1` (direct parent\n * element is requested), but the request element doesn't have a parent, the request element is returned as the result.\n * A negative value would result in the top-most element to be returned.\n */\n ancestorLevel?: number;\n}\n\n/**\n * A union of types that can be used to define a selection scope.\n * @public\n * @since 1.4.0\n */\nexport type SelectionScope = ElementSelectionScopeProps | { id: SelectionScopeIdentifier } | SelectionScopeIdentifier;\n\n/**\n * Props for `computeSelection`.\n * @public\n */\nexport interface ComputeSelectionProps {\n /** iModel query executor. */\n queryExecutor: ECSqlQueryExecutor;\n /** IDs of elements to compute selection for. */\n elementIds: Id64Arg;\n /** Selection scope to compute selection with. */\n scope: SelectionScope;\n}\n\n/**\n * Computes selection from given element IDs.\n * @public\n */\nexport async function* computeSelection(props: ComputeSelectionProps): AsyncIterableIterator<SelectableInstanceKey> {\n const { queryExecutor, elementIds, scope } = props;\n\n if (typeof scope === \"string\") {\n yield* computeSelection({ queryExecutor, elementIds, scope: { id: scope } });\n return;\n }\n\n const nonTransientIds: Id64Array = [];\n for (const id of Id64.iterable(elementIds)) {\n if (!Id64.isTransient(id)) {\n nonTransientIds.push(id);\n }\n }\n\n switch (scope.id) {\n case \"element\":\n yield* computeElementSelection(queryExecutor, nonTransientIds, (scope as ElementSelectionScopeProps).ancestorLevel ?? 0);\n return;\n case \"category\":\n yield* computeCategorySelection(queryExecutor, nonTransientIds);\n return;\n case \"model\":\n yield* computeModelSelection(queryExecutor, nonTransientIds);\n return;\n case \"functional\":\n yield* computeFunctionalElementSelection(queryExecutor, nonTransientIds, (scope as ElementSelectionScopeProps).ancestorLevel ?? 0);\n return;\n }\n}\n\nasync function* computeElementSelection(\n queryExecutor: ECSqlQueryExecutor,\n elementIds: string[],\n ancestorLevel: number,\n): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const recurseUntilRoot = ancestorLevel < 0;\n const ctes = [\n `\n AncestorElements(ECInstanceId, ECClassId, Depth, ParentId) AS (\n SELECT ECInstanceId, ECClassId, ${formAncestorLevelBinding(ancestorLevel, bindings)}, Parent.Id\n FROM BisCore.Element\n WHERE ${formIdBindings(\"ECInstanceId\", elementIds, bindings)}\n UNION ALL\n SELECT pe.ECInstanceId, pe.ECClassId, a.Depth - 1, pe.Parent.Id\n FROM AncestorElements a\n JOIN BisCore.Element pe ON pe.ECInstanceId = a.ParentId\n WHERE ${recurseUntilRoot ? \"\" : \"Depth > 0 AND\"} ParentId IS NOT NULL\n )\n `,\n ];\n const ecsql = `\n SELECT DISTINCT ECInstanceId, ec_classname(ECClassId, 's.c') AS ClassName\n FROM AncestorElements\n WHERE ${recurseUntilRoot ? \"\" : \"Depth = 0 OR\"} ParentId IS NULL\n `;\n yield* executeQuery(queryExecutor, { ctes, ecsql, bindings });\n}\n\nasync function* computeCategorySelection(queryExecutor: ECSqlQueryExecutor, ids: string[]): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const ecsql = [\n `\n SELECT DISTINCT c.ECInstanceId, ec_classname(c.ECClassId, 's.c') AS ClassName\n FROM BisCore.Category c\n JOIN BisCore.GeometricElement2d ge ON ge.Category.Id = c.ECInstanceId\n WHERE ${formIdBindings(\"ge.ECInstanceId\", ids, bindings)}\n `,\n `\n SELECT DISTINCT c.ECInstanceId, ec_classname(c.ECClassId, 's.c') AS ClassName\n FROM BisCore.Category c\n JOIN BisCore.GeometricElement3d ge ON ge.Category.Id = c.ECInstanceId\n WHERE ${formIdBindings(\"ge.ECInstanceId\", ids, bindings)}\n `,\n ].join(\" UNION ALL \");\n yield* executeQuery(queryExecutor, { ecsql, bindings });\n}\n\nasync function* computeModelSelection(queryExecutor: ECSqlQueryExecutor, ids: string[]): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const ecsql = `\n SELECT DISTINCT m.ECInstanceId, ec_classname(m.ECClassId, 's.c') AS ClassName\n FROM BisCore.Model m\n JOIN BisCore.Element e ON e.Model.Id = m.ECInstanceId\n WHERE ${formIdBindings(\"e.ECInstanceId\", ids, bindings)}\n `;\n yield* executeQuery(queryExecutor, { ecsql, bindings });\n}\n\nasync function* computeFunctionalElementSelection(\n queryExecutor: ECSqlQueryExecutor,\n ids: string[],\n ancestorLevel: number,\n): AsyncIterableIterator<SelectableInstanceKey> {\n const bindings: ECSqlBinding[] = [];\n const recurseUntilRoot = ancestorLevel < 0;\n // cspell:disable\n const ctes = [\n `\n Elements2dOrNearestFunctionalElements(OriginalECInstanceId, OriginalECClassId, ECInstanceId, ECClassId, ParentId) AS (\n SELECT ECInstanceId, ECClassId, ECInstanceId, ECClassId, Parent.Id\n FROM BisCore.Element\n WHERE ${formIdBindings(\"ECInstanceId\", ids, bindings)} AND ECClassId IS NOT (BisCore.GeometricElement3d)\n UNION ALL\n SELECT\n e2onfe.OriginalECInstanceId,\n e2onfe.OriginalECClassId,\n COALESCE(dgrfe.TargetECInstanceId, pe.ECInstanceId),\n COALESCE(dgrfe.TargetECClassId, pe.ECClassId),\n pe.Parent.Id\n FROM Elements2dOrNearestFunctionalElements e2onfe\n LEFT JOIN BisCore.Element pe ON pe.ECInstanceId = e2onfe.ParentId\n LEFT JOIN Functional.DrawingGraphicRepresentsFunctionalElement dgrfe ON dgrfe.SourceECInstanceId = e2onfe.ECInstanceId\n WHERE e2onfe.ECClassId IS NOT (Functional.FunctionalElement) AND (e2onfe.ParentId IS NOT NULL OR dgrfe.TargetECInstanceId IS NOT NULL)\n )\n `,\n `\n Element2dNearestFunctionalElements(OriginalECInstanceId, ECInstanceId, ECClassId) AS (\n SELECT OriginalECInstanceId, ECInstanceId, ECClassId\n FROM Elements2dOrNearestFunctionalElements\n WHERE ECClassId IS (Functional.FunctionalElement)\n )\n `,\n `\n Elements2dWithoutFunctionalElement(ECInstanceId, ECClassId) AS (\n SELECT e2wfe.OriginalECInstanceId, OriginalECClassId\n FROM Elements2dOrNearestFunctionalElements e2wfe\n LEFT JOIN Element2dNearestFunctionalElements e2nfe ON e2nfe.OriginalECInstanceId = e2wfe.OriginalECInstanceId\n WHERE e2wfe.ParentId IS NULL AND e2nfe.ECInstanceId IS NULL\n )\n `,\n `\n Elements2d(ECInstanceId, ECClassId) AS (\n SELECT ECInstanceId, ECClassId FROM Element2dNearestFunctionalElements\n UNION\n SELECT ECInstanceId, ECClassId FROM Elements2dWithoutFunctionalElement\n )\n `,\n `\n Element2dAncestorElements(ECInstanceId, ECClassId, Depth, ParentId) AS (\n SELECT e.ECInstanceId, e.ECClassId, ${formAncestorLevelBinding(ancestorLevel, bindings)}, e.Parent.Id\n FROM BisCore.Element e\n JOIN Elements2d e2d ON e2d.ECInstanceId = e.ECInstanceId\n UNION ALL\n SELECT pe.ECInstanceId, pe.ECClassId, e2ae.Depth - 1, pe.Parent.Id\n FROM Element2dAncestorElements e2ae\n JOIN BisCore.Element pe ON pe.ECInstanceId = e2ae.ParentId\n WHERE ${recurseUntilRoot ? \"\" : \"Depth > 0 AND\"} ParentId IS NOT NULL\n )\n `,\n `\n Element3dAncestorElements(ECInstanceId, ECClassId, Depth, ParentId) AS (\n SELECT ge.ECInstanceId, ge.ECClassId, ${formAncestorLevelBinding(ancestorLevel, bindings)}, ge.Parent.Id\n FROM BisCore.GeometricElement3d ge\n WHERE ${formIdBindings(\"ge.ECInstanceId\", ids, bindings)}\n UNION ALL\n SELECT pe.ECInstanceId, pe.ECClassId, e3ae.Depth - 1, pe.Parent.Id\n FROM Element3dAncestorElements e3ae\n JOIN BisCore.Element pe ON pe.ECInstanceId = e3ae.ParentId\n WHERE ${recurseUntilRoot ? \"\" : \"Depth > 0 AND\"} ParentId IS NOT NULL\n )\n `,\n `\n Element3dAncestorRelatedFunctionalElement(ECInstanceId, ClassName) AS (\n SELECT\n COALESCE(peff.TargetECInstanceId, e3ae.ECInstanceId),\n ec_classname(COALESCE(peff.TargetECClassId, e3ae.ECClassId), 's.c')\n FROM Element3dAncestorElements e3ae\n LEFT JOIN Functional.PhysicalElementFulfillsFunction peff ON peff.SourceECInstanceId = e3ae.ECInstanceId\n WHERE ${recurseUntilRoot ? \"\" : \"e3ae.Depth = 0 OR\"} e3ae.ParentId IS NULL\n )\n `,\n ];\n const ecsql = [\n `\n SELECT DISTINCT ECInstanceId, ec_classname(ECClassId, 's.c') AS ClassName\n FROM Element2dAncestorElements\n WHERE ${recurseUntilRoot ? \"\" : \"Depth = 0 OR\"} ParentId IS NULL\n `,\n `\n SELECT DISTINCT ECInstanceId, ClassName FROM Element3dAncestorRelatedFunctionalElement\n `,\n ].join(\" UNION \");\n // cspell:enable\n yield* executeQuery(queryExecutor, { ctes, ecsql, bindings });\n}\n\nfunction formAncestorLevelBinding(ancestorLevel: number, bindings: ECSqlBinding[]) {\n bindings.push({ type: \"int\", value: ancestorLevel });\n return \"?\";\n}\n\nasync function* executeQuery(queryExecutor: ECSqlQueryExecutor, query: ECSqlQueryDef): AsyncIterableIterator<SelectableInstanceKey> {\n yield* genericExecuteQuery(queryExecutor, query, (row: ECSqlQueryRow) => ({\n className: row.ClassName,\n id: row.ECInstanceId,\n }));\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/unified-selection",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "Package for managing unified selection in iTwin.js applications.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"./package.json": "./package.json"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@itwin/core-bentley": "^5.
|
|
39
|
+
"@itwin/core-bentley": "^5.2.0-dev.25",
|
|
40
40
|
"rxjs": "^7.8.1",
|
|
41
41
|
"rxjs-for-await": "^1.0.0",
|
|
42
42
|
"@itwin/presentation-shared": "^1.2.3"
|