1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | Object.defineProperty(exports, "__esModule", { value: true });
|
18 | exports.SyncReferenceCollection = exports.ReferenceCollection = exports.AbstractReferenceCollection = void 0;
|
19 | const disposable_1 = require("./disposable");
|
20 | const event_1 = require("./event");
|
21 | class AbstractReferenceCollection {
|
22 | constructor() {
|
23 | this._keys = new Map();
|
24 | this._values = new Map();
|
25 | this.references = new Map();
|
26 | this.onDidCreateEmitter = new event_1.Emitter();
|
27 | this.onDidCreate = this.onDidCreateEmitter.event;
|
28 | this.onWillDisposeEmitter = new event_1.Emitter();
|
29 | this.onWillDispose = this.onWillDisposeEmitter.event;
|
30 | this.toDispose = new disposable_1.DisposableCollection();
|
31 | this.toDispose.push(this.onDidCreateEmitter);
|
32 | this.toDispose.push(this.onWillDisposeEmitter);
|
33 | this.toDispose.push(disposable_1.Disposable.create(() => this.clear()));
|
34 | }
|
35 | dispose() {
|
36 | this.toDispose.dispose();
|
37 | }
|
38 | clear() {
|
39 | for (const value of this._values.values()) {
|
40 | try {
|
41 | value.dispose();
|
42 | }
|
43 | catch (e) {
|
44 | console.error(e);
|
45 | }
|
46 | }
|
47 | }
|
48 | has(args) {
|
49 | const key = this.toKey(args);
|
50 | return this.references.has(key);
|
51 | }
|
52 | keys() {
|
53 | return [...this._keys.values()];
|
54 | }
|
55 | values() {
|
56 | return [...this._values.values()];
|
57 | }
|
58 | get(args) {
|
59 | const key = this.toKey(args);
|
60 | return this._values.get(key);
|
61 | }
|
62 | doAcquire(key, object) {
|
63 | const references = this.references.get(key) || this.createReferences(key, object);
|
64 | const reference = {
|
65 | object,
|
66 | dispose: () => { }
|
67 | };
|
68 | references.push(reference);
|
69 | return reference;
|
70 | }
|
71 | toKey(args) {
|
72 | return JSON.stringify(args);
|
73 | }
|
74 | createReferences(key, value) {
|
75 | const references = new disposable_1.DisposableCollection();
|
76 | references.onDispose(() => value.dispose());
|
77 | const disposeObject = value.dispose.bind(value);
|
78 | value.dispose = () => {
|
79 | this.onWillDisposeEmitter.fire(value);
|
80 | disposeObject();
|
81 | this._values.delete(key);
|
82 | this._keys.delete(key);
|
83 | this.references.delete(key);
|
84 | references.dispose();
|
85 | };
|
86 | this.references.set(key, references);
|
87 | return references;
|
88 | }
|
89 | }
|
90 | exports.AbstractReferenceCollection = AbstractReferenceCollection;
|
91 | class ReferenceCollection extends AbstractReferenceCollection {
|
92 | constructor(factory) {
|
93 | super();
|
94 | this.factory = factory;
|
95 | this.pendingValues = new Map();
|
96 | }
|
97 | async acquire(args) {
|
98 | const key = this.toKey(args);
|
99 | const existing = this._values.get(key);
|
100 | if (existing) {
|
101 | return this.doAcquire(key, existing);
|
102 | }
|
103 | const object = await this.getOrCreateValue(key, args);
|
104 | return this.doAcquire(key, object);
|
105 | }
|
106 | async getOrCreateValue(key, args) {
|
107 | const existing = this.pendingValues.get(key);
|
108 | if (existing) {
|
109 | return existing;
|
110 | }
|
111 | const pending = this.factory(args);
|
112 | this._keys.set(key, args);
|
113 | this.pendingValues.set(key, pending);
|
114 | try {
|
115 | const value = await pending;
|
116 | this._values.set(key, value);
|
117 | this.onDidCreateEmitter.fire(value);
|
118 | return value;
|
119 | }
|
120 | catch (e) {
|
121 | this._keys.delete(key);
|
122 | throw e;
|
123 | }
|
124 | finally {
|
125 | this.pendingValues.delete(key);
|
126 | }
|
127 | }
|
128 | }
|
129 | exports.ReferenceCollection = ReferenceCollection;
|
130 | class SyncReferenceCollection extends AbstractReferenceCollection {
|
131 | constructor(factory) {
|
132 | super();
|
133 | this.factory = factory;
|
134 | }
|
135 | acquire(args) {
|
136 | const key = this.toKey(args);
|
137 | const object = this.getOrCreateValue(key, args);
|
138 | return this.doAcquire(key, object);
|
139 | }
|
140 | getOrCreateValue(key, args) {
|
141 | const existing = this._values.get(key);
|
142 | if (existing) {
|
143 | return existing;
|
144 | }
|
145 | const value = this.factory(args);
|
146 | this._keys.set(key, args);
|
147 | this._values.set(key, value);
|
148 | this.onDidCreateEmitter.fire(value);
|
149 | return value;
|
150 | }
|
151 | }
|
152 | exports.SyncReferenceCollection = SyncReferenceCollection;
|
153 |
|
\ | No newline at end of file |