mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-26 19:44:25 +01:00
don't use array, sorting, and array#delta but map and set, #35996
This commit is contained in:
@@ -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';
|
||||
@@ -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}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
) {
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user