/
NodeCollectionDeserializer.ts
161 lines (143 loc) · 6.26 KB
/
NodeCollectionDeserializer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*!
* Copyright 2021 Cognite AS
*/
import * as THREE from 'three';
import assert from 'assert';
import { CogniteClient } from '@cognite/sdk';
import { NumericRange, IndexSet } from '@reveal/utilities';
import { AssetNodeCollection } from './AssetNodeCollection';
import { PropertyFilterNodeCollection } from './PropertyFilterNodeCollection';
import { InvertedNodeCollection } from './InvertedNodeCollection';
import { SinglePropertyFilterNodeCollection } from './SinglePropertyFilterNodeCollection';
import { CdfModelNodeCollectionDataProvider } from './CdfModelNodeCollectionDataProvider';
import { TreeIndexNodeCollection } from './TreeIndexNodeCollection';
import { IntersectionNodeCollection } from './IntersectionNodeCollection';
import { UnionNodeCollection } from './UnionNodeCollection';
import { NodeCollection } from './NodeCollection';
import { SerializedNodeCollection } from './SerializedNodeCollection';
export type NodeCollectionSerializationContext = { client: CogniteClient; model: CdfModelNodeCollectionDataProvider };
export class NodeCollectionDeserializer {
public static readonly Instance = new NodeCollectionDeserializer();
private readonly _types = new Map<
string,
{
deserializer: (
state: SerializedNodeCollection,
context: NodeCollectionSerializationContext
) => Promise<NodeCollection>;
}
>();
private constructor() {
this._types = new Map();
this.registerWellKnownNodeCollectionTypes();
}
registerNodeCollectionType<T extends NodeCollection>(
nodeCollectionTypeName: string,
deserializer: (descriptor: SerializedNodeCollection, context: NodeCollectionSerializationContext) => Promise<T>
): void {
this._types.set(nodeCollectionTypeName, {
deserializer: (descriptor: SerializedNodeCollection, context: NodeCollectionSerializationContext) =>
deserializer(descriptor, context) as Promise<T>
});
}
async deserialize(
// TODO 2021-10-01 larsmoa: Avoid forcing node collections to rely on CogniteClient
// to support more generic deployment scenarios.
client: CogniteClient,
model: CdfModelNodeCollectionDataProvider,
descriptor: SerializedNodeCollection
): Promise<NodeCollection> {
const context: NodeCollectionSerializationContext = { client, model };
const deserializer = this.getDeserializer(descriptor.token);
return deserializer(descriptor, context);
}
private getDeserializer(typeName: string) {
const entry = this._types.get(typeName);
assert(entry !== undefined);
return entry!.deserializer;
}
private registerWellKnownNodeCollectionTypes() {
this.registerNodeCollectionType<AssetNodeCollection>(
AssetNodeCollection.classToken,
async (descriptor, context) => {
const nodeCollection = new AssetNodeCollection(context.client, context.model);
await nodeCollection.executeFilter(descriptor.state);
return nodeCollection;
}
);
this.registerNodeCollectionType<PropertyFilterNodeCollection>(
PropertyFilterNodeCollection.classToken,
async (descriptor, context) => {
const nodeCollection = new PropertyFilterNodeCollection(context.client, context.model, descriptor.options);
await nodeCollection.executeFilter(descriptor.state);
return nodeCollection;
}
);
this.registerNodeCollectionType<SinglePropertyFilterNodeCollection>(
SinglePropertyFilterNodeCollection.classToken,
async (descriptor, context) => {
const nodeCollection = new SinglePropertyFilterNodeCollection(
context.client,
context.model,
descriptor.options
);
const { propertyCategory, propertyKey, propertyValues } = descriptor.state;
await nodeCollection.executeFilter(propertyCategory, propertyKey, propertyValues);
return nodeCollection;
}
);
this.registerNodeCollectionType<TreeIndexNodeCollection>(TreeIndexNodeCollection.classToken, descriptor => {
const indexSet = new IndexSet();
descriptor.state.forEach((range: NumericRange) => indexSet.addRange(new NumericRange(range.from, range.count)));
const nodeCollection = new TreeIndexNodeCollection(indexSet);
if (descriptor.options?.areas !== undefined) {
const areas = descriptor.options?.areas as {
min: { x: number; y: number; z: number };
max: { x: number; y: number; z: number };
}[];
const areaBoxes = areas.map(area => {
const min = new THREE.Vector3(area.min.x, area.min.y, area.min.z);
const max = new THREE.Vector3(area.max.x, area.max.y, area.max.z);
return new THREE.Box3(min, max);
});
nodeCollection.addAreas(areaBoxes);
}
return Promise.resolve(nodeCollection);
});
this.registerNodeCollectionType<IntersectionNodeCollection>(
IntersectionNodeCollection.classToken,
async (descriptor, context) => {
const subCollections: NodeCollection[] = await Promise.all(
descriptor.state.subCollections.map((subSet: any) => {
return this.deserialize(context.client, context.model, subSet);
})
);
return new IntersectionNodeCollection(subCollections);
}
);
this.registerNodeCollectionType<UnionNodeCollection>(
UnionNodeCollection.classToken,
async (descriptor, context) => {
const subCollections: NodeCollection[] = await Promise.all(
descriptor.state.subCollections.map((subSet: any) => {
return this.deserialize(context.client, context.model, subSet);
})
);
return new UnionNodeCollection(subCollections);
}
);
this.registerNodeCollectionType<InvertedNodeCollection>(
InvertedNodeCollection.classToken,
async (descriptor, context) => {
const innerCollection = await this.deserialize(context.client, context.model, descriptor.state.innerSet);
return new InvertedNodeCollection(context.model, innerCollection);
}
);
}
}
export function registerNodeCollectionType<T extends NodeCollection>(
nodeCollectionTypeName: string,
deserializer: (descriptor: SerializedNodeCollection, context: NodeCollectionSerializationContext) => Promise<T>
): void {
NodeCollectionDeserializer.Instance.registerNodeCollectionType(nodeCollectionTypeName, deserializer);
}