simplify ReferenceCollection

This commit is contained in:
Joao Moreno 2016-11-22 10:43:08 +01:00
parent b560a80a6e
commit 6913eb58d3
3 changed files with 17 additions and 30 deletions

View file

@ -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> {

View file

@ -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', () => {

View file

@ -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() }));
}