mirror of
https://github.com/Microsoft/vscode
synced 2024-09-19 02:26:04 +00:00
simplify ReferenceCollection
This commit is contained in:
parent
b560a80a6e
commit
6913eb58d3
|
@ -72,24 +72,23 @@ export interface IReference<T> extends IDisposable {
|
|||
readonly object: T;
|
||||
}
|
||||
|
||||
export abstract class ReferenceCollection<T, R> {
|
||||
export abstract class ReferenceCollection<T> {
|
||||
|
||||
private references: { [key: string]: { readonly object: R; counter: number; } } = Object.create(null);
|
||||
private references: { [key: string]: { readonly object: T; counter: number; } } = Object.create(null);
|
||||
|
||||
constructor() { }
|
||||
|
||||
acquire(t: T): IReference<R> {
|
||||
const key = this.getKey(t);
|
||||
acquire(key: string): IReference<T> {
|
||||
let reference = this.references[key];
|
||||
|
||||
if (!reference) {
|
||||
reference = this.references[key] = { counter: 0, object: this.create(key) };
|
||||
reference = this.references[key] = { counter: 0, object: this.createReferencedObject(key) };
|
||||
}
|
||||
|
||||
const { object } = reference;
|
||||
const dispose = () => {
|
||||
if (--reference.counter === 0) {
|
||||
this.destroy(reference.object);
|
||||
this.destroyReferencedObject(reference.object);
|
||||
delete this.references[key];
|
||||
}
|
||||
};
|
||||
|
@ -99,9 +98,8 @@ export abstract class ReferenceCollection<T, R> {
|
|||
return { object, dispose };
|
||||
}
|
||||
|
||||
protected abstract getKey(t: T): string;
|
||||
protected abstract create(key: string): R;
|
||||
protected abstract destroy(object: R): void;
|
||||
protected abstract createReferencedObject(key: string): T;
|
||||
protected abstract destroyReferencedObject(object: T): void;
|
||||
}
|
||||
|
||||
export class ImmortalReference<T> implements IReference<T> {
|
||||
|
|
|
@ -52,12 +52,11 @@ suite('Lifecycle', () => {
|
|||
});
|
||||
|
||||
suite('Reference Collection', () => {
|
||||
class Collection extends ReferenceCollection<string, number> {
|
||||
class Collection extends ReferenceCollection<number> {
|
||||
private _count = 0;
|
||||
get count() { return this._count; }
|
||||
protected getKey(key): string { return key; }
|
||||
protected create(key: string): number { this._count++; return key.length; }
|
||||
protected destroy(object: number): void { this._count--; }
|
||||
protected createReferencedObject(key: string): number { this._count++; return key.length; }
|
||||
protected destroyReferencedObject(object: number): void { this._count--; }
|
||||
}
|
||||
|
||||
test('simple', () => {
|
||||
|
|
|
@ -17,34 +17,26 @@ import network = require('vs/base/common/network');
|
|||
import { ITextModelResolverService, ITextModelContentProvider, ITextEditorModel } from 'vs/editor/common/services/resolverService';
|
||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
||||
class ResourceModelCollection extends ReferenceCollection<URI, TPromise<ITextEditorModel>> {
|
||||
class ResourceModelCollection extends ReferenceCollection<TPromise<ITextEditorModel>> {
|
||||
|
||||
private providers: { [scheme: string]: ITextModelContentProvider[] } = Object.create(null);
|
||||
|
||||
constructor(
|
||||
@ITextFileService private textFileService: ITextFileService,
|
||||
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
|
||||
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IModelService private modelService: IModelService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
getKey(uri: URI): string {
|
||||
return uri.toString();
|
||||
}
|
||||
|
||||
create(key: string): TPromise<ITextEditorModel> {
|
||||
createReferencedObject(key: string): TPromise<ITextEditorModel> {
|
||||
const resource = URI.parse(key);
|
||||
|
||||
return this.resolveTextModelContent(this.modelService, key)
|
||||
.then(() => this.instantiationService.createInstance(ResourceEditorModel, resource));
|
||||
}
|
||||
|
||||
destroy(modelPromise: TPromise<ITextEditorModel>): void {
|
||||
destroyReferencedObject(modelPromise: TPromise<ITextEditorModel>): void {
|
||||
modelPromise.done(model => model.dispose());
|
||||
}
|
||||
|
||||
|
@ -107,9 +99,7 @@ export class TextModelResolverService implements ITextModelResolverService {
|
|||
constructor(
|
||||
@ITextFileService private textFileService: ITextFileService,
|
||||
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
|
||||
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IModelService private modelService: IModelService
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
) {
|
||||
this.resourceModelCollection = instantiationService.createInstance(ResourceModelCollection);
|
||||
}
|
||||
|
@ -122,12 +112,12 @@ export class TextModelResolverService implements ITextModelResolverService {
|
|||
return promise;
|
||||
}
|
||||
|
||||
promise = this.promiseCache[uri] = this.getModel(resource);
|
||||
promise = this.promiseCache[uri] = this._createModelReference(resource);
|
||||
|
||||
return always(promise, () => delete this.promiseCache[uri]);
|
||||
}
|
||||
|
||||
private getModel(resource: URI): TPromise<IReference<ITextEditorModel>> {
|
||||
private _createModelReference(resource: URI): TPromise<IReference<ITextEditorModel>> {
|
||||
// File Schema: use text file service
|
||||
// TODO ImmortalReference is a hack
|
||||
if (resource.scheme === network.Schemas.file) {
|
||||
|
@ -142,7 +132,7 @@ export class TextModelResolverService implements ITextModelResolverService {
|
|||
.then(model => new ImmortalReference(model));
|
||||
}
|
||||
|
||||
const ref = this.resourceModelCollection.acquire(resource);
|
||||
const ref = this.resourceModelCollection.acquire(resource.toString());
|
||||
return ref.object.then(model => ({ object: model, dispose: () => ref.dispose() }));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue