@@ -8,9 +8,10 @@ import { bufferTime, filter, firstValueFrom, mergeAll, mergeMap, ReplaySubject,
8
8
import { assert } from "@itwin/core-bentley" ;
9
9
import { pushToMap } from "../../common/Utils" ;
10
10
11
+ import type { InstanceKey } from "@itwin/presentation-shared" ;
11
12
import type { ModelsTreeDefinition } from "../ModelsTreeDefinition" ;
12
13
import type { Id64Array , Id64Set , Id64String } from "@itwin/core-bentley" ;
13
- import type { LimitingECSqlQueryExecutor } from "@itwin/presentation-hierarchies" ;
14
+ import type { HierarchyNodeIdentifiersPath , LimitingECSqlQueryExecutor } from "@itwin/presentation-hierarchies" ;
14
15
15
16
interface SubjectInfo {
16
17
parentSubject : Id64String | undefined ;
@@ -32,12 +33,18 @@ export class ModelsTreeIdsCache {
32
33
private _subjectInfos : Promise < Map < Id64String , SubjectInfo > > | undefined ;
33
34
private _parentSubjectIds : Promise < Id64Array > | undefined ; // the list should contain a subject id if its node should be shown as having children
34
35
private _modelInfos : Promise < Map < Id64String , ModelInfo > > | undefined ;
36
+ private _modelKeyPaths : Map < Id64String , Promise < HierarchyNodeIdentifiersPath [ ] > > ;
37
+ private _subjectKeyPaths : Map < Id64String , Promise < HierarchyNodeIdentifiersPath > > ;
38
+ private _categoryKeyPaths : Map < Id64String , Promise < HierarchyNodeIdentifiersPath [ ] > > ;
35
39
36
40
constructor (
37
41
private _queryExecutor : LimitingECSqlQueryExecutor ,
38
42
private _hierarchyConfig : ModelsTreeHierarchyConfiguration ,
39
43
) {
40
44
this . _categoryElementCounts = new ModelCategoryElementsCountCache ( async ( input ) => this . queryCategoryElementCounts ( input ) ) ;
45
+ this . _modelKeyPaths = new Map ( ) ;
46
+ this . _subjectKeyPaths = new Map ( ) ;
47
+ this . _categoryKeyPaths = new Map ( ) ;
41
48
}
42
49
43
50
public [ Symbol . dispose ] ( ) {
@@ -215,22 +222,25 @@ export class ModelsTreeIdsCache {
215
222
return modelIds ;
216
223
}
217
224
218
- /**
219
- * Returns a list of Subject ancestor ECInstanceIds from root to target Subject as displayed in the
220
- * hierarchy - taking into account `hideInHierarchy` flag.
221
- */
222
- public async getSubjectAncestorsPath ( targetSubjectId : Id64String ) : Promise < Id64Array > {
223
- const subjectInfos = await this . getSubjectInfos ( ) ;
224
- const result = new Array < Id64String > ( ) ;
225
- let currParentId : Id64String | undefined = targetSubjectId ;
226
- while ( currParentId ) {
227
- const parentInfo = subjectInfos . get ( currParentId ) ;
228
- if ( ! parentInfo ?. hideInHierarchy ) {
229
- result . push ( currParentId ) ;
230
- }
231
- currParentId = parentInfo ?. parentSubject ;
225
+ public async createSubjectInstanceKeysPath ( targetSubjectId : Id64String ) : Promise < HierarchyNodeIdentifiersPath > {
226
+ let entry = this . _subjectKeyPaths . get ( targetSubjectId ) ;
227
+ if ( ! entry ) {
228
+ entry = ( async ( ) => {
229
+ const subjectInfos = await this . getSubjectInfos ( ) ;
230
+ const result = new Array < InstanceKey > ( ) ;
231
+ let currParentId : Id64String | undefined = targetSubjectId ;
232
+ while ( currParentId ) {
233
+ const parentInfo = subjectInfos . get ( currParentId ) ;
234
+ if ( ! parentInfo ?. hideInHierarchy ) {
235
+ result . push ( { className : "BisCore.Subject" , id : currParentId } ) ;
236
+ }
237
+ currParentId = parentInfo ?. parentSubject ;
238
+ }
239
+ return result . reverse ( ) ;
240
+ } ) ( ) ;
241
+ this . _subjectKeyPaths . set ( targetSubjectId , entry ) ;
232
242
}
233
- return result . reverse ( ) ;
243
+ return entry ;
234
244
}
235
245
236
246
private async * queryModelElementCounts ( ) {
@@ -297,15 +307,24 @@ export class ModelsTreeIdsCache {
297
307
return modelInfos . get ( modelId ) ?. elementCount ?? 0 ;
298
308
}
299
309
300
- public async getModelSubjects ( modelId : Id64String ) : Promise < Id64Array > {
301
- const result = new Array < Id64String > ( ) ;
302
- const subjectInfos = await this . getSubjectInfos ( ) ;
303
- subjectInfos . forEach ( ( subjectInfo , subjectId ) => {
304
- if ( subjectInfo . childModels . has ( modelId ) ) {
305
- result . push ( subjectId ) ;
306
- }
307
- } ) ;
308
- return result ;
310
+ public async createModelInstanceKeyPaths ( modelId : Id64String ) : Promise < HierarchyNodeIdentifiersPath [ ] > {
311
+ let entry = this . _modelKeyPaths . get ( modelId ) ;
312
+ if ( ! entry ) {
313
+ entry = ( async ( ) => {
314
+ const result = new Array < HierarchyNodeIdentifiersPath > ( ) ;
315
+ const subjectInfos = ( await this . getSubjectInfos ( ) ) . entries ( ) ;
316
+ for ( const [ modelSubjectId , subjectInfo ] of subjectInfos ) {
317
+ if ( subjectInfo . childModels . has ( modelId ) ) {
318
+ const subjectPath = await this . createSubjectInstanceKeysPath ( modelSubjectId ) ;
319
+ result . push ( [ ...subjectPath , { className : "BisCore.GeometricModel3d" , id : modelId } ] ) ;
320
+ }
321
+ }
322
+ return result ;
323
+ } ) ( ) ;
324
+
325
+ this . _modelKeyPaths . set ( modelId , entry ) ;
326
+ }
327
+ return entry ;
309
328
}
310
329
311
330
private async queryCategoryElementCounts (
@@ -352,15 +371,30 @@ export class ModelsTreeIdsCache {
352
371
return this . _categoryElementCounts . getCategoryElementsCount ( modelId , categoryId ) ;
353
372
}
354
373
355
- public async getCategoryModels ( categoryId : Id64String ) : Promise < Id64Array > {
356
- const result = new Set < Id64String > ( ) ;
357
- const modelInfos = await this . getModelInfos ( ) ;
358
- modelInfos ?. forEach ( ( modelInfo , modelId ) => {
359
- if ( modelInfo . categories . has ( categoryId ) ) {
360
- result . add ( modelId ) ;
361
- }
362
- } ) ;
363
- return [ ...result ] ;
374
+ public async createCategoryInstanceKeyPaths ( categoryId : Id64String ) : Promise < HierarchyNodeIdentifiersPath [ ] > {
375
+ let entry = this . _categoryKeyPaths . get ( categoryId ) ;
376
+ if ( ! entry ) {
377
+ entry = ( async ( ) => {
378
+ const result = new Set < Id64String > ( ) ;
379
+ const modelInfos = await this . getModelInfos ( ) ;
380
+ modelInfos ?. forEach ( ( modelInfo , modelId ) => {
381
+ if ( modelInfo . categories . has ( categoryId ) ) {
382
+ result . add ( modelId ) ;
383
+ }
384
+ } ) ;
385
+
386
+ const categoryPaths = new Array < HierarchyNodeIdentifiersPath > ( ) ;
387
+ for ( const categoryModelId of [ ...result ] ) {
388
+ const modelPaths = await this . createModelInstanceKeyPaths ( categoryModelId ) ;
389
+ for ( const modelPath of modelPaths ) {
390
+ categoryPaths . push ( [ ...modelPath , { className : "BisCore.SpatialCategory" , id : categoryId } ] ) ;
391
+ }
392
+ }
393
+ return categoryPaths ;
394
+ } ) ( ) ;
395
+ this . _categoryKeyPaths . set ( categoryId , entry ) ;
396
+ }
397
+ return entry ;
364
398
}
365
399
}
366
400
0 commit comments