UNPKG

@giro3d/giro3d

Version:

A JS/WebGL framework for 3D geospatial data visualization

113 lines (93 loc) 2.62 kB
/* * Copyright (c) 2015-2018, IGN France. * Copyright (c) 2018-2026, Giro3D team. * SPDX-License-Identifier: MIT */ import { EventDispatcher } from 'three'; import type Progress from './Progress'; export interface OperationCounterEvents { /** * Raised when the counter is changed. */ changed: unknown; /** * Raised when all operations are completed. */ complete: unknown; } /** * Provides a way to track the progress of running operations. */ export class OperationCounter extends EventDispatcher<OperationCounterEvents> implements Progress { private _operations: number; private _completed: number; private _total: number; public constructor() { super(); this._operations = 0; this._completed = 0; this._total = 0; } /** * Gets the number of pending operations. */ public get operations(): number { return this._operations; } /** * Gets the number of completed operations. */ public get completed(): number { return this._completed; } /** * Gets whether at least one operation is being executed. */ public get loading(): boolean { return this._operations > 0; } /** * Returns a number between 0 and 1 which represent the ratio between * completed operations and total operations. */ public get progress(): number { if (this._operations === 0) { return 1; } return this._completed / this._total; } /** * Decrements the number of pending operations. */ public decrement(): void { if (this._operations === 0) { return; } this._operations--; this._completed++; this.dispatchEvent({ type: 'changed' }); if (this._operations === 0) { this._total = 0; this._completed = 0; this.dispatchEvent({ type: 'complete' }); } } /** * Increments the counter before starting the promise, then decrements it safely when the * promises resolves or fails. */ public wrap<T>(promise: Promise<T>): Promise<T> { this.increment(); return promise.finally(() => this.decrement()); } /** * Increment the number of pending operations. * @param count - How many increments to do. Default is 1. */ public increment(count = 1): void { this._operations += count; this._total += count; this.dispatchEvent({ type: 'changed' }); } } export default OperationCounter;