Skip to content

Commit

Permalink
don't use array, sorting, and array#delta but map and set, #35996
Browse files Browse the repository at this point in the history
  • Loading branch information
jrieken authored and egamma committed Oct 31, 2017
1 parent c97fa5f commit 83f3f31
Showing 1 changed file with 80 additions and 36 deletions.
116 changes: 80 additions & 36 deletions src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

import { IModelService } from 'vs/editor/common/services/modelService';
import { IModel, ICommonCodeEditor, isCommonCodeEditor, isCommonDiffEditor } from 'vs/editor/common/editorCommon';
import { compare } from 'vs/base/common/strings';
import { delta } from 'vs/base/common/arrays';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ICodeEditorService } from 'vs/editor/common/services/codeEditorService';
import Event, { Emitter } from 'vs/base/common/event';
Expand All @@ -26,28 +24,72 @@ import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/un
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';

namespace cmp {
export function compareModels(a: IModel, b: IModel): number {
return compare(a.uri.toString(), b.uri.toString());
namespace mapset {

export function newSet<E>(from: Set<E>): Set<E> {
let ret = new Set<E>();
from.forEach(ret.add, ret);
return ret;
}
export function compareEditors(a: EditorAndModel, b: EditorAndModel): number {
let ret = compare(a.editor.getId(), b.editor.getId());
if (ret === 0) {
ret = compare(a.document.uri.toString(), b.document.uri.toString());
}

export function setValues<T>(set: Set<T>): T[] {
// return Array.from(set);
let ret: T[] = [];
set.forEach(v => ret.push(v));
return ret;
}

export function mapValues<T>(map: Map<any, T>): T[] {
// return Array.from(map.values());
let ret: T[] = [];
map.forEach(v => ret.push(v));
return ret;
}
}

class EditorAndModel {
namespace delta {

export function ofSets<T>(before: Set<T>, after: Set<T>): { removed: T[], added: T[] } {
const removed: T[] = [];
const added: T[] = [];
before.forEach(element => {
if (!after.has(element)) {
removed.push(element);
}
});
after.forEach(element => {
if (!before.has(element)) {
added.push(element);
}
});
return { removed, added };
};

export function ofMaps<K, V>(before: Map<K, V>, after: Map<K, V>): { removed: V[], added: V[] } {
const removed: V[] = [];
const added: V[] = [];
before.forEach((value, index) => {
if (!after.has(index)) {
removed.push(value);
}
});
after.forEach((value, index) => {
if (!before.has(index)) {
added.push(value);
}
});
return { removed, added };
};
}

class EditorSnapshot {

readonly id: string;

constructor(
readonly editor: ICommonCodeEditor,
readonly document: IModel,
) {
this.id = `${editor.getId()},${document.uri.toString()}`;
this.id = `${editor.getId()},${editor.getModel().id}`;
}
}

Expand All @@ -58,8 +100,8 @@ class DocumentAndEditorStateDelta {
constructor(
readonly removedDocuments: IModel[],
readonly addedDocuments: IModel[],
readonly removedEditors: EditorAndModel[],
readonly addedEditors: EditorAndModel[],
readonly removedEditors: EditorSnapshot[],
readonly addedEditors: EditorSnapshot[],
readonly oldActiveEditor: string,
readonly newActiveEditor: string,
) {
Expand All @@ -85,10 +127,14 @@ class DocumentAndEditorState {

static compute(before: DocumentAndEditorState, after: DocumentAndEditorState): DocumentAndEditorStateDelta {
if (!before) {
return new DocumentAndEditorStateDelta([], after.documents, [], after.editors, undefined, after.activeEditor);
return new DocumentAndEditorStateDelta(
[], mapset.setValues(after.documents),
[], mapset.mapValues(after.editors),
undefined, after.activeEditor
);
}
const documentDelta = delta(before.documents, after.documents, cmp.compareModels);
const editorDelta = delta(before.editors, after.editors, cmp.compareEditors);
const documentDelta = delta.ofSets(before.documents, after.documents);
const editorDelta = delta.ofMaps(before.editors, after.editors);
const oldActiveEditor = before.activeEditor !== after.activeEditor ? before.activeEditor : undefined;
const newActiveEditor = before.activeEditor !== after.activeEditor ? after.activeEditor : undefined;

Expand All @@ -100,12 +146,11 @@ class DocumentAndEditorState {
}

constructor(
readonly documents: IModel[],
readonly editors: EditorAndModel[],
readonly documents: Set<IModel>,
readonly editors: Map<string, EditorSnapshot>,
readonly activeEditor: string,
) {
this.documents = documents.sort(cmp.compareModels);
this.editors = editors.sort(cmp.compareEditors);
//
}
}

Expand Down Expand Up @@ -154,16 +199,16 @@ class MainThreadDocumentAndEditorStateComputer {
private _updateState(): void {

// models: ignore too large models
const models = this._modelService.getModels();
for (let i = 0; i < models.length; i++) {
if (models[i].isTooLargeForHavingARichMode()) {
models.splice(i, 1);
i--;
const models = new Set<IModel>();
for (const model of this._modelService.getModels()) {
if (!model.isTooLargeForHavingARichMode()) {
models.add(model);
}
}


// editor: only take those that have a not too large model
const editors: EditorAndModel[] = [];
const editors = new Map<string, EditorSnapshot>();
let activeEditor: string = null;

for (const editor of this._codeEditorService.listCodeEditors()) {
Expand All @@ -172,8 +217,8 @@ class MainThreadDocumentAndEditorStateComputer {
&& !model.isDisposed() // model disposed
&& Boolean(this._modelService.getModel(model.uri)) // model disposing, the flag didn't flip yet but the model service already removed it
) {
const apiEditor = new EditorAndModel(editor, model);
editors.push(apiEditor);
const apiEditor = new EditorSnapshot(editor);
editors.set(apiEditor.id, apiEditor);
if (editor.isFocused()) {
activeEditor = apiEditor.id;
}
Expand All @@ -194,12 +239,11 @@ class MainThreadDocumentAndEditorStateComputer {
candidate = workbenchEditorControl.getModifiedEditor();
}
if (candidate) {
for (const { editor, id } of editors) {
if (candidate === editor) {
activeEditor = id;
break;
editors.forEach(snapshot => {
if (candidate === snapshot.editor) {
activeEditor = snapshot.id;
}
}
});
}
}
}
Expand Down Expand Up @@ -282,7 +326,7 @@ export class MainThreadDocumentsAndEditors {

// added editors
for (const apiEditor of delta.addedEditors) {
const mainThreadEditor = new MainThreadTextEditor(apiEditor.id, apiEditor.document,
const mainThreadEditor = new MainThreadTextEditor(apiEditor.id, apiEditor.editor.getModel(),
apiEditor.editor, { onGainedFocus() { }, onLostFocus() { } }, this._modelService);

this._editors[apiEditor.id] = mainThreadEditor;
Expand Down

0 comments on commit 83f3f31

Please sign in to comment.