@itwin/core-frontend 5.15.0-dev.2 → 5.15.0-dev.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -1
- package/lib/cjs/GeoServices.d.ts +13 -3
- package/lib/cjs/GeoServices.d.ts.map +1 -1
- package/lib/cjs/GeoServices.js +51 -18
- package/lib/cjs/GeoServices.js.map +1 -1
- package/lib/cjs/IModelApp.d.ts +19 -1
- package/lib/cjs/IModelApp.d.ts.map +1 -1
- package/lib/cjs/IModelApp.js +15 -0
- package/lib/cjs/IModelApp.js.map +1 -1
- package/lib/cjs/IModelConnection.d.ts +14 -8
- package/lib/cjs/IModelConnection.d.ts.map +1 -1
- package/lib/cjs/IModelConnection.js +24 -5
- package/lib/cjs/IModelConnection.js.map +1 -1
- package/lib/cjs/RealityDataSourceCesiumIonAssetImpl.d.ts.map +1 -1
- package/lib/cjs/RealityDataSourceCesiumIonAssetImpl.js +7 -14
- package/lib/cjs/RealityDataSourceCesiumIonAssetImpl.js.map +1 -1
- package/lib/cjs/extension/ExtensionRuntime.js +1 -0
- package/lib/cjs/extension/ExtensionRuntime.js.map +1 -1
- package/lib/cjs/internal/tile/OrbitGtTileTree.d.ts.map +1 -1
- package/lib/cjs/internal/tile/OrbitGtTileTree.js +16 -5
- package/lib/cjs/internal/tile/OrbitGtTileTree.js.map +1 -1
- package/lib/cjs/quantity-formatting/FormatsProviderReloadCoordinator.d.ts +53 -0
- package/lib/cjs/quantity-formatting/FormatsProviderReloadCoordinator.d.ts.map +1 -0
- package/lib/cjs/quantity-formatting/FormatsProviderReloadCoordinator.js +145 -0
- package/lib/cjs/quantity-formatting/FormatsProviderReloadCoordinator.js.map +1 -0
- package/lib/cjs/quantity-formatting/QuantityFormatter.d.ts +23 -34
- package/lib/cjs/quantity-formatting/QuantityFormatter.d.ts.map +1 -1
- package/lib/cjs/quantity-formatting/QuantityFormatter.js +107 -93
- package/lib/cjs/quantity-formatting/QuantityFormatter.js.map +1 -1
- package/lib/cjs/quantity-formatting/UnitsData.d.ts.map +1 -1
- package/lib/cjs/quantity-formatting/UnitsData.js +3 -0
- package/lib/cjs/quantity-formatting/UnitsData.js.map +1 -1
- package/lib/cjs/tile/map/CesiumTerrainProvider.d.ts +27 -6
- package/lib/cjs/tile/map/CesiumTerrainProvider.d.ts.map +1 -1
- package/lib/cjs/tile/map/CesiumTerrainProvider.js +51 -21
- package/lib/cjs/tile/map/CesiumTerrainProvider.js.map +1 -1
- package/lib/cjs/tile/map/MapLayerAuthentication.js.map +1 -1
- package/lib/cjs/tools/ToolAdmin.d.ts +7 -0
- package/lib/cjs/tools/ToolAdmin.d.ts.map +1 -1
- package/lib/cjs/tools/ToolAdmin.js +23 -2
- package/lib/cjs/tools/ToolAdmin.js.map +1 -1
- package/lib/esm/GeoServices.d.ts +13 -3
- package/lib/esm/GeoServices.d.ts.map +1 -1
- package/lib/esm/GeoServices.js +51 -18
- package/lib/esm/GeoServices.js.map +1 -1
- package/lib/esm/IModelApp.d.ts +19 -1
- package/lib/esm/IModelApp.d.ts.map +1 -1
- package/lib/esm/IModelApp.js +15 -0
- package/lib/esm/IModelApp.js.map +1 -1
- package/lib/esm/IModelConnection.d.ts +14 -8
- package/lib/esm/IModelConnection.d.ts.map +1 -1
- package/lib/esm/IModelConnection.js +24 -5
- package/lib/esm/IModelConnection.js.map +1 -1
- package/lib/esm/RealityDataSourceCesiumIonAssetImpl.d.ts.map +1 -1
- package/lib/esm/RealityDataSourceCesiumIonAssetImpl.js +7 -14
- package/lib/esm/RealityDataSourceCesiumIonAssetImpl.js.map +1 -1
- package/lib/esm/extension/ExtensionRuntime.js +2 -1
- package/lib/esm/extension/ExtensionRuntime.js.map +1 -1
- package/lib/esm/internal/tile/OrbitGtTileTree.d.ts.map +1 -1
- package/lib/esm/internal/tile/OrbitGtTileTree.js +16 -5
- package/lib/esm/internal/tile/OrbitGtTileTree.js.map +1 -1
- package/lib/esm/quantity-formatting/FormatsProviderReloadCoordinator.d.ts +53 -0
- package/lib/esm/quantity-formatting/FormatsProviderReloadCoordinator.d.ts.map +1 -0
- package/lib/esm/quantity-formatting/FormatsProviderReloadCoordinator.js +140 -0
- package/lib/esm/quantity-formatting/FormatsProviderReloadCoordinator.js.map +1 -0
- package/lib/esm/quantity-formatting/QuantityFormatter.d.ts +23 -34
- package/lib/esm/quantity-formatting/QuantityFormatter.d.ts.map +1 -1
- package/lib/esm/quantity-formatting/QuantityFormatter.js +107 -93
- package/lib/esm/quantity-formatting/QuantityFormatter.js.map +1 -1
- package/lib/esm/quantity-formatting/UnitsData.d.ts.map +1 -1
- package/lib/esm/quantity-formatting/UnitsData.js +3 -0
- package/lib/esm/quantity-formatting/UnitsData.js.map +1 -1
- package/lib/esm/tile/map/CesiumTerrainProvider.d.ts +27 -6
- package/lib/esm/tile/map/CesiumTerrainProvider.d.ts.map +1 -1
- package/lib/esm/tile/map/CesiumTerrainProvider.js +50 -22
- package/lib/esm/tile/map/CesiumTerrainProvider.js.map +1 -1
- package/lib/esm/tile/map/MapLayerAuthentication.js.map +1 -1
- package/lib/esm/tools/ToolAdmin.d.ts +7 -0
- package/lib/esm/tools/ToolAdmin.d.ts.map +1 -1
- package/lib/esm/tools/ToolAdmin.js +23 -2
- package/lib/esm/tools/ToolAdmin.js.map +1 -1
- package/lib/public/locales/en/iModelJs.json +3 -1
- package/lib/public/scripts/parse-imdl-worker.js +2 -2
- package/lib/test-public/scripts/checkbrowser.js +24 -0
- package/lib/test-public/scripts/draco_encoder.js +52 -0
- package/lib/test-public/scripts/draco_wasm_wrapper.js +117 -0
- package/lib/test-public/scripts/parse-imdl-worker.js +2 -0
- package/lib/test-public/test-worker.js +1 -0
- package/package.json +22 -23
|
@@ -15,6 +15,7 @@ const core_quantity_1 = require("@itwin/core-quantity");
|
|
|
15
15
|
const FrontendLoggerCategory_1 = require("../common/FrontendLoggerCategory");
|
|
16
16
|
const IModelApp_1 = require("../IModelApp");
|
|
17
17
|
const AlternateUnitLabels_1 = require("./AlternateUnitLabels");
|
|
18
|
+
const FormatsProviderReloadCoordinator_1 = require("./FormatsProviderReloadCoordinator");
|
|
18
19
|
// cSpell:ignore FORMATPROPS FORMATKEY ussurvey uscustomary USCUSTOM
|
|
19
20
|
/**
|
|
20
21
|
* Defines standard format types for tools that need to display measurements to user.
|
|
@@ -49,7 +50,12 @@ var QuantityType;
|
|
|
49
50
|
class AlternateUnitLabelsRegistry {
|
|
50
51
|
_alternateLabelRegistry = new Map();
|
|
51
52
|
addAlternateLabels(key, ...labels) {
|
|
52
|
-
|
|
53
|
+
let entry = this._alternateLabelRegistry.get(key);
|
|
54
|
+
if (!entry) {
|
|
55
|
+
entry = new Set();
|
|
56
|
+
this._alternateLabelRegistry.set(key, entry);
|
|
57
|
+
}
|
|
58
|
+
labels.forEach((value) => entry.add(value));
|
|
53
59
|
}
|
|
54
60
|
constructor(defaultAlternates) {
|
|
55
61
|
if (defaultAlternates) {
|
|
@@ -201,12 +207,24 @@ class FormatsProviderManager {
|
|
|
201
207
|
}
|
|
202
208
|
get formatsProvider() { return this; }
|
|
203
209
|
set formatsProvider(formatsProvider) {
|
|
210
|
+
this.setFormatsProvider(formatsProvider);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Replaces the underlying formats provider and raises an event indicating that all formats changed.
|
|
214
|
+
* @param formatsProvider The formats provider to use for subsequent format lookups.
|
|
215
|
+
* @param impliedUnitSystem The unit system implied by the replacement provider, if any. Not stored here; [[QuantityFormatter]] applies it as the active unit system when handling `onFormatsChanged`.
|
|
216
|
+
* @internal
|
|
217
|
+
*/
|
|
218
|
+
setFormatsProvider(formatsProvider, impliedUnitSystem) {
|
|
204
219
|
this._removeProviderListener?.();
|
|
205
220
|
this._formatsProvider = formatsProvider;
|
|
206
221
|
this._removeProviderListener = this._formatsProvider.onFormatsChanged.addListener((args) => {
|
|
207
222
|
this.onFormatsChanged.raiseEvent(args);
|
|
208
223
|
});
|
|
209
|
-
|
|
224
|
+
const args = { formatsChanged: "all" };
|
|
225
|
+
if (impliedUnitSystem !== undefined)
|
|
226
|
+
args.impliedUnitSystem = impliedUnitSystem;
|
|
227
|
+
this.onFormatsChanged.raiseEvent(args);
|
|
210
228
|
}
|
|
211
229
|
}
|
|
212
230
|
exports.FormatsProviderManager = FormatsProviderManager;
|
|
@@ -288,10 +306,13 @@ class QuantityFormatter {
|
|
|
288
306
|
_hasEverBeenReady = false;
|
|
289
307
|
_initializedPromise;
|
|
290
308
|
_resolveInitialized;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
309
|
+
_emitSystemChangedOnReady = false;
|
|
310
|
+
_isDisposed = false;
|
|
311
|
+
_disposedError = new Error("QuantityFormatter was disposed before the reload completed.");
|
|
312
|
+
_reloadCoordinator;
|
|
294
313
|
_removeFormatsProviderListener;
|
|
314
|
+
_activeFormatSpecsTarget;
|
|
315
|
+
_activeParserSpecsTarget;
|
|
295
316
|
/**
|
|
296
317
|
* constructor
|
|
297
318
|
* @param showMetricOrUnitSystem - Pass in `true` to show Metric formatted quantity values. Defaults to Imperial. To explicitly
|
|
@@ -301,6 +322,12 @@ class QuantityFormatter {
|
|
|
301
322
|
this._initializedPromise = new Promise((resolve) => {
|
|
302
323
|
this._resolveInitialized = resolve;
|
|
303
324
|
});
|
|
325
|
+
this._reloadCoordinator = new FormatsProviderReloadCoordinator_1.FormatsProviderReloadCoordinator({
|
|
326
|
+
startReload: () => { this._isReady = false; },
|
|
327
|
+
executeReload: async (intent) => this._executeReload(intent),
|
|
328
|
+
finalizeReload: async () => this.finalizeReload(),
|
|
329
|
+
handleReloadFailure: (error) => this._handleReloadFailure(error),
|
|
330
|
+
}, this._disposedError);
|
|
304
331
|
if (undefined !== showMetricOrUnitSystem) {
|
|
305
332
|
if (typeof showMetricOrUnitSystem === "boolean")
|
|
306
333
|
this._activeUnitSystem = showMetricOrUnitSystem ? "metric" : "imperial";
|
|
@@ -309,70 +336,44 @@ class QuantityFormatter {
|
|
|
309
336
|
}
|
|
310
337
|
}
|
|
311
338
|
[Symbol.dispose]() {
|
|
339
|
+
if (this._isDisposed)
|
|
340
|
+
return;
|
|
341
|
+
this._isDisposed = true;
|
|
342
|
+
this._isReady = false;
|
|
343
|
+
this._emitSystemChangedOnReady = false;
|
|
344
|
+
this._reloadCoordinator.dispose();
|
|
312
345
|
if (this._removeFormatsProviderListener) {
|
|
313
346
|
this._removeFormatsProviderListener();
|
|
314
347
|
this._removeFormatsProviderListener = undefined;
|
|
315
348
|
}
|
|
316
349
|
}
|
|
350
|
+
/** Runs an action that schedules a reload and waits for the reload queue to drain.
|
|
351
|
+
* The most recent call wins. If another call is made before this reload queue drains, this call is rejected.
|
|
352
|
+
* @internal
|
|
353
|
+
*/
|
|
354
|
+
async runAndWaitForReload(action) {
|
|
355
|
+
return this._reloadCoordinator.runAndWaitForReload(action);
|
|
356
|
+
}
|
|
317
357
|
/** Schedule an async reload. If no reload is in flight, runs immediately. If a reload is
|
|
318
|
-
* already in flight, stores the intent as pending
|
|
319
|
-
*
|
|
358
|
+
* already in flight, stores the intent as pending. Pending format changes are merged and run before
|
|
359
|
+
* the latest other pending intent. `finalizeReload()` fires only when the queue is fully drained.
|
|
320
360
|
*
|
|
321
361
|
* **Await semantics:** When a reload is already in flight, the returned promise resolves
|
|
322
362
|
* immediately *without* the requested reload having run. Callers that need to know when
|
|
323
|
-
*
|
|
363
|
+
* an explicitly triggered reload has actually completed should use [[runAndWaitForReload]].
|
|
324
364
|
*
|
|
325
|
-
* Reload intents:
|
|
326
|
-
* - `"full"` — rebuild entire registry + re-register provider listener (onInitialized, setUnitsProvider)
|
|
327
|
-
* - `"formatsChanged"` — patch registry from provider + load maps (formatsChanged listener)
|
|
328
|
-
* - `"activeSystem"` — reload format/parsing maps for current unit system (setActiveUnitSystem, reinitializeFormatAndParsingsMaps)
|
|
329
365
|
* @internal
|
|
330
366
|
*/
|
|
331
367
|
async scheduleReload(intent) {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
368
|
+
return this._reloadCoordinator.scheduleReload(intent);
|
|
369
|
+
}
|
|
370
|
+
_handleReloadFailure(error) {
|
|
371
|
+
if (!this._isDisposed)
|
|
372
|
+
core_bentley_1.Logger.logError(`${FrontendLoggerCategory_1.FrontendLoggerCategory.Package}.QuantityFormatter`, core_bentley_1.BentleyError.getErrorMessage(error));
|
|
373
|
+
if (this._hasEverBeenReady && !this._isDisposed) {
|
|
374
|
+
core_bentley_1.Logger.logWarning(`${FrontendLoggerCategory_1.FrontendLoggerCategory.Package}.QuantityFormatter`, "Reload failed — restoring previous ready state. Cached specs may be stale.");
|
|
375
|
+
this._isReady = true;
|
|
336
376
|
}
|
|
337
|
-
this._reloadInFlight = true;
|
|
338
|
-
this._isReady = false;
|
|
339
|
-
this._deferredSystemChangedEmit = undefined; // Clear stale deferred from prior cycle
|
|
340
|
-
try {
|
|
341
|
-
await this._executeReload(intent);
|
|
342
|
-
}
|
|
343
|
-
catch (err) {
|
|
344
|
-
core_bentley_1.Logger.logError(`${FrontendLoggerCategory_1.FrontendLoggerCategory.Package}.QuantityFormatter`, core_bentley_1.BentleyError.getErrorMessage(err));
|
|
345
|
-
this._reloadInFlight = false;
|
|
346
|
-
// If there's a pending reload, still try to run it
|
|
347
|
-
if (this._pendingReload) {
|
|
348
|
-
const next = this._pendingReload;
|
|
349
|
-
this._pendingReload = undefined;
|
|
350
|
-
return this.scheduleReload(next);
|
|
351
|
-
}
|
|
352
|
-
// Restore prior ready state so stale-but-usable specs remain accessible
|
|
353
|
-
if (this._hasEverBeenReady) {
|
|
354
|
-
core_bentley_1.Logger.logWarning(`${FrontendLoggerCategory_1.FrontendLoggerCategory.Package}.QuantityFormatter`, "Reload failed — restoring previous ready state. Cached specs may be stale.");
|
|
355
|
-
this._isReady = true;
|
|
356
|
-
}
|
|
357
|
-
return;
|
|
358
|
-
}
|
|
359
|
-
// Current reload succeeded — check if another was queued
|
|
360
|
-
if (this._pendingReload) {
|
|
361
|
-
const next = this._pendingReload;
|
|
362
|
-
this._pendingReload = undefined;
|
|
363
|
-
this._reloadInFlight = false;
|
|
364
|
-
return this.scheduleReload(next);
|
|
365
|
-
}
|
|
366
|
-
// Queue is drained — finalize
|
|
367
|
-
await this.finalizeReload();
|
|
368
|
-
// A new reload may have been queued during the async finalizeReload window
|
|
369
|
-
if (this._pendingReload) {
|
|
370
|
-
const next = this._pendingReload;
|
|
371
|
-
this._pendingReload = undefined;
|
|
372
|
-
this._reloadInFlight = false;
|
|
373
|
-
return this.scheduleReload(next);
|
|
374
|
-
}
|
|
375
|
-
this._reloadInFlight = false;
|
|
376
377
|
}
|
|
377
378
|
/** Execute the reload work for a given intent. All reload logic is centralized here.
|
|
378
379
|
* @internal
|
|
@@ -381,47 +382,51 @@ class QuantityFormatter {
|
|
|
381
382
|
switch (intent.scope) {
|
|
382
383
|
case "full":
|
|
383
384
|
await this._reloadCore();
|
|
385
|
+
return;
|
|
386
|
+
case "formatsChanged":
|
|
387
|
+
await this._rebuildRegistryFromProvider(intent.args);
|
|
384
388
|
break;
|
|
385
|
-
case "formatsChanged": {
|
|
386
|
-
const { args } = intent;
|
|
387
|
-
await this._rebuildRegistryFromProvider(args);
|
|
388
|
-
if (args.impliedUnitSystem && args.impliedUnitSystem !== this._activeUnitSystem) {
|
|
389
|
-
this._activeUnitSystem = args.impliedUnitSystem;
|
|
390
|
-
}
|
|
391
|
-
await this.loadFormatAndParsingMapsForSystem(this._activeUnitSystem);
|
|
392
|
-
if (args.impliedUnitSystem) {
|
|
393
|
-
this._deferredSystemChangedEmit = { system: this._activeUnitSystem };
|
|
394
|
-
}
|
|
395
|
-
break;
|
|
396
|
-
}
|
|
397
|
-
case "activeSystem":
|
|
398
|
-
await this.loadFormatAndParsingMapsForSystem(this._activeUnitSystem);
|
|
399
|
-
if (intent.emitSystemChanged) {
|
|
400
|
-
this._deferredSystemChangedEmit = { system: this._activeUnitSystem };
|
|
401
|
-
}
|
|
402
|
-
break;
|
|
403
389
|
}
|
|
390
|
+
// Build the active specs in temporary maps so readers keep using complete specs until the new ones are ready.
|
|
391
|
+
const nextFormatSpecs = new Map();
|
|
392
|
+
const nextParserSpecs = new Map();
|
|
393
|
+
this._activeFormatSpecsTarget = nextFormatSpecs;
|
|
394
|
+
this._activeParserSpecsTarget = nextParserSpecs;
|
|
395
|
+
try {
|
|
396
|
+
await this.loadFormatAndParsingMapsForSystem(this._activeUnitSystem);
|
|
397
|
+
}
|
|
398
|
+
finally {
|
|
399
|
+
this._activeFormatSpecsTarget = undefined;
|
|
400
|
+
this._activeParserSpecsTarget = undefined;
|
|
401
|
+
}
|
|
402
|
+
this._activeFormatSpecsByType = nextFormatSpecs;
|
|
403
|
+
this._activeParserSpecsByType = nextParserSpecs;
|
|
404
404
|
}
|
|
405
405
|
/** Called when the reload queue is fully drained after a successful reload.
|
|
406
406
|
* Sets `isReady` to true, resolves `whenInitialized` (one-shot), and emits ready events.
|
|
407
407
|
* @internal
|
|
408
408
|
*/
|
|
409
409
|
async finalizeReload() {
|
|
410
|
+
if (this._isDisposed)
|
|
411
|
+
return;
|
|
410
412
|
// Phase 1: Let providers register async work
|
|
411
413
|
const collector = new core_quantity_1.FormattingReadyCollector();
|
|
412
414
|
this.onBeforeFormattingReady.raiseEvent(collector);
|
|
413
415
|
await collector.awaitAll();
|
|
416
|
+
if (this._isDisposed)
|
|
417
|
+
return;
|
|
414
418
|
// Phase 2: Signal ready to consumers
|
|
415
419
|
this._isReady = true;
|
|
416
420
|
this._hasEverBeenReady = true;
|
|
417
421
|
this._resolveInitialized();
|
|
418
422
|
this.onFormattingReady.emit();
|
|
419
|
-
|
|
423
|
+
if (this._isDisposed)
|
|
424
|
+
return;
|
|
425
|
+
// Phase 3: Emit unit-system-changed if the unit system was changed since the last ready state, reporting the system that is now active.
|
|
420
426
|
// This fires after isReady === true so listeners can safely use the formatter.
|
|
421
|
-
if (this.
|
|
422
|
-
|
|
423
|
-
this.
|
|
424
|
-
this.onActiveFormattingUnitSystemChanged.emit(args);
|
|
427
|
+
if (this._emitSystemChangedOnReady) {
|
|
428
|
+
this._emitSystemChangedOnReady = false;
|
|
429
|
+
this.onActiveFormattingUnitSystemChanged.emit({ system: this._activeUnitSystem });
|
|
425
430
|
}
|
|
426
431
|
}
|
|
427
432
|
getOverrideFormatPropsByQuantityType(quantityTypeKey, unitSystem) {
|
|
@@ -492,8 +497,8 @@ class QuantityFormatter {
|
|
|
492
497
|
async loadFormatAndParserSpec(quantityTypeDefinition, formatProps) {
|
|
493
498
|
const formatterSpec = await quantityTypeDefinition.generateFormatterSpec(formatProps, this.unitsProvider);
|
|
494
499
|
const parserSpec = await quantityTypeDefinition.generateParserSpec(formatProps, this.unitsProvider, this.alternateUnitLabelsProvider);
|
|
495
|
-
this._activeFormatSpecsByType.set(quantityTypeDefinition.key, formatterSpec);
|
|
496
|
-
this._activeParserSpecsByType.set(quantityTypeDefinition.key, parserSpec);
|
|
500
|
+
(this._activeFormatSpecsTarget ?? this._activeFormatSpecsByType).set(quantityTypeDefinition.key, formatterSpec);
|
|
501
|
+
(this._activeParserSpecsTarget ?? this._activeParserSpecsByType).set(quantityTypeDefinition.key, parserSpec);
|
|
497
502
|
}
|
|
498
503
|
// repopulate formatSpec and parserSpec entries using only default format
|
|
499
504
|
async loadDefaultFormatAndParserSpecForQuantity(typeKey) {
|
|
@@ -550,17 +555,20 @@ class QuantityFormatter {
|
|
|
550
555
|
* @internal
|
|
551
556
|
*/
|
|
552
557
|
async onInitialized() {
|
|
558
|
+
// Register once, before the first reload, so provider changes made while a units-provider reload is running are not missed.
|
|
559
|
+
this._removeFormatsProviderListener ??= IModelApp_1.IModelApp.formatsProvider.onFormatsChanged.addListener((args) => {
|
|
560
|
+
if (args.impliedUnitSystem && args.impliedUnitSystem !== this._activeUnitSystem) {
|
|
561
|
+
this._activeUnitSystem = args.impliedUnitSystem;
|
|
562
|
+
this._emitSystemChangedOnReady = true;
|
|
563
|
+
}
|
|
564
|
+
void this.scheduleReload({ scope: "formatsChanged", args });
|
|
565
|
+
});
|
|
553
566
|
await this.scheduleReload({ scope: "full" });
|
|
554
567
|
}
|
|
555
568
|
/** Core reload logic — does all async I/O and cache rebuilding without events or state management.
|
|
556
569
|
* @internal
|
|
557
570
|
*/
|
|
558
571
|
async _reloadCore() {
|
|
559
|
-
// Remove any existing listener before re-registering to avoid duplicates when called via setUnitsProvider.
|
|
560
|
-
if (this._removeFormatsProviderListener) {
|
|
561
|
-
this._removeFormatsProviderListener();
|
|
562
|
-
this._removeFormatsProviderListener = undefined;
|
|
563
|
-
}
|
|
564
572
|
await this.initializeQuantityTypesRegistry();
|
|
565
573
|
const initialKoQs = [["DefaultToolsUnits.LENGTH", "Units.M"], ["DefaultToolsUnits.ANGLE", "Units.RAD"], ["DefaultToolsUnits.AREA", "Units.SQ_M"], ["DefaultToolsUnits.VOLUME", "Units.CUB_M"], ["DefaultToolsUnits.LENGTH_COORDINATE", "Units.M"], ["CivilUnits.STATION", "Units.M"], ["CivilUnits.LENGTH", "Units.M"], ["AecUnits.LENGTH", "Units.M"]];
|
|
566
574
|
for (const entry of initialKoQs) {
|
|
@@ -573,10 +581,6 @@ class QuantityFormatter {
|
|
|
573
581
|
}
|
|
574
582
|
}
|
|
575
583
|
}
|
|
576
|
-
// Register formatsProvider listener that triggers a queued reload when formats change
|
|
577
|
-
this._removeFormatsProviderListener = IModelApp_1.IModelApp.formatsProvider.onFormatsChanged.addListener((args) => {
|
|
578
|
-
void this.scheduleReload({ scope: "formatsChanged", args });
|
|
579
|
-
});
|
|
580
584
|
// initialize default format and parsing specs
|
|
581
585
|
await this.loadFormatAndParsingMapsForSystem();
|
|
582
586
|
}
|
|
@@ -670,6 +674,9 @@ class QuantityFormatter {
|
|
|
670
674
|
await IModelApp_1.IModelApp.quantityFormatter.resetToUseInternalUnitsProvider();
|
|
671
675
|
return;
|
|
672
676
|
}
|
|
677
|
+
// Disposal can occur while the reload is awaited, so do not notify afterward.
|
|
678
|
+
if (this._isDisposed)
|
|
679
|
+
return;
|
|
673
680
|
this.onUnitsProviderChanged.emit();
|
|
674
681
|
}
|
|
675
682
|
/**
|
|
@@ -709,7 +716,11 @@ class QuantityFormatter {
|
|
|
709
716
|
this._overrideFormatPropsByUnitSystem = overrideFormatPropsByUnitSystem;
|
|
710
717
|
}
|
|
711
718
|
unitSystemKey && (this._activeUnitSystem = unitSystemKey);
|
|
712
|
-
|
|
719
|
+
if (fireUnitSystemChanged)
|
|
720
|
+
this._emitSystemChangedOnReady = true;
|
|
721
|
+
await this.scheduleReload({ scope: "activeSystem" });
|
|
722
|
+
if (this._isDisposed)
|
|
723
|
+
return;
|
|
713
724
|
IModelApp_1.IModelApp.toolAdmin && startDefaultTool && await IModelApp_1.IModelApp.toolAdmin.startDefaultTool();
|
|
714
725
|
}
|
|
715
726
|
/** Set the Active unit system to one of the supported types. This will asynchronously load the formatter and parser specs for the activated system. */
|
|
@@ -722,7 +733,10 @@ class QuantityFormatter {
|
|
|
722
733
|
if (this._activeUnitSystem === systemType)
|
|
723
734
|
return;
|
|
724
735
|
this._activeUnitSystem = systemType;
|
|
725
|
-
|
|
736
|
+
this._emitSystemChangedOnReady = true;
|
|
737
|
+
await this.scheduleReload({ scope: "activeSystem" });
|
|
738
|
+
if (this._isDisposed)
|
|
739
|
+
return;
|
|
726
740
|
// allow settings provider to store the change
|
|
727
741
|
await this._unitFormattingSettingsProvider?.storeUnitSystemSetting({ system: systemType });
|
|
728
742
|
if (IModelApp_1.IModelApp.toolAdmin && restartActiveTool)
|
|
@@ -847,7 +861,7 @@ class QuantityFormatter {
|
|
|
847
861
|
const entry = this.quantityTypesRegistry.get(quantityKey);
|
|
848
862
|
if (!entry)
|
|
849
863
|
throw new Error(`Unable to find registered quantity type with key ${quantityKey}`);
|
|
850
|
-
return entry.generateParserSpec(this.getFormatPropsByQuantityTypeEntryAndSystem(entry, requestedSystem), this.unitsProvider);
|
|
864
|
+
return entry.generateParserSpec(this.getFormatPropsByQuantityTypeEntryAndSystem(entry, requestedSystem), this.unitsProvider, this.alternateUnitLabelsProvider);
|
|
851
865
|
}
|
|
852
866
|
/** Asynchronous Call to get a ParserSpec for a QuantityType.
|
|
853
867
|
* @param type One of the built-in quantity types supported.
|
|
@@ -995,7 +1009,7 @@ class QuantityFormatter {
|
|
|
995
1009
|
const { persistenceUnitName, formatProps, formatName } = props;
|
|
996
1010
|
const persistenceUnitProps = await this._unitsProvider.findUnitByName(persistenceUnitName);
|
|
997
1011
|
const format = await core_quantity_1.Format.createFromJSON(formatName ?? "temp", this._unitsProvider, formatProps);
|
|
998
|
-
return core_quantity_1.ParserSpec.create(format, this._unitsProvider, persistenceUnitProps);
|
|
1012
|
+
return core_quantity_1.ParserSpec.create(format, this._unitsProvider, persistenceUnitProps, this.alternateUnitLabelsProvider);
|
|
999
1013
|
}
|
|
1000
1014
|
/**
|
|
1001
1015
|
* @beta
|