1 |
|
2 |
|
3 |
|
4 |
|
5 | import type * as Workspace from '../workspace/workspace.js';
|
6 |
|
7 | export interface LiveLocation {
|
8 | update(): Promise<void>;
|
9 | uiLocation(): Promise<Workspace.UISourceCode.UILocation|null>;
|
10 | dispose(): void;
|
11 | isIgnoreListed(): Promise<boolean>;
|
12 | }
|
13 |
|
14 | export class LiveLocationWithPool implements LiveLocation {
|
15 | #updateDelegate: ((arg0: LiveLocation) => Promise<void>)|null;
|
16 | readonly #locationPool: LiveLocationPool;
|
17 | #updatePromise: Promise<void>|null;
|
18 |
|
19 | constructor(updateDelegate: (arg0: LiveLocation) => Promise<void>, locationPool: LiveLocationPool) {
|
20 | this.#updateDelegate = updateDelegate;
|
21 | this.#locationPool = locationPool;
|
22 | this.#locationPool.add(this);
|
23 |
|
24 | this.#updatePromise = null;
|
25 | }
|
26 |
|
27 | async update(): Promise<void> {
|
28 | if (!this.#updateDelegate) {
|
29 | return;
|
30 | }
|
31 | // The following is a basic scheduling algorithm, guaranteeing that
|
32 | // {#updateDelegate} is always run atomically. That is, we always
|
33 | // wait for an update to finish before we trigger the next run.
|
34 | if (this.#updatePromise) {
|
35 | await this.#updatePromise.then(() => this.update());
|
36 | } else {
|
37 | this.#updatePromise = this.#updateDelegate(this);
|
38 | await this.#updatePromise;
|
39 | this.#updatePromise = null;
|
40 | }
|
41 | }
|
42 |
|
43 | async uiLocation(): Promise<Workspace.UISourceCode.UILocation|null> {
|
44 | throw 'Not implemented';
|
45 | }
|
46 |
|
47 | dispose(): void {
|
48 | this.#locationPool.delete(this);
|
49 | this.#updateDelegate = null;
|
50 | }
|
51 |
|
52 | async isIgnoreListed(): Promise<boolean> {
|
53 | throw 'Not implemented';
|
54 | }
|
55 | }
|
56 |
|
57 | export class LiveLocationPool {
|
58 | readonly #locations: Set<LiveLocation>;
|
59 |
|
60 | constructor() {
|
61 | this.#locations = new Set();
|
62 | }
|
63 |
|
64 | add(location: LiveLocation): void {
|
65 | this.#locations.add(location);
|
66 | }
|
67 |
|
68 | delete(location: LiveLocation): void {
|
69 | this.#locations.delete(location);
|
70 | }
|
71 |
|
72 | disposeAll(): void {
|
73 | for (const location of this.#locations) {
|
74 | location.dispose();
|
75 | }
|
76 | }
|
77 | }
|
78 |
|
\ | No newline at end of file |