| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import type * as Workspace from '../workspace/workspace.js'; |
| |
| export interface LiveLocation { |
| update(): Promise<void>; |
| uiLocation(): Promise<Workspace.UISourceCode.UILocation|null>; |
| dispose(): void; |
| isDisposed(): boolean; |
| } |
| |
| export class LiveLocationWithPool implements LiveLocation { |
| #updateDelegate: ((arg0: LiveLocation) => Promise<void>)|null; |
| readonly #locationPool: LiveLocationPool; |
| #updatePromise: Promise<void>|null; |
| |
| constructor(updateDelegate: (arg0: LiveLocation) => Promise<void>, locationPool: LiveLocationPool) { |
| this.#updateDelegate = updateDelegate; |
| this.#locationPool = locationPool; |
| this.#locationPool.add(this); |
| |
| this.#updatePromise = null; |
| } |
| |
| async update(): Promise<void> { |
| if (!this.#updateDelegate) { |
| return; |
| } |
| // The following is a basic scheduling algorithm, guaranteeing that |
| // {#updateDelegate} is always run atomically. That is, we always |
| // wait for an update to finish before we trigger the next run. |
| if (this.#updatePromise) { |
| await this.#updatePromise.then(() => this.update()); |
| } else { |
| this.#updatePromise = this.#updateDelegate(this); |
| await this.#updatePromise; |
| this.#updatePromise = null; |
| } |
| } |
| |
| async uiLocation(): Promise<Workspace.UISourceCode.UILocation|null> { |
| throw new Error('Not implemented'); |
| } |
| |
| dispose(): void { |
| this.#locationPool.delete(this); |
| this.#updateDelegate = null; |
| } |
| |
| isDisposed(): boolean { |
| return !this.#locationPool.has(this); |
| } |
| } |
| |
| export class LiveLocationPool { |
| readonly #locations: Set<LiveLocation>; |
| |
| constructor() { |
| this.#locations = new Set(); |
| } |
| |
| add(location: LiveLocation): void { |
| this.#locations.add(location); |
| } |
| |
| delete(location: LiveLocation): void { |
| this.#locations.delete(location); |
| } |
| |
| has(location: LiveLocation): boolean { |
| return this.#locations.has(location); |
| } |
| |
| disposeAll(): void { |
| for (const location of this.#locations) { |
| location.dispose(); |
| } |
| } |
| } |