@shapediver/viewer.session-engine.session-engine 2.10.1-rc.0 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/implementation/OutputDelayException.js +5 -1
- package/dist/implementation/OutputDelayException.js.map +1 -1
- package/dist/implementation/OutputLoader.d.ts +4 -1
- package/dist/implementation/OutputLoader.d.ts.map +1 -1
- package/dist/implementation/OutputLoader.js +41 -30
- package/dist/implementation/OutputLoader.js.map +1 -1
- package/dist/implementation/SessionData.js +6 -2
- package/dist/implementation/SessionData.js.map +1 -1
- package/dist/implementation/SessionEngine.d.ts +22 -12
- package/dist/implementation/SessionEngine.d.ts.map +1 -1
- package/dist/implementation/SessionEngine.js +442 -301
- package/dist/implementation/SessionEngine.js.map +1 -1
- package/dist/implementation/SessionOutputData.js +6 -2
- package/dist/implementation/SessionOutputData.js.map +1 -1
- package/dist/implementation/SessionTreeNode.js +6 -2
- package/dist/implementation/SessionTreeNode.js.map +1 -1
- package/dist/implementation/dto/Export.js +17 -13
- package/dist/implementation/dto/Export.js.map +1 -1
- package/dist/implementation/dto/FileParameter.js +34 -7
- package/dist/implementation/dto/FileParameter.js.map +1 -1
- package/dist/implementation/dto/Output.d.ts +6 -6
- package/dist/implementation/dto/Output.d.ts.map +1 -1
- package/dist/implementation/dto/Output.js +21 -14
- package/dist/implementation/dto/Output.js.map +1 -1
- package/dist/implementation/dto/Parameter.js +60 -33
- package/dist/implementation/dto/Parameter.js.map +1 -1
- package/dist/index.js +20 -11
- package/dist/index.js.map +1 -1
- package/dist/interfaces/ISessionData.js +2 -1
- package/dist/interfaces/ISessionEngine.d.ts +12 -8
- package/dist/interfaces/ISessionEngine.d.ts.map +1 -1
- package/dist/interfaces/ISessionEngine.js +7 -5
- package/dist/interfaces/ISessionEngine.js.map +1 -1
- package/dist/interfaces/ISessionOutputData.js +2 -1
- package/dist/interfaces/ISessionTreeNode.js +2 -1
- package/dist/interfaces/dto/IExport.js +2 -1
- package/dist/interfaces/dto/IFileParameter.js +2 -1
- package/dist/interfaces/dto/IOutput.d.ts +1 -1
- package/dist/interfaces/dto/IOutput.d.ts.map +1 -1
- package/dist/interfaces/dto/IOutput.js +2 -1
- package/dist/interfaces/dto/IParameter.js +2 -1
- package/package.json +9 -9
- package/src/implementation/OutputLoader.ts +16 -5
- package/src/implementation/SessionEngine.ts +682 -500
- package/src/implementation/dto/Output.ts +16 -15
- package/src/interfaces/ISessionEngine.ts +51 -44
- package/src/interfaces/dto/IOutput.ts +1 -1
|
@@ -1,24 +1,65 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
import {
|
|
2
|
+
convert,
|
|
3
|
+
ISettings,
|
|
4
|
+
latestVersion,
|
|
5
|
+
validate,
|
|
6
|
+
versions
|
|
7
|
+
} from '@shapediver/viewer.settings';
|
|
8
|
+
import {
|
|
9
|
+
create,
|
|
10
|
+
isGBResponseError,
|
|
11
|
+
ShapeDiverError as ShapeDiverBackendError,
|
|
12
|
+
ShapeDiverRequestConfigure,
|
|
13
|
+
ShapeDiverRequestCustomization,
|
|
14
|
+
ShapeDiverRequestExport,
|
|
15
|
+
ShapeDiverRequestGltfUploadQueryConversion,
|
|
16
|
+
ShapeDiverResponseDto,
|
|
17
|
+
ShapeDiverResponseErrorType,
|
|
18
|
+
ShapeDiverResponseExport,
|
|
19
|
+
ShapeDiverResponseExportDefinitionType,
|
|
20
|
+
ShapeDiverResponseModelComputationStatus,
|
|
21
|
+
ShapeDiverResponseOutput,
|
|
22
|
+
ShapeDiverSdk,
|
|
23
|
+
ShapeDiverSdkConfigType
|
|
24
|
+
} from '@shapediver/sdk.geometry-api-sdk-v2';
|
|
25
|
+
import {
|
|
26
|
+
EventEngine,
|
|
27
|
+
EVENTTYPE,
|
|
28
|
+
HttpClient,
|
|
29
|
+
HttpResponse,
|
|
30
|
+
Logger,
|
|
31
|
+
PerformanceEvaluator,
|
|
32
|
+
SettingsEngine,
|
|
33
|
+
ShapeDiverViewerError,
|
|
34
|
+
ShapeDiverViewerSessionError,
|
|
35
|
+
ShapeDiverViewerSettingsError,
|
|
36
|
+
StateEngine,
|
|
37
|
+
SystemInfo,
|
|
38
|
+
UuidGenerator
|
|
39
|
+
} from '@shapediver/viewer.shared.services';
|
|
40
|
+
import { Export } from './dto/Export';
|
|
41
|
+
import { FileParameter } from './dto/FileParameter';
|
|
42
|
+
import { IExport } from '../interfaces/dto/IExport';
|
|
43
|
+
import { IFileParameter } from '../interfaces/dto/IFileParameter';
|
|
44
|
+
import { IOutput } from '../interfaces/dto/IOutput';
|
|
45
|
+
import { IParameter } from '../interfaces/dto/IParameter';
|
|
46
|
+
import { ISessionEngine, ISettingsSections, PARAMETER_TYPE } from '../interfaces/ISessionEngine';
|
|
47
|
+
import { ISessionTreeNode } from '../interfaces/ISessionTreeNode';
|
|
48
|
+
import { IOutputEvent, ITaskEvent, TASK_TYPE } from '@shapediver/viewer.shared.types';
|
|
49
|
+
import {
|
|
50
|
+
ITree,
|
|
51
|
+
ITreeNode,
|
|
52
|
+
Tree,
|
|
53
|
+
TreeNode
|
|
54
|
+
} from '@shapediver/viewer.shared.node-tree';
|
|
55
|
+
import { Output } from './dto/Output';
|
|
56
|
+
import { OutputDelayException } from './OutputDelayException';
|
|
57
|
+
import { OutputLoader, OutputLoaderTaskEventInfo } from './OutputLoader';
|
|
58
|
+
import { Parameter } from './dto/Parameter';
|
|
59
|
+
import { SessionData } from './SessionData';
|
|
60
|
+
import { SessionTreeNode } from './SessionTreeNode';
|
|
61
|
+
import { vec3 } from 'gl-matrix';
|
|
62
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
22
63
|
|
|
23
64
|
export class SessionEngine implements ISessionEngine {
|
|
24
65
|
// #region Properties (43)
|
|
@@ -34,7 +75,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
34
75
|
private readonly _outputs: { [key: string]: IOutput; } = {};
|
|
35
76
|
private readonly _outputsFreeze: { [key: string]: boolean; } = {};
|
|
36
77
|
private readonly _parameterValues: { [key: string]: string; } = {};
|
|
37
|
-
private readonly _parameters: { [key: string]: IParameter<
|
|
78
|
+
private readonly _parameters: { [key: string]: IParameter<unknown>; } = {};
|
|
38
79
|
private readonly _performanceEvaluator = PerformanceEvaluator.instance;
|
|
39
80
|
private readonly _sceneTree: ITree = Tree.instance;
|
|
40
81
|
private readonly _sessionEngineId = (UuidGenerator.instance).create();
|
|
@@ -43,17 +84,17 @@ export class SessionEngine implements ISessionEngine {
|
|
|
43
84
|
private readonly _ticket?: string;
|
|
44
85
|
private readonly _uuidGenerator = UuidGenerator.instance;
|
|
45
86
|
|
|
46
|
-
#customizationProcess
|
|
87
|
+
#customizationProcess?: string;
|
|
47
88
|
#parameterHistory: {
|
|
48
89
|
[key: string]: {
|
|
49
|
-
value:
|
|
90
|
+
value: unknown,
|
|
50
91
|
valueString: string
|
|
51
92
|
}
|
|
52
93
|
}[] = [];
|
|
53
94
|
#parameterHistoryCall = false;
|
|
54
95
|
#parameterHistoryForward: {
|
|
55
96
|
[key: string]: {
|
|
56
|
-
value:
|
|
97
|
+
value: unknown,
|
|
57
98
|
valueString: string
|
|
58
99
|
}
|
|
59
100
|
}[] = [];
|
|
@@ -62,14 +103,14 @@ export class SessionEngine implements ISessionEngine {
|
|
|
62
103
|
private _closed: boolean = false;
|
|
63
104
|
private _customizeOnParameterChange: boolean = false;
|
|
64
105
|
private _dataCache: {
|
|
65
|
-
[key: string]: Promise<HttpResponse<
|
|
106
|
+
[key: string]: Promise<HttpResponse<unknown>>
|
|
66
107
|
} = {};
|
|
67
108
|
private _excludeViewports: string[] = [];
|
|
68
109
|
private _headers = {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
110
|
+
'X-ShapeDiver-Origin': (SystemInfo.instance).origin,
|
|
111
|
+
'X-ShapeDiver-SessionEngineId': this._sessionEngineId,
|
|
112
|
+
'X-ShapeDiver-BuildVersion': '',
|
|
113
|
+
'X-ShapeDiver-BuildDate': ''
|
|
73
114
|
};
|
|
74
115
|
private _initialized: boolean = false;
|
|
75
116
|
private _jwtToken?: string;
|
|
@@ -115,7 +156,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
115
156
|
|
|
116
157
|
// #endregion Constructors (1)
|
|
117
158
|
|
|
118
|
-
// #region Public Accessors (
|
|
159
|
+
// #region Public Accessors (25)
|
|
119
160
|
|
|
120
161
|
public get automaticSceneUpdate(): boolean {
|
|
121
162
|
return this._automaticSceneUpdate;
|
|
@@ -192,7 +233,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
192
233
|
return this._parameterValues;
|
|
193
234
|
}
|
|
194
235
|
|
|
195
|
-
public get parameters(): { [key: string]: IParameter<
|
|
236
|
+
public get parameters(): { [key: string]: IParameter<unknown>; } {
|
|
196
237
|
return this._parameters;
|
|
197
238
|
}
|
|
198
239
|
|
|
@@ -213,149 +254,149 @@ export class SessionEngine implements ISessionEngine {
|
|
|
213
254
|
}
|
|
214
255
|
|
|
215
256
|
public get updateCallback(): ((newNode: ITreeNode, oldNode: ITreeNode) => void) | null {
|
|
216
|
-
|
|
257
|
+
return this._updateCallback;
|
|
217
258
|
}
|
|
218
259
|
|
|
219
260
|
public set updateCallback(value: ((newNode: ITreeNode, oldNode: ITreeNode) => void) | null) {
|
|
220
|
-
|
|
261
|
+
this._updateCallback = value;
|
|
221
262
|
}
|
|
222
263
|
|
|
223
264
|
public get viewerSettings(): object | undefined {
|
|
224
265
|
return this._viewerSettings;
|
|
225
266
|
}
|
|
226
267
|
|
|
227
|
-
// #endregion Public Accessors (
|
|
268
|
+
// #endregion Public Accessors (25)
|
|
228
269
|
|
|
229
|
-
// #region Public Methods (
|
|
270
|
+
// #region Public Methods (27)
|
|
230
271
|
|
|
231
272
|
public applySettings(response: ShapeDiverResponseDto, sections?: ISettingsSections) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
273
|
+
sections = sections || {};
|
|
274
|
+
if (sections.session === undefined) {
|
|
275
|
+
sections.session = {
|
|
276
|
+
parameter: { displayname: false, order: false, hidden: false },
|
|
277
|
+
export: { displayname: false, order: false, hidden: false }
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
if (sections.session.parameter === undefined)
|
|
281
|
+
sections.session.parameter = { displayname: false, order: false, hidden: false, value: false };
|
|
282
|
+
if (sections.session.export === undefined)
|
|
283
|
+
sections.session.export = { displayname: false, order: false, hidden: false };
|
|
284
|
+
if (sections.viewport === undefined)
|
|
285
|
+
sections.viewport = { ar: false, scene: false, camera: false, light: false, environment: false, general: false, postprocessing: false };
|
|
286
|
+
|
|
287
|
+
let config: object;
|
|
288
|
+
if ((<ShapeDiverResponseDto>response).viewer !== undefined) {
|
|
289
|
+
config = (<ShapeDiverResponseDto>response).viewer!.config;
|
|
290
|
+
} else {
|
|
291
|
+
throw new ShapeDiverViewerSettingsError('Session.applySettings: No config object available.');
|
|
292
|
+
}
|
|
252
293
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
294
|
+
try {
|
|
295
|
+
validate(config);
|
|
296
|
+
} catch (e) {
|
|
297
|
+
throw new ShapeDiverViewerSettingsError('Session.applySettings: Was not able to validate config object.');
|
|
298
|
+
}
|
|
258
299
|
|
|
259
|
-
|
|
300
|
+
const settings = <ISettings>convert(config, latestVersion);
|
|
260
301
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
302
|
+
const exportMappingUid: { [key: string]: string | undefined } = {};
|
|
303
|
+
if (sections.session.export.displayname || sections.session.export.order || sections.session.export.hidden)
|
|
304
|
+
if (response.exports)
|
|
305
|
+
for (const exportId in response.exports)
|
|
306
|
+
if (response.exports[exportId].uid !== undefined)
|
|
307
|
+
exportMappingUid[response.exports[exportId].uid!] = exportId;
|
|
267
308
|
|
|
268
|
-
|
|
309
|
+
const currentSettings = this._settingsEngine.settings;
|
|
269
310
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
311
|
+
// apply parameter settings
|
|
312
|
+
if (sections.session.parameter.displayname || sections.session.parameter.order || sections.session.parameter.hidden || sections.session.parameter.value) {
|
|
313
|
+
for (const p in this.parameters) {
|
|
314
|
+
if (settings.session[p]) {
|
|
315
|
+
if (sections.session.parameter.displayname) this.parameters[p].displayname = settings.session[p].displayname;
|
|
316
|
+
if (sections.session.parameter.order) this.parameters[p].order = settings.session[p].order;
|
|
317
|
+
if (sections.session.parameter.hidden) this.parameters[p].hidden = settings.session[p].hidden || false;
|
|
318
|
+
}
|
|
278
319
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
320
|
+
if (response.parameters && response.parameters[p] && !((this.parameters[p] instanceof FileParameter) || this.parameters[p].type.startsWith('s'))) {
|
|
321
|
+
if (sections.session.parameter.value) this.parameters[p].value = response.parameters[p].defval !== undefined ? response.parameters[p].defval : this.parameters[p].value;
|
|
282
322
|
}
|
|
283
323
|
}
|
|
324
|
+
}
|
|
284
325
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
326
|
+
// apply export settings
|
|
327
|
+
if (sections.session.export.displayname || sections.session.export.order || sections.session.export.hidden) {
|
|
328
|
+
for (const p in this.exports) {
|
|
329
|
+
let idForSettings = '';
|
|
330
|
+
if (settings.session[p]) {
|
|
331
|
+
idForSettings = p;
|
|
332
|
+
} else {
|
|
333
|
+
const uid = this.exports[p].uid;
|
|
334
|
+
if (!uid) continue;
|
|
335
|
+
if (!exportMappingUid[uid]) continue;
|
|
336
|
+
idForSettings = exportMappingUid[uid]!;
|
|
337
|
+
}
|
|
338
|
+
if (settings.session[idForSettings]) {
|
|
339
|
+
if (sections.session.export.displayname) this.exports[p].displayname = settings.session[idForSettings].displayname;
|
|
340
|
+
if (sections.session.export.order) this.exports[p].order = settings.session[idForSettings].order;
|
|
341
|
+
if (sections.session.export.hidden) this.exports[p].hidden = settings.session[idForSettings].hidden || false;
|
|
302
342
|
}
|
|
303
343
|
}
|
|
344
|
+
}
|
|
304
345
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
346
|
+
// apply ar settings
|
|
347
|
+
if (sections.viewport.ar) {
|
|
348
|
+
currentSettings.ar = settings.ar;
|
|
349
|
+
currentSettings.general.transformation = settings.general.transformation;
|
|
350
|
+
}
|
|
310
351
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
352
|
+
// apply camera settings
|
|
353
|
+
if (sections.viewport.camera)
|
|
354
|
+
currentSettings.camera = settings.camera;
|
|
355
|
+
|
|
356
|
+
// apply light settings
|
|
357
|
+
if (sections.viewport.light)
|
|
358
|
+
currentSettings.light = settings.light;
|
|
359
|
+
|
|
360
|
+
// apply scene settings
|
|
361
|
+
if (sections.viewport.scene) {
|
|
362
|
+
currentSettings.environmentGeometry.gridColor = settings.environmentGeometry.gridColor;
|
|
363
|
+
currentSettings.environmentGeometry.gridVisibility = settings.environmentGeometry.gridVisibility;
|
|
364
|
+
currentSettings.environmentGeometry.groundPlaneColor = settings.environmentGeometry.groundPlaneColor;
|
|
365
|
+
currentSettings.environmentGeometry.groundPlaneVisibility = settings.environmentGeometry.groundPlaneVisibility;
|
|
366
|
+
currentSettings.environmentGeometry.groundPlaneShadowColor = settings.environmentGeometry.groundPlaneShadowColor;
|
|
367
|
+
currentSettings.environmentGeometry.groundPlaneShadowVisibility = settings.environmentGeometry.groundPlaneShadowVisibility;
|
|
368
|
+
|
|
369
|
+
currentSettings.rendering.shadows = settings.rendering.shadows;
|
|
370
|
+
currentSettings.rendering.softShadows = settings.rendering.softShadows;
|
|
371
|
+
|
|
372
|
+
currentSettings.rendering.automaticColorAdjustment = settings.rendering.automaticColorAdjustment;
|
|
373
|
+
currentSettings.rendering.textureEncoding = settings.rendering.textureEncoding;
|
|
374
|
+
currentSettings.rendering.outputEncoding = settings.rendering.outputEncoding;
|
|
375
|
+
currentSettings.rendering.physicallyCorrectLights = settings.rendering.physicallyCorrectLights;
|
|
376
|
+
currentSettings.rendering.toneMapping = settings.rendering.toneMapping;
|
|
377
|
+
currentSettings.rendering.toneMappingExposure = settings.rendering.toneMappingExposure;
|
|
378
|
+
}
|
|
338
379
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
380
|
+
if (sections.viewport.general) {
|
|
381
|
+
currentSettings.general.defaultMaterialColor = settings.general.defaultMaterialColor;
|
|
382
|
+
currentSettings.general.commitParameters = settings.general.commitParameters;
|
|
383
|
+
currentSettings.general.pointSize = settings.general.pointSize;
|
|
384
|
+
}
|
|
344
385
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
386
|
+
// apply postprocessing settings
|
|
387
|
+
if (sections.viewport.postprocessing)
|
|
388
|
+
currentSettings.postprocessing = settings.postprocessing;
|
|
389
|
+
|
|
390
|
+
// apply environment settings
|
|
391
|
+
if (sections.viewport.environment) {
|
|
392
|
+
currentSettings.environment.clearAlpha = settings.environment.clearAlpha;
|
|
393
|
+
currentSettings.environment.clearColor = settings.environment.clearColor;
|
|
394
|
+
currentSettings.environment.map = settings.environment.map;
|
|
395
|
+
currentSettings.environment.mapAsBackground = settings.environment.mapAsBackground;
|
|
396
|
+
currentSettings.environment.rotation = settings.environment.rotation;
|
|
397
|
+
currentSettings.environment.blurriness = settings.environment.blurriness;
|
|
398
|
+
currentSettings.environment.intensity = settings.environment.intensity;
|
|
399
|
+
}
|
|
359
400
|
}
|
|
360
401
|
|
|
361
402
|
public canGoBack(): boolean {
|
|
@@ -368,11 +409,20 @@ export class SessionEngine implements ISessionEngine {
|
|
|
368
409
|
return this.#parameterHistoryForward.length > 0;
|
|
369
410
|
}
|
|
370
411
|
|
|
412
|
+
public cancelCustomization() {
|
|
413
|
+
if(this.#customizationProcess) {
|
|
414
|
+
for (const r in this._stateEngine.renderingEngines)
|
|
415
|
+
if (this._stateEngine.renderingEngines[r].busy.includes(this.#customizationProcess))
|
|
416
|
+
this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(this.#customizationProcess), 1);
|
|
417
|
+
}
|
|
418
|
+
this.#customizationProcess = undefined;
|
|
419
|
+
}
|
|
420
|
+
|
|
371
421
|
public async close(retry = false): Promise<void> {
|
|
372
422
|
this.checkAvailability('close');
|
|
373
423
|
|
|
374
424
|
try {
|
|
375
|
-
this._httpClient.removeDataLoading(this._sessionId!)
|
|
425
|
+
this._httpClient.removeDataLoading(this._sessionId!);
|
|
376
426
|
await this._sdk.session.close(this._sessionId!);
|
|
377
427
|
if (this._automaticSceneUpdate) this.removeFromSceneTree(this._node);
|
|
378
428
|
|
|
@@ -389,7 +439,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
389
439
|
* @param parameters the parameter set to update the session
|
|
390
440
|
* @returns promise with a scene graph node
|
|
391
441
|
*/
|
|
392
|
-
public async customize(force: boolean = false): Promise<ITreeNode> {
|
|
442
|
+
public async customize(force: boolean = false, waitForViewportUpdate: boolean = false): Promise<ITreeNode> {
|
|
393
443
|
const eventId = this._uuidGenerator.create();
|
|
394
444
|
const customizationId = this._uuidGenerator.create();
|
|
395
445
|
try {
|
|
@@ -399,7 +449,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
399
449
|
for (const parameterId in this.parameters)
|
|
400
450
|
if (this.parameters[parameterId].sessionValue !== this.parameters[parameterId].value)
|
|
401
451
|
changes = true;
|
|
402
|
-
if(changes === false)
|
|
452
|
+
if (changes === false)
|
|
403
453
|
return this.node;
|
|
404
454
|
}
|
|
405
455
|
|
|
@@ -411,65 +461,28 @@ export class SessionEngine implements ISessionEngine {
|
|
|
411
461
|
|
|
412
462
|
this._logger.debugLow(`Session(${this.id}).customize: Customizing session.`);
|
|
413
463
|
|
|
414
|
-
for (
|
|
415
|
-
if(!this.excludeViewports.includes(r))
|
|
464
|
+
for (const r in this._stateEngine.renderingEngines)
|
|
465
|
+
if (!this.excludeViewports.includes(r))
|
|
416
466
|
this._stateEngine.renderingEngines[r].busy.push(customizationId);
|
|
417
467
|
|
|
418
468
|
const eventFileUpload: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 0.1, data: { sessionId: this.id }, status: 'Uploading file parameters' };
|
|
419
469
|
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_PROCESS, eventFileUpload);
|
|
420
470
|
|
|
421
|
-
const fileParameterIds: { [key: string]: string } = {}
|
|
471
|
+
const fileParameterIds: { [key: string]: string } = {};
|
|
422
472
|
// load file parameter first
|
|
423
473
|
for (const parameterId in this.parameters) {
|
|
424
474
|
if (this.parameters[parameterId] instanceof FileParameter) {
|
|
425
475
|
fileParameterIds[parameterId] = await (<IFileParameter>this.parameters[parameterId]).upload();
|
|
426
476
|
|
|
427
477
|
// OPTION TO SKIP - PART 1a
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
|
|
431
|
-
this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
|
|
432
|
-
|
|
433
|
-
this._logger.debug(`Session(${this.id}).customize: Session customization was exceeded by other customization request.`);
|
|
434
|
-
|
|
435
|
-
const eventCancel1a: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session customization was exceeded by other customization request' };
|
|
436
|
-
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_CANCEL, eventCancel1a);
|
|
437
|
-
return new SessionTreeNode();
|
|
438
|
-
} else if (this._closed === true) {
|
|
439
|
-
for (let r in this._stateEngine.renderingEngines)
|
|
440
|
-
if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
|
|
441
|
-
this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
|
|
442
|
-
|
|
443
|
-
this._logger.debug(`Session(${this.id}).customize: Session was closed during customization request.`);
|
|
444
|
-
|
|
445
|
-
const eventCancel1a: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session was closed during customization request' };
|
|
446
|
-
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_CANCEL, eventCancel1a);
|
|
447
|
-
return new SessionTreeNode();
|
|
448
|
-
}
|
|
478
|
+
const cancelResult = this.cancelProcess(customizationId, eventId, TASK_TYPE.SESSION_CUSTOMIZATION, 1, { sessionId: this.id });
|
|
479
|
+
if (cancelResult) return cancelResult;
|
|
449
480
|
}
|
|
450
481
|
}
|
|
451
482
|
|
|
452
483
|
// OPTION TO SKIP - PART 1b
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
|
|
456
|
-
this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
|
|
457
|
-
|
|
458
|
-
const eventCancel1b: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session customization was exceeded by other customization request' };
|
|
459
|
-
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_CANCEL, eventCancel1b);
|
|
460
|
-
this._logger.debug(`Session(${this.id}).customize: Session customization was exceeded by other customization request.`);
|
|
461
|
-
return new SessionTreeNode();
|
|
462
|
-
} else if (this._closed === true) {
|
|
463
|
-
for (let r in this._stateEngine.renderingEngines)
|
|
464
|
-
if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
|
|
465
|
-
this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
|
|
466
|
-
|
|
467
|
-
this._logger.debug(`Session(${this.id}).customize: Session was closed during customization request.`);
|
|
468
|
-
|
|
469
|
-
const eventCancel1b: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session was closed during customization request' };
|
|
470
|
-
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_CANCEL, eventCancel1b);
|
|
471
|
-
return new SessionTreeNode();
|
|
472
|
-
}
|
|
484
|
+
const cancelResult = this.cancelProcess(customizationId, eventId, TASK_TYPE.SESSION_CUSTOMIZATION, 1, { sessionId: this.id });
|
|
485
|
+
if (cancelResult) return cancelResult;
|
|
473
486
|
|
|
474
487
|
// assign the uploaded parameters
|
|
475
488
|
for (const parameterId in fileParameterIds)
|
|
@@ -477,7 +490,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
477
490
|
|
|
478
491
|
const parameterSet: {
|
|
479
492
|
[key: string]: {
|
|
480
|
-
value:
|
|
493
|
+
value: unknown,
|
|
481
494
|
valueString: string
|
|
482
495
|
}
|
|
483
496
|
} = {};
|
|
@@ -487,7 +500,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
487
500
|
parameterSet[parameterId] = {
|
|
488
501
|
value: this.parameters[parameterId].value,
|
|
489
502
|
valueString: this.parameters[parameterId].stringify()
|
|
490
|
-
}
|
|
503
|
+
};
|
|
491
504
|
}
|
|
492
505
|
|
|
493
506
|
// update the session engine parameter values if everything succeeded
|
|
@@ -498,6 +511,8 @@ export class SessionEngine implements ISessionEngine {
|
|
|
498
511
|
const eventRequest: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 0.1, data: { sessionId: this.id }, status: 'Sending customization request' };
|
|
499
512
|
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_PROCESS, eventRequest);
|
|
500
513
|
|
|
514
|
+
const oldOutputVersions = this._outputLoader.getCurrentOutputVersions();
|
|
515
|
+
|
|
501
516
|
const newNode = await this.customizeInternal(() => this.#customizationProcess !== customizationId, {
|
|
502
517
|
eventId,
|
|
503
518
|
type: TASK_TYPE.SESSION_CUSTOMIZATION,
|
|
@@ -508,29 +523,32 @@ export class SessionEngine implements ISessionEngine {
|
|
|
508
523
|
data: { sessionId: this.id }
|
|
509
524
|
});
|
|
510
525
|
|
|
526
|
+
// OPTION TO SKIP - PART 2
|
|
527
|
+
const cancelResult2 = this.cancelProcess(customizationId, eventId, TASK_TYPE.SESSION_CUSTOMIZATION, 1, { sessionId: this.id });
|
|
528
|
+
if (cancelResult2) return cancelResult2;
|
|
529
|
+
|
|
530
|
+
const newOutputVersions = this._outputLoader.getCurrentOutputVersions();
|
|
531
|
+
|
|
511
532
|
const eventSceneUpdate: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 0.9, data: { sessionId: this.id }, status: 'Updating scene' };
|
|
512
533
|
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_PROCESS, eventSceneUpdate);
|
|
513
534
|
|
|
514
|
-
//
|
|
515
|
-
if (
|
|
516
|
-
for (
|
|
517
|
-
if (
|
|
518
|
-
this.
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
this.
|
|
530
|
-
|
|
531
|
-
const eventCancel2: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session was closed during customization request' };
|
|
532
|
-
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_CANCEL, eventCancel2);
|
|
533
|
-
return new SessionTreeNode();
|
|
535
|
+
// call the update callbacks
|
|
536
|
+
if (waitForViewportUpdate === false) {
|
|
537
|
+
for (const outputId in this.outputs) {
|
|
538
|
+
if (oldOutputVersions[outputId] !== newOutputVersions[outputId]) {
|
|
539
|
+
this._eventEngine.emitEvent(EVENTTYPE.OUTPUT.OUTPUT_UPDATED, <IOutputEvent>{
|
|
540
|
+
outputId: outputId,
|
|
541
|
+
outputVersion: newOutputVersions[outputId],
|
|
542
|
+
newNode: newNode.children.find(c => c.name === outputId)!,
|
|
543
|
+
oldNode: oldNode.children.find(c => c.name === outputId)!
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
await this.waitForUpdateCallbacks(newOutputVersions, oldOutputVersions, newNode, oldNode);
|
|
549
|
+
|
|
550
|
+
const cancelResult = this.cancelProcess(customizationId, eventId, TASK_TYPE.SESSION_CUSTOMIZATION, 1, { sessionId: this.id });
|
|
551
|
+
if (cancelResult) return cancelResult;
|
|
534
552
|
}
|
|
535
553
|
|
|
536
554
|
// if this is not a call by the goBack or goForward functions, add the parameter values to the history and delete the forward history
|
|
@@ -547,8 +565,8 @@ export class SessionEngine implements ISessionEngine {
|
|
|
547
565
|
|
|
548
566
|
// set the session values to the current ones in all parameters
|
|
549
567
|
for (const parameterId in this.parameters)
|
|
550
|
-
(<
|
|
551
|
-
|
|
568
|
+
(<unknown>this.parameters[parameterId].sessionValue) = parameterSet[parameterId].value;
|
|
569
|
+
|
|
552
570
|
// set the output content to what has been updated
|
|
553
571
|
for (const outputId in this.outputs)
|
|
554
572
|
this.outputs[outputId].updateOutput(
|
|
@@ -564,7 +582,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
564
582
|
|
|
565
583
|
this.node.excludeViewports = JSON.parse(JSON.stringify(this._excludeViewports));
|
|
566
584
|
|
|
567
|
-
for (
|
|
585
|
+
for (const r in this._stateEngine.renderingEngines)
|
|
568
586
|
if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
|
|
569
587
|
this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
|
|
570
588
|
|
|
@@ -576,26 +594,44 @@ export class SessionEngine implements ISessionEngine {
|
|
|
576
594
|
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_END, eventEnd);
|
|
577
595
|
|
|
578
596
|
// update the viewports
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
this._stateEngine.renderingEngines[r].
|
|
597
|
+
if (waitForViewportUpdate) {
|
|
598
|
+
for (const r in this._stateEngine.renderingEngines)
|
|
599
|
+
if (!this.excludeViewports.includes(this._stateEngine.renderingEngines[r].id))
|
|
600
|
+
this._stateEngine.renderingEngines[r].update(`SessionEngine(${this.id}).customize`);
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
for (const outputId in this.outputs) {
|
|
604
|
+
if (oldOutputVersions[outputId] !== newOutputVersions[outputId]) {
|
|
605
|
+
this._eventEngine.emitEvent(EVENTTYPE.OUTPUT.OUTPUT_UPDATED, <IOutputEvent>{
|
|
606
|
+
outputId: outputId,
|
|
607
|
+
outputVersion: newOutputVersions[outputId],
|
|
608
|
+
newNode: newNode.children.find(c => c.name === outputId)!,
|
|
609
|
+
oldNode: oldNode.children.find(c => c.name === outputId)!
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
}
|
|
582
613
|
|
|
583
|
-
|
|
584
|
-
|
|
614
|
+
// call the update callbacks
|
|
615
|
+
await this.waitForUpdateCallbacks(newOutputVersions, oldOutputVersions, newNode, oldNode);
|
|
585
616
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
)
|
|
617
|
+
const cancelResult = this.cancelProcess(customizationId, eventId, TASK_TYPE.SESSION_CUSTOMIZATION, 1, { sessionId: this.id });
|
|
618
|
+
if (cancelResult) return cancelResult;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
if (!waitForViewportUpdate) {
|
|
622
|
+
setTimeout(() => {
|
|
623
|
+
for (const r in this._stateEngine.renderingEngines)
|
|
624
|
+
if (!this.excludeViewports.includes(this._stateEngine.renderingEngines[r].id))
|
|
625
|
+
this._stateEngine.renderingEngines[r].update(`SessionEngine(${this.id}).customize`);
|
|
626
|
+
}, 0);
|
|
627
|
+
}
|
|
592
628
|
|
|
593
629
|
return this.node;
|
|
594
630
|
} catch (e) {
|
|
595
631
|
const eventCancel: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session customization failed' };
|
|
596
632
|
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_CANCEL, eventCancel);
|
|
597
633
|
|
|
598
|
-
for (
|
|
634
|
+
for (const r in this._stateEngine.renderingEngines)
|
|
599
635
|
if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
|
|
600
636
|
this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
|
|
601
637
|
|
|
@@ -603,34 +639,36 @@ export class SessionEngine implements ISessionEngine {
|
|
|
603
639
|
}
|
|
604
640
|
}
|
|
605
641
|
|
|
606
|
-
public async customizeParallel(parameterValues: { [key: string]: string }): Promise<
|
|
607
|
-
|
|
642
|
+
public async customizeParallel(parameterValues: { [key: string]: string }, loadOutputs = true): Promise<ISessionTreeNode | ShapeDiverResponseDto> {
|
|
643
|
+
const eventId = this._uuidGenerator.create();
|
|
608
644
|
|
|
609
|
-
|
|
610
|
-
|
|
645
|
+
const eventStart: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 0, data: { sessionId: this.id }, status: 'Customizing session' };
|
|
646
|
+
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_START, eventStart);
|
|
611
647
|
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
648
|
+
const parameterSet: {
|
|
649
|
+
[key: string]: string
|
|
650
|
+
} = {};
|
|
615
651
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
652
|
+
// create a set of the current validated parameter values
|
|
653
|
+
for (const parameterId in this.parameters)
|
|
654
|
+
parameterSet[parameterId] = parameterValues[parameterId] !== undefined ? (' ' + parameterValues[parameterId]).slice(1) : this.parameters[parameterId].stringify();
|
|
619
655
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
656
|
+
const result = await this.customizeSession(parameterSet, () => false, {
|
|
657
|
+
eventId,
|
|
658
|
+
type: TASK_TYPE.SESSION_CUSTOMIZATION,
|
|
659
|
+
progressRange: {
|
|
660
|
+
min: 0.0,
|
|
661
|
+
max: 1
|
|
662
|
+
},
|
|
663
|
+
data: { sessionId: this.id }
|
|
664
|
+
}, true, loadOutputs);
|
|
665
|
+
|
|
666
|
+
if (result instanceof SessionTreeNode)
|
|
667
|
+
result.excludeViewports = JSON.parse(JSON.stringify(this._excludeViewports));
|
|
668
|
+
|
|
669
|
+
const eventEnd: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session customized' };
|
|
670
|
+
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_END, eventEnd);
|
|
671
|
+
return result;
|
|
634
672
|
}
|
|
635
673
|
|
|
636
674
|
public async goBack(): Promise<ITreeNode> {
|
|
@@ -684,7 +722,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
684
722
|
public async init(parameterValues?: {
|
|
685
723
|
[key: string]: string;
|
|
686
724
|
}, retry = false): Promise<void> {
|
|
687
|
-
if (this._initialized === true)
|
|
725
|
+
if (this._initialized === true)
|
|
688
726
|
throw new ShapeDiverViewerSessionError('Session.init: Session already initialized.');
|
|
689
727
|
|
|
690
728
|
try {
|
|
@@ -695,13 +733,13 @@ export class SessionEngine implements ISessionEngine {
|
|
|
695
733
|
for (const parameterNameOrId in parameterValues)
|
|
696
734
|
parameterSet[parameterNameOrId] = (' ' + parameterValues[parameterNameOrId]).slice(1);
|
|
697
735
|
|
|
698
|
-
if(this._ticket) {
|
|
736
|
+
if (this._ticket) {
|
|
699
737
|
this._responseDto = await this._sdk.session.init(this._ticket, parameterSet);
|
|
700
|
-
} else if(this._guid) {
|
|
738
|
+
} else if (this._guid) {
|
|
701
739
|
this._responseDto = await this._sdk.session.initForModel(this._guid, parameterSet);
|
|
702
740
|
} else {
|
|
703
741
|
// we should never get here
|
|
704
|
-
throw new ShapeDiverViewerSessionError(
|
|
742
|
+
throw new ShapeDiverViewerSessionError('Session.init: Initialization of session failed. Neither a ticket nor a guid are available.');
|
|
705
743
|
}
|
|
706
744
|
this._performanceEvaluator.endSection('sessionResponse');
|
|
707
745
|
|
|
@@ -709,18 +747,18 @@ export class SessionEngine implements ISessionEngine {
|
|
|
709
747
|
this._viewerSettingsVersionBackend = this._responseDto.viewerSettingsVersion || latestVersion;
|
|
710
748
|
this._sessionId = this._responseDto.sessionId;
|
|
711
749
|
this._modelId = this._responseDto.model?.id;
|
|
712
|
-
|
|
750
|
+
|
|
713
751
|
this._httpClient.addDataLoading(this._sessionId!, {
|
|
714
752
|
getAsset: this._sdk.asset.getAsset.bind(this._sdk.asset),
|
|
715
753
|
downloadTexture: this._sdk.asset.downloadImage.bind(this._sdk.asset),
|
|
716
|
-
})
|
|
754
|
+
});
|
|
717
755
|
|
|
718
756
|
this._settingsEngine.loadSettings(this._viewerSettings);
|
|
719
|
-
|
|
757
|
+
|
|
720
758
|
if (!this._sessionId)
|
|
721
|
-
throw new ShapeDiverViewerSessionError(
|
|
759
|
+
throw new ShapeDiverViewerSessionError('Session.init: Initialization of session failed. ResponseDto did not have a sessionId.');
|
|
722
760
|
if (!this._modelId)
|
|
723
|
-
throw new ShapeDiverViewerSessionError(
|
|
761
|
+
throw new ShapeDiverViewerSessionError('Session.init: Initialization of session failed. ResponseDto did not have a model.id.');
|
|
724
762
|
|
|
725
763
|
this.updateResponseDto(this._responseDto, parameterSet);
|
|
726
764
|
this._initialized = true;
|
|
@@ -730,7 +768,63 @@ export class SessionEngine implements ISessionEngine {
|
|
|
730
768
|
}
|
|
731
769
|
}
|
|
732
770
|
|
|
733
|
-
|
|
771
|
+
public async loadCachedOutputsParallel(outputMapping: { [key: string]: string }, taskEventInfo?: OutputLoaderTaskEventInfo, retry = false): Promise<{ [key: string]: ITreeNode | undefined }> {
|
|
772
|
+
this.checkAvailability();
|
|
773
|
+
// if there is already task event info, use it
|
|
774
|
+
// this happens after a retry
|
|
775
|
+
const eventId = taskEventInfo ? taskEventInfo.eventId : this._uuidGenerator.create();
|
|
776
|
+
const eventType = taskEventInfo ? taskEventInfo.type : TASK_TYPE.SESSION_OUTPUTS_LOADING;
|
|
777
|
+
const eventData = taskEventInfo ? taskEventInfo.data : { sessionId: this.id };
|
|
778
|
+
|
|
779
|
+
taskEventInfo = taskEventInfo ? taskEventInfo : {
|
|
780
|
+
eventId,
|
|
781
|
+
type: eventType,
|
|
782
|
+
progressRange: {
|
|
783
|
+
min: 0,
|
|
784
|
+
max: 1
|
|
785
|
+
},
|
|
786
|
+
data: eventData
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
try {
|
|
790
|
+
// send start event if this function was called initially
|
|
791
|
+
if (!taskEventInfo) {
|
|
792
|
+
const eventStart: ITaskEvent = { type: eventType, id: eventId, progress: 0, data: eventData, status: 'Loading cached outputs' };
|
|
793
|
+
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_START, eventStart);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// get the cached outputs
|
|
797
|
+
const responseDto = await this._sdk.output.getCache(this._sessionId!, outputMapping);
|
|
798
|
+
|
|
799
|
+
// create atomic output api objects for them
|
|
800
|
+
const outputs: {
|
|
801
|
+
[key: string]: IOutput;
|
|
802
|
+
} = {};
|
|
803
|
+
for (const outputId in responseDto.outputs) {
|
|
804
|
+
responseDto.outputs[outputId].id = outputId;
|
|
805
|
+
outputs[outputId] = new Output(<ShapeDiverResponseOutput>responseDto.outputs[outputId], this);
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// process the output data
|
|
809
|
+
const node = await this._outputLoader.loadOutputs(this._responseDto!.model?.name || 'model', outputs, {}, taskEventInfo, false);
|
|
810
|
+
|
|
811
|
+
// send the end event once done
|
|
812
|
+
const eventEnd: ITaskEvent = { type: eventType, id: eventId, progress: 1, data: eventData, status: 'Loaded cached outputs' };
|
|
813
|
+
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_END, eventEnd);
|
|
814
|
+
|
|
815
|
+
// create a mapping with a dictionary for the id of the outputs
|
|
816
|
+
const outputNodeMapping: { [key: string]: ITreeNode | undefined } = {};
|
|
817
|
+
for (const outputId in outputMapping)
|
|
818
|
+
outputNodeMapping[outputId] = node.children.find(n => n.name === outputId);
|
|
819
|
+
|
|
820
|
+
return outputNodeMapping;
|
|
821
|
+
}
|
|
822
|
+
catch (e) {
|
|
823
|
+
await this.handleError(e, retry);
|
|
824
|
+
return await this.loadCachedOutputsParallel(outputMapping, taskEventInfo, true);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
|
|
734
828
|
/**
|
|
735
829
|
* Load the outputs and return the scene graph node of the result.
|
|
736
830
|
* In case the outputs have a delay property, another customization request with the parameter set is sent.
|
|
@@ -739,25 +833,16 @@ export class SessionEngine implements ISessionEngine {
|
|
|
739
833
|
* @param outputs the outputs to load
|
|
740
834
|
* @returns promise with a scene graph node
|
|
741
835
|
*/
|
|
742
|
-
public async
|
|
836
|
+
public async loadOutputs(cancelRequest: () => boolean = () => false, taskEventInfo: OutputLoaderTaskEventInfo, retry = false): Promise<ISessionTreeNode> {
|
|
743
837
|
this.checkAvailability();
|
|
744
838
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
} = {}
|
|
748
|
-
let outputsFreeze: {
|
|
749
|
-
[key: string]: boolean;
|
|
750
|
-
} = {}
|
|
751
|
-
|
|
752
|
-
for (let outputId in responseDto.outputs) {
|
|
753
|
-
responseDto.outputs[outputId].id = outputId;
|
|
754
|
-
if (this.outputsFreeze[outputId] === undefined) outputsFreeze[outputId] = false;
|
|
755
|
-
outputs[outputId] = new Output(<ShapeDiverResponseOutput>responseDto.outputs[outputId], this);
|
|
756
|
-
}
|
|
757
|
-
|
|
839
|
+
const o = Object.assign({}, this._outputs);
|
|
840
|
+
const of = Object.assign({}, this._outputsFreeze);
|
|
758
841
|
try {
|
|
759
|
-
const node = await this._outputLoader.loadOutputs(this._responseDto!.model?.name || 'model',
|
|
760
|
-
node.data.push(new SessionData(
|
|
842
|
+
const node = await this._outputLoader.loadOutputs(this._responseDto!.model?.name || 'model', o, of, taskEventInfo);
|
|
843
|
+
node.data.push(new SessionData(this._responseDto!));
|
|
844
|
+
if (cancelRequest()) return node;
|
|
845
|
+
node.excludeViewports = JSON.parse(JSON.stringify(this._excludeViewports));
|
|
761
846
|
return node;
|
|
762
847
|
}
|
|
763
848
|
catch (e) {
|
|
@@ -766,23 +851,23 @@ export class SessionEngine implements ISessionEngine {
|
|
|
766
851
|
} else {
|
|
767
852
|
await this.handleError(e, retry);
|
|
768
853
|
if (cancelRequest()) return new SessionTreeNode();
|
|
769
|
-
return await this.
|
|
854
|
+
return await this.loadOutputs(cancelRequest, taskEventInfo, true);
|
|
770
855
|
}
|
|
771
856
|
|
|
772
857
|
if (cancelRequest()) return new SessionTreeNode();
|
|
773
|
-
|
|
774
|
-
for (
|
|
775
|
-
outputMapping[output] =
|
|
858
|
+
const outputMapping: { [key: string]: string } = {};
|
|
859
|
+
for (const output in o)
|
|
860
|
+
outputMapping[output] = o[output].version;
|
|
776
861
|
|
|
777
862
|
try {
|
|
778
863
|
const responseDto = await this._sdk.output.getCache(this._sessionId!, outputMapping);
|
|
779
864
|
if (cancelRequest()) return new SessionTreeNode();
|
|
780
865
|
this.updateResponseDto(responseDto);
|
|
781
|
-
return await this.
|
|
866
|
+
return await this.loadOutputs(cancelRequest, taskEventInfo);
|
|
782
867
|
} catch (e) {
|
|
783
868
|
await this.handleError(e, retry);
|
|
784
869
|
if (cancelRequest()) return new SessionTreeNode();
|
|
785
|
-
return await this.
|
|
870
|
+
return await this.loadOutputs(cancelRequest, taskEventInfo, true);
|
|
786
871
|
}
|
|
787
872
|
}
|
|
788
873
|
}
|
|
@@ -795,23 +880,25 @@ export class SessionEngine implements ISessionEngine {
|
|
|
795
880
|
* @param outputs the outputs to load
|
|
796
881
|
* @returns promise with a scene graph node
|
|
797
882
|
*/
|
|
798
|
-
public async
|
|
883
|
+
public async loadOutputsParallel(responseDto: ShapeDiverResponseDto, cancelRequest: () => boolean = () => false, taskEventInfo: OutputLoaderTaskEventInfo, retry = false): Promise<ISessionTreeNode> {
|
|
799
884
|
this.checkAvailability();
|
|
800
885
|
|
|
801
|
-
const
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
if (cancelRequest()) return node;
|
|
808
|
-
|
|
809
|
-
if (this._automaticSceneUpdate) this.removeFromSceneTree(this._node);
|
|
810
|
-
this._node = node;
|
|
811
|
-
if (this._automaticSceneUpdate && this._closed === false) this.addToSceneTree(this._node);
|
|
886
|
+
const outputs: {
|
|
887
|
+
[key: string]: IOutput;
|
|
888
|
+
} = {};
|
|
889
|
+
const outputsFreeze: {
|
|
890
|
+
[key: string]: boolean;
|
|
891
|
+
} = {};
|
|
812
892
|
|
|
813
|
-
|
|
893
|
+
for (const outputId in responseDto.outputs) {
|
|
894
|
+
responseDto.outputs[outputId].id = outputId;
|
|
895
|
+
if (this.outputsFreeze[outputId] === undefined) outputsFreeze[outputId] = false;
|
|
896
|
+
outputs[outputId] = new Output(<ShapeDiverResponseOutput>responseDto.outputs[outputId], this);
|
|
897
|
+
}
|
|
814
898
|
|
|
899
|
+
try {
|
|
900
|
+
const node = await this._outputLoader.loadOutputs(this._responseDto!.model?.name || 'model', outputs, outputsFreeze, taskEventInfo);
|
|
901
|
+
node.data.push(new SessionData(responseDto));
|
|
815
902
|
return node;
|
|
816
903
|
}
|
|
817
904
|
catch (e) {
|
|
@@ -820,23 +907,23 @@ export class SessionEngine implements ISessionEngine {
|
|
|
820
907
|
} else {
|
|
821
908
|
await this.handleError(e, retry);
|
|
822
909
|
if (cancelRequest()) return new SessionTreeNode();
|
|
823
|
-
return await this.
|
|
910
|
+
return await this.loadOutputsParallel(responseDto, cancelRequest, taskEventInfo, true);
|
|
824
911
|
}
|
|
825
912
|
|
|
826
913
|
if (cancelRequest()) return new SessionTreeNode();
|
|
827
|
-
|
|
828
|
-
for (
|
|
829
|
-
outputMapping[output] =
|
|
914
|
+
const outputMapping: { [key: string]: string } = {};
|
|
915
|
+
for (const output in outputs)
|
|
916
|
+
outputMapping[output] = outputs[output].version;
|
|
830
917
|
|
|
831
918
|
try {
|
|
832
919
|
const responseDto = await this._sdk.output.getCache(this._sessionId!, outputMapping);
|
|
833
920
|
if (cancelRequest()) return new SessionTreeNode();
|
|
834
921
|
this.updateResponseDto(responseDto);
|
|
835
|
-
return await this.
|
|
922
|
+
return await this.loadOutputsParallel(responseDto, cancelRequest, taskEventInfo);
|
|
836
923
|
} catch (e) {
|
|
837
924
|
await this.handleError(e, retry);
|
|
838
925
|
if (cancelRequest()) return new SessionTreeNode();
|
|
839
|
-
return await this.
|
|
926
|
+
return await this.loadOutputsParallel(responseDto, cancelRequest, taskEventInfo, true);
|
|
840
927
|
}
|
|
841
928
|
}
|
|
842
929
|
}
|
|
@@ -844,32 +931,8 @@ export class SessionEngine implements ISessionEngine {
|
|
|
844
931
|
public async requestExport(exportId: string, parameters: { [key: string]: string }, maxWaitTime: number, retry = false): Promise<ShapeDiverResponseExport> {
|
|
845
932
|
this.checkAvailability('export');
|
|
846
933
|
try {
|
|
847
|
-
const requestParameterSet
|
|
848
|
-
|
|
849
|
-
// first step, we convert all our names and displaynames to ids
|
|
850
|
-
for (const parameterIdOrName in parameters) {
|
|
851
|
-
// we prioritize id, then name and then displayname
|
|
852
|
-
// if there are two parameters with the same name or displayname, we take the one that is found first (no way for us to evaluate which one the user meant)
|
|
853
|
-
const parameterObject = Object.values(this._parameters).find(p => p.id === parameterIdOrName || p.name === parameterIdOrName || p.displayname === parameterIdOrName);
|
|
854
|
-
|
|
855
|
-
// in case the key of the key value pair was neither the id, name or displayname, skip
|
|
856
|
-
if(!parameterObject) continue;
|
|
857
|
-
|
|
858
|
-
// deep copy into new dictionary
|
|
859
|
-
requestParameterSet[parameterObject.id] = (' ' + parameters[parameterIdOrName]).slice(1);
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
// seconds step, fill all other parameter values that are currently not set
|
|
863
|
-
const currentParameters = this.parameterValues;
|
|
864
|
-
for (const parameterId in currentParameters) {
|
|
865
|
-
// if already set by input values, skip
|
|
866
|
-
if(requestParameterSet[parameterId] !== undefined) continue;
|
|
867
|
-
|
|
868
|
-
// deep copy into new dictionary
|
|
869
|
-
requestParameterSet[parameterId] = (' ' + currentParameters[parameterId]).slice(1);
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
const responseDto = await this._sdk.utils.submitAndWaitForExport(this._sdk, this._sessionId!, { exports: { id: exportId }, parameters: requestParameterSet }, maxWaitTime)
|
|
934
|
+
const requestParameterSet = this.cleanExportParameters(parameters);
|
|
935
|
+
const responseDto = await this._sdk.utils.submitAndWaitForExport(this._sdk, this._sessionId!, { exports: { id: exportId }, parameters: requestParameterSet }, maxWaitTime);
|
|
873
936
|
this.updateResponseDto(responseDto);
|
|
874
937
|
return this.exports[exportId];
|
|
875
938
|
} catch (e) {
|
|
@@ -878,42 +941,55 @@ export class SessionEngine implements ISessionEngine {
|
|
|
878
941
|
}
|
|
879
942
|
}
|
|
880
943
|
|
|
944
|
+
public async requestExports(body: ShapeDiverRequestExport, maxWaitMsec?: number, retry = false): Promise<ShapeDiverResponseDto> {
|
|
945
|
+
this.checkAvailability('export');
|
|
946
|
+
try {
|
|
947
|
+
const requestParameterSet = this.cleanExportParameters(body.parameters);
|
|
948
|
+
const responseDto = await this._sdk.utils.submitAndWaitForExport(this._sdk, this._sessionId!, { exports: body.exports, parameters: requestParameterSet, outputs: body.outputs, max_wait_time: body.max_wait_time }, maxWaitMsec);
|
|
949
|
+
this.updateResponseDto(responseDto);
|
|
950
|
+
return responseDto;
|
|
951
|
+
} catch (e) {
|
|
952
|
+
await this.handleError(e, retry);
|
|
953
|
+
return await this.requestExports(body, maxWaitMsec, true);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
881
957
|
public resetSettings(sections?: ISettingsSections): void {
|
|
882
958
|
if (!this._responseDto)
|
|
883
|
-
throw new ShapeDiverViewerSessionError(
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
959
|
+
throw new ShapeDiverViewerSessionError('Session.resetSettings: responseDto not available.');
|
|
960
|
+
|
|
961
|
+
sections = sections || {};
|
|
962
|
+
if (sections.session === undefined) {
|
|
963
|
+
sections.session = {
|
|
964
|
+
parameter: { displayname: true, order: true, hidden: true },
|
|
965
|
+
export: { displayname: true, order: true, hidden: true }
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
if (sections.session.parameter === undefined)
|
|
969
|
+
sections.session.parameter = { displayname: true, order: true, hidden: true, value: true };
|
|
970
|
+
if (sections.session.export === undefined)
|
|
971
|
+
sections.session.export = { displayname: true, order: true, hidden: true };
|
|
972
|
+
if (sections.viewport === undefined)
|
|
973
|
+
sections.viewport = { ar: true, scene: true, camera: true, light: true, environment: true, general: true, postprocessing: true };
|
|
974
|
+
|
|
975
|
+
return this.applySettings(this._responseDto, sections);
|
|
900
976
|
}
|
|
901
977
|
|
|
902
978
|
public async saveDefaultParameterValues(): Promise<boolean> {
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
979
|
+
this._logger.debugLow(`Session(${this.id}).saveDefaultParameters: Saving default parameters.`);
|
|
980
|
+
const response = await this.saveDefaultParameters();
|
|
981
|
+
if (response) {
|
|
982
|
+
this._logger.debug(`Session(${this.id}).saveDefaultParameters: Saved default parameters.`);
|
|
983
|
+
} else {
|
|
984
|
+
throw new ShapeDiverViewerSessionError(`Session(${this.id}).saveDefaultParameters: Could not save default parameters.`);
|
|
985
|
+
}
|
|
986
|
+
return response;
|
|
911
987
|
}
|
|
912
988
|
|
|
913
989
|
public async saveDefaultParameters(retry = false): Promise<boolean> {
|
|
914
990
|
this.checkAvailability('defaultparam', true);
|
|
915
991
|
try {
|
|
916
|
-
await this._sdk.model.setDefaultParams(this._modelId!, this._parameterValues)
|
|
992
|
+
await this._sdk.model.setDefaultParams(this._modelId!, this._parameterValues);
|
|
917
993
|
return true;
|
|
918
994
|
} catch (e) {
|
|
919
995
|
await this.handleError(e, retry);
|
|
@@ -993,22 +1069,22 @@ export class SessionEngine implements ISessionEngine {
|
|
|
993
1069
|
}
|
|
994
1070
|
}
|
|
995
1071
|
|
|
996
|
-
public async saveSettings(json:
|
|
1072
|
+
public async saveSettings(json: unknown, retry = false): Promise<boolean> {
|
|
997
1073
|
this.checkAvailability('configure', true);
|
|
998
|
-
|
|
1074
|
+
|
|
999
1075
|
try {
|
|
1000
|
-
validate(json, <versions>this._viewerSettingsVersion)
|
|
1001
|
-
|
|
1076
|
+
validate(json, <versions>this._viewerSettingsVersion);
|
|
1077
|
+
|
|
1002
1078
|
// if viewer settings version is higher than backend settings version
|
|
1003
1079
|
// convert to backend settings version
|
|
1004
|
-
if(+this._viewerSettingsVersion > +this._viewerSettingsVersionBackend)
|
|
1005
|
-
json = convert(json, <versions>this._viewerSettingsVersionBackend)
|
|
1080
|
+
if (+this._viewerSettingsVersion > +this._viewerSettingsVersionBackend)
|
|
1081
|
+
json = convert(json, <versions>this._viewerSettingsVersionBackend);
|
|
1006
1082
|
} catch (e) {
|
|
1007
1083
|
throw new ShapeDiverViewerSettingsError('Session.saveSettings: Settings could not be validated. ' + (<Error>e).message, <Error>e);
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
try {
|
|
1011
|
-
await this._sdk.model.updateConfig(this._modelId!, json);
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
try {
|
|
1087
|
+
await this._sdk.model.updateConfig(this._modelId!, json as ShapeDiverRequestConfigure);
|
|
1012
1088
|
return true;
|
|
1013
1089
|
} catch (e) {
|
|
1014
1090
|
await this.handleError(e, retry);
|
|
@@ -1017,60 +1093,60 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1017
1093
|
}
|
|
1018
1094
|
|
|
1019
1095
|
public async saveUiProperties(saveInSettings: boolean = true): Promise<boolean> {
|
|
1020
|
-
|
|
1096
|
+
this._logger.debugLow(`Session(${this.id}).saveSessionProperties: Saving session properties.`);
|
|
1021
1097
|
|
|
1022
|
-
|
|
1023
|
-
|
|
1098
|
+
// settings saving
|
|
1099
|
+
this._saveSessionSettings();
|
|
1024
1100
|
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
}
|
|
1032
|
-
} = {};
|
|
1033
|
-
for (let p in this.parameters) {
|
|
1034
|
-
properties[p] = {
|
|
1035
|
-
displayname: this.parameters[p].displayname !== undefined ? this.parameters[p].displayname! : '',
|
|
1036
|
-
hidden: this.parameters[p].hidden !== undefined ? this.parameters[p].hidden : false,
|
|
1037
|
-
order: this.parameters[p].order !== undefined ? this.parameters[p].order! : 0,
|
|
1038
|
-
tooltip: this.parameters[p].tooltip !== undefined ? this.parameters[p].tooltip! : '',
|
|
1039
|
-
};
|
|
1040
|
-
}
|
|
1041
|
-
const responseP = Object.values(properties).length !== 0 ? await this.saveParameterProperties(properties) : true;
|
|
1042
|
-
|
|
1043
|
-
properties = {};
|
|
1044
|
-
for (let e in this.exports) {
|
|
1045
|
-
properties[e] = {
|
|
1046
|
-
displayname: this.exports[e].displayname !== undefined ? this.exports[e].displayname! : '',
|
|
1047
|
-
hidden: this.exports[e].hidden !== undefined ? this.exports[e].hidden : false,
|
|
1048
|
-
order: this.exports[e].order !== undefined ? this.exports[e].order! : 0,
|
|
1049
|
-
tooltip: this.exports[e].tooltip !== undefined ? this.exports[e].tooltip! : '',
|
|
1050
|
-
};
|
|
1051
|
-
}
|
|
1052
|
-
const responseE = Object.values(properties).length !== 0 ? await this.saveExportProperties(properties) : true;
|
|
1053
|
-
|
|
1054
|
-
properties = {};
|
|
1055
|
-
for (let o in this.outputs) {
|
|
1056
|
-
properties[o] = {
|
|
1057
|
-
displayname: this.outputs[o].displayname !== undefined ? this.outputs[o].displayname! : '',
|
|
1058
|
-
hidden: this.outputs[o].hidden !== undefined ? this.outputs[o].hidden : false,
|
|
1059
|
-
order: this.outputs[o].order !== undefined ? this.outputs[o].order! : 0,
|
|
1060
|
-
tooltip: this.outputs[o].tooltip !== undefined ? this.outputs[o].tooltip! : '',
|
|
1061
|
-
};
|
|
1101
|
+
let properties: {
|
|
1102
|
+
[key: string]: {
|
|
1103
|
+
displayname: string,
|
|
1104
|
+
hidden: boolean,
|
|
1105
|
+
order: number,
|
|
1106
|
+
tooltip: string
|
|
1062
1107
|
}
|
|
1063
|
-
|
|
1108
|
+
} = {};
|
|
1109
|
+
for (const p in this.parameters) {
|
|
1110
|
+
properties[p] = {
|
|
1111
|
+
displayname: this.parameters[p].displayname !== undefined ? this.parameters[p].displayname! : '',
|
|
1112
|
+
hidden: this.parameters[p].hidden !== undefined ? this.parameters[p].hidden : false,
|
|
1113
|
+
order: this.parameters[p].order !== undefined ? this.parameters[p].order! : 0,
|
|
1114
|
+
tooltip: this.parameters[p].tooltip !== undefined ? this.parameters[p].tooltip! : '',
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
const responseP = Object.values(properties).length !== 0 ? await this.saveParameterProperties(properties) : true;
|
|
1118
|
+
|
|
1119
|
+
properties = {};
|
|
1120
|
+
for (const e in this.exports) {
|
|
1121
|
+
properties[e] = {
|
|
1122
|
+
displayname: this.exports[e].displayname !== undefined ? this.exports[e].displayname! : '',
|
|
1123
|
+
hidden: this.exports[e].hidden !== undefined ? this.exports[e].hidden : false,
|
|
1124
|
+
order: this.exports[e].order !== undefined ? this.exports[e].order! : 0,
|
|
1125
|
+
tooltip: this.exports[e].tooltip !== undefined ? this.exports[e].tooltip! : '',
|
|
1126
|
+
};
|
|
1127
|
+
}
|
|
1128
|
+
const responseE = Object.values(properties).length !== 0 ? await this.saveExportProperties(properties) : true;
|
|
1129
|
+
|
|
1130
|
+
properties = {};
|
|
1131
|
+
for (const o in this.outputs) {
|
|
1132
|
+
properties[o] = {
|
|
1133
|
+
displayname: this.outputs[o].displayname !== undefined ? this.outputs[o].displayname! : '',
|
|
1134
|
+
hidden: this.outputs[o].hidden !== undefined ? this.outputs[o].hidden : false,
|
|
1135
|
+
order: this.outputs[o].order !== undefined ? this.outputs[o].order! : 0,
|
|
1136
|
+
tooltip: this.outputs[o].tooltip !== undefined ? this.outputs[o].tooltip! : '',
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
const responseO = Object.values(properties).length !== 0 ? await this.saveOutputProperties(properties) : true;
|
|
1064
1140
|
|
|
1065
|
-
|
|
1066
|
-
|
|
1141
|
+
// save partial settings
|
|
1142
|
+
const response = saveInSettings ? await this.saveSettings(this._settingsEngine.settings) : true;
|
|
1067
1143
|
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1144
|
+
if (response && responseP && responseO && responseE) {
|
|
1145
|
+
this._logger.debug(`Session(${this.id}).saveSessionProperties: Saved session properties.`);
|
|
1146
|
+
} else {
|
|
1147
|
+
this._logger.warn(`Session(${this.id}).saveSessionProperties: Could not save session properties.`);
|
|
1148
|
+
}
|
|
1149
|
+
return response && responseP && responseO && responseE;
|
|
1074
1150
|
}
|
|
1075
1151
|
|
|
1076
1152
|
public async setJwtToken(value: string) {
|
|
@@ -1080,18 +1156,18 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1080
1156
|
try {
|
|
1081
1157
|
this._sdk.setConfigurationValue(ShapeDiverSdkConfigType.JWT_TOKEN, value);
|
|
1082
1158
|
const responseDto = await this._sdk.session.default(this._sessionId!);
|
|
1083
|
-
if(this._responseDto) this._responseDto.actions = responseDto.actions;
|
|
1159
|
+
if (this._responseDto) this._responseDto.actions = responseDto.actions;
|
|
1084
1160
|
} catch (e) {
|
|
1085
1161
|
throw this._httpClient.convertError(e);
|
|
1086
1162
|
}
|
|
1087
1163
|
}
|
|
1088
1164
|
|
|
1089
|
-
public async updateOutputs(taskEventInfo?: OutputLoaderTaskEventInfo): Promise<ITreeNode> {
|
|
1165
|
+
public async updateOutputs(taskEventInfo?: OutputLoaderTaskEventInfo, waitForViewportUpdate: boolean = false): Promise<ITreeNode> {
|
|
1090
1166
|
const eventId = taskEventInfo ? taskEventInfo.eventId : this._uuidGenerator.create();
|
|
1091
1167
|
const eventType = taskEventInfo ? taskEventInfo.type : TASK_TYPE.SESSION_OUTPUTS_UPDATE;
|
|
1092
1168
|
const eventData = taskEventInfo ? taskEventInfo.data : { sessionId: this.id };
|
|
1093
1169
|
|
|
1094
|
-
if(!taskEventInfo) {
|
|
1170
|
+
if (!taskEventInfo) {
|
|
1095
1171
|
const eventStart: ITaskEvent = { type: eventType, id: eventId, progress: 0, data: eventData, status: 'Updating outputs' };
|
|
1096
1172
|
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_START, eventStart);
|
|
1097
1173
|
}
|
|
@@ -1102,13 +1178,15 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1102
1178
|
|
|
1103
1179
|
this._logger.debugLow(`Session(${this.id}).updateOutputs: Updating Outputs.`);
|
|
1104
1180
|
|
|
1105
|
-
for (
|
|
1106
|
-
if(!this.excludeViewports.includes(r))
|
|
1181
|
+
for (const r in this._stateEngine.renderingEngines)
|
|
1182
|
+
if (!this.excludeViewports.includes(r))
|
|
1107
1183
|
this._stateEngine.renderingEngines[r].busy.push(customizationId);
|
|
1108
1184
|
|
|
1109
1185
|
const eventRequest: ITaskEvent = { type: eventType, id: eventId, progress: taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 0.1 + taskEventInfo.progressRange.min : 0.1, data: eventData, status: 'Loading outputs' };
|
|
1110
1186
|
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_PROCESS, eventRequest);
|
|
1111
1187
|
|
|
1188
|
+
const oldOutputVersions = this._outputLoader.getCurrentOutputVersions();
|
|
1189
|
+
|
|
1112
1190
|
const newNode = await this.loadOutputs(() => this.#customizationProcess !== customizationId, {
|
|
1113
1191
|
eventId,
|
|
1114
1192
|
type: eventType,
|
|
@@ -1119,29 +1197,33 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1119
1197
|
data: eventData
|
|
1120
1198
|
});
|
|
1121
1199
|
|
|
1200
|
+
const newOutputVersions = this._outputLoader.getCurrentOutputVersions();
|
|
1201
|
+
|
|
1122
1202
|
const eventSceneUpdate: ITaskEvent = { type: eventType, id: eventId, progress: taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 0.9 + taskEventInfo.progressRange.min : 0.9, data: eventData, status: 'Updating scene' };
|
|
1123
1203
|
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_PROCESS, eventSceneUpdate);
|
|
1124
1204
|
|
|
1125
1205
|
// OPTION TO SKIP - PART 1
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
const
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1206
|
+
const cancelResult = this.cancelProcess(customizationId, eventId, eventType, taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 1 + taskEventInfo.progressRange.min : 1, eventData, newNode);
|
|
1207
|
+
if (cancelResult) return cancelResult;
|
|
1208
|
+
|
|
1209
|
+
// call the update callbacks
|
|
1210
|
+
if (waitForViewportUpdate === false) {
|
|
1211
|
+
for (const outputId in this.outputs) {
|
|
1212
|
+
if (oldOutputVersions[outputId] !== newOutputVersions[outputId]) {
|
|
1213
|
+
this._eventEngine.emitEvent(EVENTTYPE.OUTPUT.OUTPUT_UPDATED, {
|
|
1214
|
+
outputId: outputId,
|
|
1215
|
+
outputVersion: newOutputVersions[outputId],
|
|
1216
|
+
newNode: newNode.children.find(c => c.name === outputId)!,
|
|
1217
|
+
oldNode: oldNode.children.find(c => c.name === outputId)!
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
await this.waitForUpdateCallbacks(newOutputVersions, oldOutputVersions, newNode, oldNode);
|
|
1141
1223
|
|
|
1142
|
-
|
|
1143
|
-
this.
|
|
1144
|
-
|
|
1224
|
+
// OPTION TO SKIP - PART 2
|
|
1225
|
+
const cancelResult = this.cancelProcess(customizationId, eventId, eventType, taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 1 + taskEventInfo.progressRange.min : 1, eventData, newNode);
|
|
1226
|
+
if (cancelResult) return cancelResult;
|
|
1145
1227
|
}
|
|
1146
1228
|
|
|
1147
1229
|
if (this.automaticSceneUpdate) this.removeFromSceneTree(this.node);
|
|
@@ -1149,7 +1231,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1149
1231
|
if (this.automaticSceneUpdate && this._closed === false) this.addToSceneTree(this.node);
|
|
1150
1232
|
|
|
1151
1233
|
this._logger.debug(`Session(${this.id}).updateOutputs: Updating outputs finished, updating geometry.`);
|
|
1152
|
-
|
|
1234
|
+
|
|
1153
1235
|
// set the output content to what has been updated
|
|
1154
1236
|
for (const outputId in this.outputs) {
|
|
1155
1237
|
this.outputs[outputId].updateOutput(
|
|
@@ -1165,31 +1247,40 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1165
1247
|
this._warningCreator();
|
|
1166
1248
|
this.node.excludeViewports = JSON.parse(JSON.stringify(this._excludeViewports));
|
|
1167
1249
|
|
|
1168
|
-
for (
|
|
1250
|
+
for (const r in this._stateEngine.renderingEngines)
|
|
1169
1251
|
if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
|
|
1170
1252
|
this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
|
|
1171
1253
|
|
|
1172
1254
|
this._logger.debug(`Session(${this.id}).updateOutputs: Updated outputs.`);
|
|
1173
|
-
|
|
1174
|
-
if(!taskEventInfo) {
|
|
1255
|
+
|
|
1256
|
+
if (!taskEventInfo) {
|
|
1175
1257
|
const eventEnd: ITaskEvent = { type: eventType, id: eventId, progress: 1, data: eventData, status: 'Outputs updated' };
|
|
1176
1258
|
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_END, eventEnd);
|
|
1177
1259
|
}
|
|
1178
1260
|
|
|
1179
1261
|
// update the viewports
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
this._stateEngine.renderingEngines[r].
|
|
1262
|
+
if (waitForViewportUpdate) {
|
|
1263
|
+
for (const r in this._stateEngine.renderingEngines)
|
|
1264
|
+
if (!this.excludeViewports.includes(this._stateEngine.renderingEngines[r].id))
|
|
1265
|
+
this._stateEngine.renderingEngines[r].update(`SessionEngine(${this.id}).updateOutputs`);
|
|
1266
|
+
|
|
1267
|
+
for (const outputId in this.outputs) {
|
|
1268
|
+
if (oldOutputVersions[outputId] !== newOutputVersions[outputId]) {
|
|
1269
|
+
this._eventEngine.emitEvent(EVENTTYPE.OUTPUT.OUTPUT_UPDATED, {
|
|
1270
|
+
outputId: outputId,
|
|
1271
|
+
outputVersion: newOutputVersions[outputId],
|
|
1272
|
+
newNode: newNode.children.find(c => c.name === outputId)!,
|
|
1273
|
+
oldNode: oldNode.children.find(c => c.name === outputId)!
|
|
1274
|
+
});
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1183
1277
|
|
|
1184
|
-
|
|
1185
|
-
if (this._updateCallback) this._updateCallback(newNode, oldNode);
|
|
1278
|
+
await this.waitForUpdateCallbacks(newOutputVersions, oldOutputVersions, newNode, oldNode);
|
|
1186
1279
|
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
oldNode.children.find(c => c.name === outputId)!
|
|
1192
|
-
);
|
|
1280
|
+
// OPTION TO SKIP - PART 3
|
|
1281
|
+
const cancelResult = this.cancelProcess(customizationId, eventId, eventType, taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 1 + taskEventInfo.progressRange.min : 1, eventData, newNode);
|
|
1282
|
+
if (cancelResult) return cancelResult;
|
|
1283
|
+
}
|
|
1193
1284
|
|
|
1194
1285
|
return this.node;
|
|
1195
1286
|
}
|
|
@@ -1199,14 +1290,14 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1199
1290
|
try {
|
|
1200
1291
|
const responseDto = await this._sdk.file.requestUpload(this._sessionId!, {
|
|
1201
1292
|
[parameterId]: { size: data.size, format: type }
|
|
1202
|
-
})
|
|
1293
|
+
});
|
|
1203
1294
|
|
|
1204
1295
|
if (responseDto && responseDto.asset && responseDto.asset.file && responseDto.asset.file[parameterId]) {
|
|
1205
1296
|
const fileAsset = responseDto.asset.file[parameterId];
|
|
1206
1297
|
await this._sdk.utils.upload(fileAsset.href, await data.arrayBuffer(), type);
|
|
1207
1298
|
return fileAsset.id;
|
|
1208
1299
|
} else {
|
|
1209
|
-
throw new ShapeDiverViewerSessionError(
|
|
1300
|
+
throw new ShapeDiverViewerSessionError('Session.uploadFile: Upload reply has not the required format.');
|
|
1210
1301
|
}
|
|
1211
1302
|
} catch (e) {
|
|
1212
1303
|
await this.handleError(e, retry);
|
|
@@ -1218,8 +1309,8 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1218
1309
|
this.checkAvailability('gltf-upload');
|
|
1219
1310
|
try {
|
|
1220
1311
|
const responseDto = await this._sdk.gltf.upload(this._sessionId!, await blob.arrayBuffer(), 'model/gltf-binary', conversion);
|
|
1221
|
-
if (!responseDto || !responseDto.gltf || !responseDto.gltf.href)
|
|
1222
|
-
throw new ShapeDiverViewerSessionError(
|
|
1312
|
+
if (!responseDto || !responseDto.gltf || !responseDto.gltf.href)
|
|
1313
|
+
throw new ShapeDiverViewerSessionError('Session.uploadGLTF: Upload reply has not the required format.');
|
|
1223
1314
|
return responseDto;
|
|
1224
1315
|
} catch (e) {
|
|
1225
1316
|
await this.handleError(e, retry);
|
|
@@ -1227,9 +1318,9 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1227
1318
|
}
|
|
1228
1319
|
}
|
|
1229
1320
|
|
|
1230
|
-
// #endregion Public Methods (
|
|
1321
|
+
// #endregion Public Methods (27)
|
|
1231
1322
|
|
|
1232
|
-
// #region Private Methods (
|
|
1323
|
+
// #region Private Methods (13)
|
|
1233
1324
|
|
|
1234
1325
|
private _saveSessionSettings() {
|
|
1235
1326
|
const parameters = this.parameters;
|
|
@@ -1242,26 +1333,26 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1242
1333
|
hidden: boolean;
|
|
1243
1334
|
}
|
|
1244
1335
|
} = {};
|
|
1245
|
-
for (
|
|
1336
|
+
for (const p in parameters) {
|
|
1246
1337
|
sessionProperties[p] = {
|
|
1247
1338
|
order: parameters[p].order || 0,
|
|
1248
1339
|
displayname: parameters[p].displayname || '',
|
|
1249
1340
|
hidden: parameters[p].hidden
|
|
1250
|
-
}
|
|
1341
|
+
};
|
|
1251
1342
|
}
|
|
1252
|
-
for (
|
|
1343
|
+
for (const e in exports) {
|
|
1253
1344
|
sessionProperties[e] = {
|
|
1254
1345
|
order: exports[e].order || 0,
|
|
1255
1346
|
displayname: exports[e].displayname || '',
|
|
1256
1347
|
hidden: exports[e].hidden
|
|
1257
|
-
}
|
|
1348
|
+
};
|
|
1258
1349
|
}
|
|
1259
1350
|
this._settingsEngine.session = sessionProperties;
|
|
1260
1351
|
|
|
1261
1352
|
let orderedOutputs: IOutput[] = [];
|
|
1262
|
-
for (
|
|
1353
|
+
for (const o in this.outputs) orderedOutputs.push(this.outputs[o]);
|
|
1263
1354
|
orderedOutputs.sort((a, b) => ((a.order || Infinity) - (b.order || Infinity)));
|
|
1264
|
-
|
|
1355
|
+
const zerosOutputs = orderedOutputs.filter(x => x.order === 0);
|
|
1265
1356
|
orderedOutputs = orderedOutputs.filter((el) => { return !zerosOutputs.includes(el); });
|
|
1266
1357
|
orderedOutputs = zerosOutputs.concat(orderedOutputs);
|
|
1267
1358
|
|
|
@@ -1306,41 +1397,110 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1306
1397
|
this._sceneTree.root.updateVersion();
|
|
1307
1398
|
}
|
|
1308
1399
|
|
|
1400
|
+
private cancelProcess(customizationId: string, eventId: string, eventType: TASK_TYPE, eventProgress: number, eventData: unknown, newNode: ITreeNode = new SessionTreeNode()): ITreeNode | undefined {
|
|
1401
|
+
if (this.#customizationProcess !== customizationId) {
|
|
1402
|
+
for (const r in this._stateEngine.renderingEngines)
|
|
1403
|
+
if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
|
|
1404
|
+
this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
|
|
1405
|
+
|
|
1406
|
+
const eventCancel: ITaskEvent = {
|
|
1407
|
+
type: eventType,
|
|
1408
|
+
id: eventId,
|
|
1409
|
+
progress: eventProgress,
|
|
1410
|
+
data: eventData,
|
|
1411
|
+
status: 'The request was exceeded by another customization request'
|
|
1412
|
+
};
|
|
1413
|
+
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_CANCEL, eventCancel);
|
|
1414
|
+
this._logger.debug(`Session(${this.id}).cancelProcess: The request was was exceeded by another request.`);
|
|
1415
|
+
return newNode;
|
|
1416
|
+
} else if ((this._closed as boolean) === true) {
|
|
1417
|
+
for (const r in this._stateEngine.renderingEngines)
|
|
1418
|
+
if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
|
|
1419
|
+
this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
|
|
1420
|
+
|
|
1421
|
+
this._logger.debug(`Session(${this.id}).cancelProcess: The session was closed during the request.`);
|
|
1422
|
+
|
|
1423
|
+
const eventCancel: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'The session was closed during the request.' };
|
|
1424
|
+
this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_CANCEL, eventCancel);
|
|
1425
|
+
return new SessionTreeNode();
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1309
1429
|
private checkAvailability(action?: string, checkForModelId = false) {
|
|
1310
1430
|
if (!this._responseDto)
|
|
1311
|
-
throw new ShapeDiverViewerSessionError(
|
|
1431
|
+
throw new ShapeDiverViewerSessionError('Session.checkAvailability: responseDto not available.');
|
|
1312
1432
|
|
|
1313
1433
|
if (!this._sessionId)
|
|
1314
|
-
throw new ShapeDiverViewerSessionError(
|
|
1434
|
+
throw new ShapeDiverViewerSessionError('Session.checkAvailability: sessionId not available.');
|
|
1315
1435
|
|
|
1316
1436
|
if (checkForModelId && !this._modelId)
|
|
1317
|
-
throw new ShapeDiverViewerSessionError(
|
|
1437
|
+
throw new ShapeDiverViewerSessionError('Session.checkAvailability: modelId not available.');
|
|
1318
1438
|
|
|
1319
1439
|
if (action && !this._responseDto.actions)
|
|
1320
|
-
throw new ShapeDiverViewerSessionError(
|
|
1440
|
+
throw new ShapeDiverViewerSessionError('Session.checkAvailability: actions not available.');
|
|
1321
1441
|
|
|
1322
1442
|
const responseDtoAction = this._responseDto.actions?.find(a => a.name === action);
|
|
1323
1443
|
if (action && !responseDtoAction)
|
|
1324
1444
|
throw new ShapeDiverViewerSessionError(`Session.checkAvailability: action ${action} not available.`);
|
|
1325
1445
|
}
|
|
1326
1446
|
|
|
1447
|
+
private cleanExportParameters(parameters: ShapeDiverRequestCustomization): ShapeDiverRequestCustomization {
|
|
1448
|
+
const requestParameterSet: ShapeDiverRequestCustomization = {};
|
|
1449
|
+
|
|
1450
|
+
// first step, we convert all our names and displaynames to ids
|
|
1451
|
+
for (const parameterIdOrName in parameters) {
|
|
1452
|
+
// we prioritize id, then name and then displayname
|
|
1453
|
+
// if there are two parameters with the same name or displayname, we take the one that is found first (no way for us to evaluate which one the user meant)
|
|
1454
|
+
const parameterObject = Object.values(this._parameters).find(p => p.id === parameterIdOrName || p.name === parameterIdOrName || p.displayname === parameterIdOrName);
|
|
1455
|
+
|
|
1456
|
+
// in case the key of the key value pair was neither the id, name or displayname, skip
|
|
1457
|
+
if (!parameterObject) continue;
|
|
1458
|
+
|
|
1459
|
+
// copy into new dictionary
|
|
1460
|
+
requestParameterSet[parameterObject.id] = parameters[parameterIdOrName];
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
// seconds step, fill all other parameter values that are currently not set
|
|
1464
|
+
const currentParameters = this.parameterValues;
|
|
1465
|
+
for (const parameterId in currentParameters) {
|
|
1466
|
+
// if already set by input values, skip
|
|
1467
|
+
if (requestParameterSet[parameterId] !== undefined) continue;
|
|
1468
|
+
|
|
1469
|
+
// deep copy into new dictionary
|
|
1470
|
+
requestParameterSet[parameterId] = (' ' + currentParameters[parameterId]).slice(1);
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
return requestParameterSet;
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1327
1476
|
private async customizeInternal(cancelRequest: () => boolean, taskEventInfo: OutputLoaderTaskEventInfo): Promise<ISessionTreeNode> {
|
|
1328
|
-
return this.customizeSession(this._parameterValues, cancelRequest, taskEventInfo)
|
|
1477
|
+
return this.customizeSession(this._parameterValues, cancelRequest, taskEventInfo) as Promise<ISessionTreeNode>;
|
|
1329
1478
|
}
|
|
1330
1479
|
|
|
1331
|
-
private async customizeSession(parameters: { [key: string]: string }, cancelRequest: () => boolean, taskEventInfo: OutputLoaderTaskEventInfo, parallel = false, retry = false): Promise<ISessionTreeNode> {
|
|
1480
|
+
private async customizeSession(parameters: { [key: string]: string }, cancelRequest: () => boolean, taskEventInfo: OutputLoaderTaskEventInfo, parallel = false, loadOutputs = true, retry = false): Promise<ISessionTreeNode | ShapeDiverResponseDto> {
|
|
1332
1481
|
this.checkAvailability('customize');
|
|
1333
1482
|
try {
|
|
1334
1483
|
this._performanceEvaluator.startSection('sessionResponse');
|
|
1335
1484
|
const responseDto = await this._sdk.utils.submitAndWaitForCustomization(this._sdk, this._sessionId!, parameters);
|
|
1336
1485
|
this._performanceEvaluator.endSection('sessionResponse');
|
|
1337
|
-
if (
|
|
1338
|
-
|
|
1339
|
-
|
|
1486
|
+
if (loadOutputs === true) {
|
|
1487
|
+
if (cancelRequest()) return new SessionTreeNode();
|
|
1488
|
+
if (parallel === true) {
|
|
1489
|
+
// special case, we load the outputs put don't add them to the scene
|
|
1490
|
+
return this.loadOutputsParallel(responseDto, cancelRequest, taskEventInfo);
|
|
1491
|
+
} else {
|
|
1492
|
+
// default case, we load the outputs and return the nodes
|
|
1493
|
+
this.updateResponseDto(responseDto);
|
|
1494
|
+
return this.loadOutputs(cancelRequest, taskEventInfo);
|
|
1495
|
+
}
|
|
1496
|
+
} else {
|
|
1497
|
+
// special case, we don't load the outputs and only return the responseDto
|
|
1498
|
+
return responseDto;
|
|
1499
|
+
}
|
|
1340
1500
|
} catch (e) {
|
|
1341
1501
|
await this.handleError(e, retry);
|
|
1342
1502
|
if (cancelRequest()) return new SessionTreeNode();
|
|
1343
|
-
return await this.customizeSession(parameters, cancelRequest, taskEventInfo, parallel, true);
|
|
1503
|
+
return await this.customizeSession(parameters, cancelRequest, taskEventInfo, parallel, loadOutputs, true);
|
|
1344
1504
|
}
|
|
1345
1505
|
}
|
|
1346
1506
|
|
|
@@ -1350,8 +1510,8 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1350
1510
|
// case 1: the session is no longer available
|
|
1351
1511
|
// we try to re-initialize the session 3 times, if that does not work, we close it
|
|
1352
1512
|
|
|
1353
|
-
this._logger.warn(
|
|
1354
|
-
if(this._sessionId) this._httpClient.removeDataLoading(this._sessionId)
|
|
1513
|
+
this._logger.warn('The session has been closed, trying to re-initialize.');
|
|
1514
|
+
if (this._sessionId) this._httpClient.removeDataLoading(this._sessionId);
|
|
1355
1515
|
|
|
1356
1516
|
if (this._retryCounter < 3) {
|
|
1357
1517
|
// we retry this 3 times, the `retry` option in the init function is set to true and passed on
|
|
@@ -1361,6 +1521,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1361
1521
|
} else {
|
|
1362
1522
|
// the retries were exceeded, we close the session
|
|
1363
1523
|
this._logger.warn('Tried to retry the connect multiple times, bearer token still not valid. Closing Session.');
|
|
1524
|
+
// eslint-disable-next-line no-empty
|
|
1364
1525
|
try { await this._closeOnFailure(); } catch (e) { }
|
|
1365
1526
|
throw this._httpClient.convertError(e);
|
|
1366
1527
|
}
|
|
@@ -1375,12 +1536,14 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1375
1536
|
} else {
|
|
1376
1537
|
// no bearer tokens are supplied, we close the session
|
|
1377
1538
|
this._logger.warn('No retry possible, no new bearer token was supplied. Closing Session.');
|
|
1539
|
+
// eslint-disable-next-line no-empty
|
|
1378
1540
|
try { await this._closeOnFailure(); } catch (e) { }
|
|
1379
1541
|
throw this._httpClient.convertError(e);
|
|
1380
1542
|
}
|
|
1381
1543
|
} else {
|
|
1382
1544
|
// the retries were exceeded, we close the session
|
|
1383
1545
|
this._logger.warn('Tried to retry the connect multiple times, bearer token still not valid. Closing Session.');
|
|
1546
|
+
// eslint-disable-next-line no-empty
|
|
1384
1547
|
try { await this._closeOnFailure(); } catch (e) { }
|
|
1385
1548
|
throw this._httpClient.convertError(e);
|
|
1386
1549
|
}
|
|
@@ -1403,7 +1566,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1403
1566
|
* @param ms the milliseconds
|
|
1404
1567
|
* @returns promise that resolve after specified milliseconds
|
|
1405
1568
|
*/
|
|
1406
|
-
private async timeout(ms: number): Promise<
|
|
1569
|
+
private async timeout(ms: number): Promise<unknown> {
|
|
1407
1570
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
1408
1571
|
}
|
|
1409
1572
|
|
|
@@ -1417,7 +1580,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1417
1580
|
|
|
1418
1581
|
// convert parameters
|
|
1419
1582
|
if (responseDto.parameters) {
|
|
1420
|
-
for (
|
|
1583
|
+
for (const parameterId in responseDto.parameters) {
|
|
1421
1584
|
this._responseDto.parameters = this._responseDto.parameters || {};
|
|
1422
1585
|
this._responseDto.parameters[parameterId] = this._responseDto.parameters[parameterId] || responseDto.parameters[parameterId];
|
|
1423
1586
|
}
|
|
@@ -1425,7 +1588,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1425
1588
|
|
|
1426
1589
|
// convert outputs
|
|
1427
1590
|
if (responseDto.outputs) {
|
|
1428
|
-
for (
|
|
1591
|
+
for (const outputId in responseDto.outputs) {
|
|
1429
1592
|
this._responseDto.outputs = this._responseDto.outputs || {};
|
|
1430
1593
|
if ('version' in responseDto.outputs[outputId] || !(this._responseDto.outputs[outputId] && 'version' in this._responseDto.outputs[outputId]))
|
|
1431
1594
|
this._responseDto.outputs[outputId] = responseDto.outputs[outputId];
|
|
@@ -1434,7 +1597,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1434
1597
|
|
|
1435
1598
|
// convert exports
|
|
1436
1599
|
if (responseDto.exports) {
|
|
1437
|
-
for (
|
|
1600
|
+
for (const exportId in responseDto.exports) {
|
|
1438
1601
|
this._responseDto.exports = this._responseDto.exports || {};
|
|
1439
1602
|
if ('version' in responseDto.exports[exportId] || !(this._responseDto.exports[exportId] && 'version' in this._responseDto.exports[exportId]))
|
|
1440
1603
|
this._responseDto.exports[exportId] = responseDto.exports[exportId];
|
|
@@ -1443,12 +1606,12 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1443
1606
|
|
|
1444
1607
|
const parameterSet: {
|
|
1445
1608
|
[key: string]: {
|
|
1446
|
-
value:
|
|
1609
|
+
value: unknown,
|
|
1447
1610
|
valueString: string
|
|
1448
1611
|
}
|
|
1449
1612
|
} = {};
|
|
1450
1613
|
|
|
1451
|
-
for (
|
|
1614
|
+
for (const parameterId in this._responseDto.parameters) {
|
|
1452
1615
|
if (this.parameters[parameterId]) continue;
|
|
1453
1616
|
this._responseDto.parameters[parameterId].id = parameterId;
|
|
1454
1617
|
|
|
@@ -1471,15 +1634,15 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1471
1634
|
}
|
|
1472
1635
|
|
|
1473
1636
|
// we don't have to do larger restrictions for this as the backend would have already thrown an error if the values were not correct
|
|
1474
|
-
if(initialParameters) {
|
|
1637
|
+
if (initialParameters) {
|
|
1475
1638
|
// check if the id is within the initial parameters
|
|
1476
|
-
if(initialParameters[parameterId] !== undefined) {
|
|
1477
|
-
this.parameters[parameterId].value = initialParameters[parameterId]
|
|
1478
|
-
}
|
|
1639
|
+
if (initialParameters[parameterId] !== undefined) {
|
|
1640
|
+
this.parameters[parameterId].value = initialParameters[parameterId];
|
|
1641
|
+
}
|
|
1479
1642
|
// check if the name is within the initial parameters
|
|
1480
|
-
else if(initialParameters[this.parameters[parameterId].name] !== undefined) {
|
|
1643
|
+
else if (initialParameters[this.parameters[parameterId].name] !== undefined) {
|
|
1481
1644
|
this.parameters[parameterId].value = initialParameters[this.parameters[parameterId].name];
|
|
1482
|
-
}
|
|
1645
|
+
}
|
|
1483
1646
|
// NOTE: At some point the checking may also be done with the displayname, this is the code for it
|
|
1484
1647
|
// // check if the displayname is within the initial parameters
|
|
1485
1648
|
// else if(this.parameters[parameterId].displayname && initialParameters[this.parameters[parameterId].displayname!] !== undefined) {
|
|
@@ -1490,7 +1653,7 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1490
1653
|
parameterSet[parameterId] = {
|
|
1491
1654
|
value: this.parameters[parameterId].value,
|
|
1492
1655
|
valueString: this.parameters[parameterId].stringify()
|
|
1493
|
-
}
|
|
1656
|
+
};
|
|
1494
1657
|
|
|
1495
1658
|
if (!this.initialized)
|
|
1496
1659
|
this.parameterValues[parameterId] = parameterSet[parameterId].valueString;
|
|
@@ -1500,27 +1663,46 @@ export class SessionEngine implements ISessionEngine {
|
|
|
1500
1663
|
if (!this.initialized)
|
|
1501
1664
|
this.#parameterHistory.push(parameterSet);
|
|
1502
1665
|
|
|
1503
|
-
for (
|
|
1666
|
+
for (const exportId in this._responseDto.exports) {
|
|
1504
1667
|
if (this._responseDto.exports[exportId].type === ShapeDiverResponseExportDefinitionType.EMAIL || this._responseDto.exports[exportId].type === ShapeDiverResponseExportDefinitionType.DOWNLOAD) {
|
|
1505
|
-
if(!this.exports[exportId]) {
|
|
1668
|
+
if (!this.exports[exportId]) {
|
|
1506
1669
|
this._responseDto.exports[exportId].id = exportId;
|
|
1507
1670
|
this.exports[exportId] = new Export(this._responseDto.exports[exportId], this);
|
|
1508
1671
|
} else {
|
|
1509
|
-
this.exports[exportId].updateExportDefinition(this._responseDto.exports[exportId])
|
|
1672
|
+
this.exports[exportId].updateExportDefinition(this._responseDto.exports[exportId]);
|
|
1510
1673
|
}
|
|
1511
1674
|
}
|
|
1512
1675
|
}
|
|
1513
1676
|
|
|
1514
|
-
for (
|
|
1515
|
-
if(!this.outputs[outputId]) {
|
|
1677
|
+
for (const outputId in this._responseDto.outputs) {
|
|
1678
|
+
if (!this.outputs[outputId]) {
|
|
1516
1679
|
this._responseDto.outputs[outputId].id = outputId;
|
|
1517
1680
|
if (this.outputsFreeze[outputId] === undefined) this.outputsFreeze[outputId] = false;
|
|
1518
1681
|
this.outputs[outputId] = new Output(<ShapeDiverResponseOutput>this._responseDto.outputs[outputId], this);
|
|
1519
1682
|
} else {
|
|
1520
|
-
this.outputs[outputId].updateOutputDefinition(<ShapeDiverResponseOutput>this._responseDto.outputs[outputId])
|
|
1683
|
+
this.outputs[outputId].updateOutputDefinition(<ShapeDiverResponseOutput>this._responseDto.outputs[outputId]);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
private async waitForUpdateCallbacks(newOutputVersions: { [key: string]: string }, oldOutputVersions: { [key: string]: string }, newNode: ITreeNode, oldNode: ITreeNode) {
|
|
1689
|
+
// call the update callback function on the session
|
|
1690
|
+
if (this._updateCallback) await Promise.resolve(this._updateCallback(newNode, oldNode));
|
|
1691
|
+
|
|
1692
|
+
const promises = [];
|
|
1693
|
+
// call the update callback functions on the outputs
|
|
1694
|
+
for (const outputId in this.outputs) {
|
|
1695
|
+
if (oldOutputVersions[outputId] !== newOutputVersions[outputId]) {
|
|
1696
|
+
promises.push(
|
|
1697
|
+
this.outputs[outputId].triggerUpdateCallback(
|
|
1698
|
+
newNode.children.find(c => c.name === outputId)!,
|
|
1699
|
+
oldNode.children.find(c => c.name === outputId)!
|
|
1700
|
+
)
|
|
1701
|
+
);
|
|
1521
1702
|
}
|
|
1522
1703
|
}
|
|
1704
|
+
await Promise.all(promises);
|
|
1523
1705
|
}
|
|
1524
1706
|
|
|
1525
|
-
// #endregion Private Methods (
|
|
1707
|
+
// #endregion Private Methods (13)
|
|
1526
1708
|
}
|