UNPKG

5.24 kBJavaScriptView Raw
1"use strict";
2// *****************************************************************************
3// Copyright (C) 2018 TypeFox and others.
4//
5// This program and the accompanying materials are made available under the
6// terms of the Eclipse Public License v. 2.0 which is available at
7// http://www.eclipse.org/legal/epl-2.0.
8//
9// This Source Code may also be made available under the following Secondary
10// Licenses when the conditions for such availability set forth in the Eclipse
11// Public License v. 2.0 are satisfied: GNU General Public License, version 2
12// with the GNU Classpath Exception which is available at
13// https://www.gnu.org/software/classpath/license.html.
14//
15// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
16// *****************************************************************************
17Object.defineProperty(exports, "__esModule", { value: true });
18exports.SyncReferenceCollection = exports.ReferenceCollection = exports.AbstractReferenceCollection = void 0;
19const disposable_1 = require("./disposable");
20const event_1 = require("./event");
21class 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}
90exports.AbstractReferenceCollection = AbstractReferenceCollection;
91class 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}
129exports.ReferenceCollection = ReferenceCollection;
130class 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}
152exports.SyncReferenceCollection = SyncReferenceCollection;
153//# sourceMappingURL=reference.js.map
\No newline at end of file