started move to web worker for diff calculation

This commit is contained in:
Phil Hughes 2017-11-22 13:39:16 +00:00
parent 7c04e4086c
commit 809a27e61e
No known key found for this signature in database
GPG key ID: 32245528C52E0F9F
8 changed files with 90 additions and 87 deletions

View file

@ -10,12 +10,12 @@ export default {
this.editor.dispose();
},
mounted() {
this.editor = Editor.create();
if (this.monaco) {
this.initMonaco();
} else {
monacoLoader(['vs/editor/editor.main'], () => {
this.editor = Editor.create(monaco);
this.initMonaco();
});
}
@ -35,7 +35,7 @@ export default {
this.editor.createInstance(this.$el);
})
.then(() => this.setupEditor())
.catch(() => flash('Error setting up monaco. Please try again.'));
.catch((e) => { throw e;flash('Error setting up monaco. Please try again.'); });
},
setupEditor() {
if (!this.activeFile) return;

View file

@ -2,25 +2,25 @@
import Disposable from './disposable';
export default class Model {
constructor(file) {
constructor(monaco, file) {
this.monaco = monaco;
this.disposable = new Disposable();
this.file = file;
this.content = file.content !== '' ? file.content : file.raw;
this.disposable.add(
this.originalModel = monaco.editor.createModel(
this.content,
this.originalModel = this.monaco.editor.createModel(
this.file.raw,
undefined,
new monaco.Uri(null, null, `original/${this.file.path}`),
new this.monaco.Uri(null, null, `original/${this.file.path}`),
),
this.model = monaco.editor.createModel(
this.model = this.monaco.editor.createModel(
this.content,
undefined,
new monaco.Uri(null, null, this.file.path),
new this.monaco.Uri(null, null, this.file.path),
),
);
this.attachedToWorker = false;
this.events = new Map();
}
@ -37,19 +37,18 @@ export default class Model {
}
get diffModel() {
return {
url: this.model.uri.toString(),
versionId: this.model.getVersionId(),
lines: this.model.getLinesContent(),
EOL: '\n',
};
return Model.getDiffModel(this.model);
}
get originalDiffModel() {
return Model.getDiffModel(this.originalModel);
}
static getDiffModel(model) {
return {
url: this.originalModel.uri.toString(),
versionId: this.originalModel.getVersionId(),
lines: this.originalModel.getLinesContent(),
url: model.uri.toString(),
versionId: model.getVersionId(),
lines: model.getLinesContent(),
EOL: '\n',
};
}
@ -62,21 +61,17 @@ export default class Model {
return this.originalModel;
}
setAttachedToWorker(val) {
this.attachedToWorker = val;
}
onChange(cb) {
this.events.set(
this.file.path,
this.model.onDidChangeContent(e => cb(this.model, e)),
this.disposable.add(
this.model.onDidChangeContent(e => cb(this.model, e)),
),
);
}
dispose() {
this.disposable.dispose();
this.events.forEach(disposer => disposer.dispose());
this.events.clear();
}
}

View file

@ -2,7 +2,8 @@ import Disposable from './disposable';
import Model from './model';
export default class ModelManager {
constructor() {
constructor(monaco) {
this.monaco = monaco;
this.disposable = new Disposable();
this.models = new Map();
}
@ -16,7 +17,7 @@ export default class ModelManager {
return this.models.get(file.path);
}
const model = new Model(file);
const model = new Model(this.monaco, file);
this.models.set(model.path, model);
this.disposable.add(model);

View file

@ -1,7 +1,6 @@
import editor from '../editor';
class DecorationsController {
constructor() {
export default class DecorationsController {
constructor(editor) {
this.editor = editor;
this.decorations = new Map();
this.editorDecorations = new Map();
}
@ -33,7 +32,7 @@ class DecorationsController {
this.editorDecorations.set(
model.url,
editor.editorInstance.instance.deltaDecorations(oldDecorations, decorations),
this.editor.instance.deltaDecorations(oldDecorations, decorations),
);
}
@ -42,5 +41,3 @@ class DecorationsController {
this.editorDecorations.clear();
}
}
export default new DecorationsController();

View file

@ -1,7 +1,7 @@
/* global monaco */
import DirtyDiffWorker from './worker';
import DirtyDiffWorker from './diff';
console.log(DirtyDiffWorker);
import Disposable from '../common/disposable';
import decorationsController from '../decorations/controller';
export const getDiffChangeType = (change) => {
if (change.modified) {
@ -28,17 +28,14 @@ export const getDecorator = change => ({
},
});
export const decorate = (model, changes) => {
const decorations = changes.map(change => getDecorator(change));
decorationsController.addDecorations(model, 'dirtyDiff', decorations);
};
export default class DirtyDiffController {
constructor(modelManager) {
constructor(modelManager, decorationsController) {
this.disposable = new Disposable();
this.editorSimpleWorker = null;
this.modelManager = modelManager;
this.dirtyDiffWorker = new DirtyDiffWorker();
this.decorationsController = decorationsController;
console.log(DirtyDiffWorker);
// this.dirtyDiffWorker = new DirtyDiffWorker();
}
attachModel(model) {
@ -46,12 +43,17 @@ export default class DirtyDiffController {
}
computeDiff(model) {
decorate(model, this.dirtyDiffWorker.compute(model));
this.decorate(model, this.dirtyDiffWorker.compute(model));
}
// eslint-disable-next-line class-methods-use-this
reDecorate(model) {
decorationsController.decorate(model);
this.decorationsController.decorate(model);
}
decorate(model, changes) {
const decorations = changes.map(change => getDecorator(change));
this.decorationsController.addDecorations(model, 'dirtyDiff', decorations);
}
dispose() {

View file

@ -0,0 +1,38 @@
import { diffLines } from 'diff';
// export default class DirtyDiffWorker {
// // eslint-disable-next-line class-methods-use-this
// compute(model) {
// console.time('a');
// const originalContent = model.getOriginalModel().getValue();
// const newContent = model.getModel().getValue();
// const changes = diffLines(originalContent, newContent);
//
// let lineNumber = 1;
// const a = changes.reduce((acc, change) => {
// const findOnLine = acc.find(c => c.lineNumber === lineNumber);
//
// if (findOnLine) {
// Object.assign(findOnLine, change, {
// modified: true,
// endLineNumber: (lineNumber + change.count) - 1,
// });
// } else if ('added' in change || 'removed' in change) {
// acc.push(Object.assign({}, change, {
// lineNumber,
// modified: undefined,
// endLineNumber: (lineNumber + change.count) - 1,
// }));
// }
//
// if (!change.removed) {
// lineNumber += change.count;
// }
//
// return acc;
// }, []);
// console.timeEnd('a');
//
// return a;
// }
// }

View file

@ -1,34 +0,0 @@
import { diffLines } from 'diff';
export default class DirtyDiffWorker {
// eslint-disable-next-line class-methods-use-this
compute(model) {
const originalContent = model.getOriginalModel().getValue();
const newContent = model.getModel().getValue();
const changes = diffLines(originalContent, newContent);
let lineNumber = 1;
return changes.reduce((acc, change) => {
const findOnLine = acc.find(c => c.lineNumber === lineNumber);
if (findOnLine) {
Object.assign(findOnLine, change, {
modified: true,
endLineNumber: (lineNumber + change.count) - 1,
});
} else if ('added' in change || 'removed' in change) {
acc.push(Object.assign({}, change, {
lineNumber,
modified: undefined,
endLineNumber: (lineNumber + change.count) - 1,
}));
}
if (!change.removed) {
lineNumber += change.count;
}
return acc;
}, []);
}
}

View file

@ -1,36 +1,40 @@
/* global monaco */
import DecorationsController from './decorations/controller';
import DirtyDiffController from './diff/controller';
import Disposable from './common/disposable';
import ModelManager from './common/model_manager';
export default class Editor {
static create() {
this.editorInstance = new Editor();
static create(monaco) {
this.editorInstance = new Editor(monaco);
return this.editorInstance;
}
constructor() {
constructor(monaco) {
this.monaco = monaco;
this.currentModel = null;
this.instance = null;
this.dirtyDiffController = null;
this.disposable = new Disposable();
this.disposable.add(
this.modelManager = new ModelManager(),
this.modelManager = new ModelManager(this.monaco),
this.decorationsController = new DecorationsController(this),
);
}
createInstance(domElement) {
if (!this.instance) {
this.disposable.add(
this.instance = monaco.editor.create(domElement, {
this.instance = this.monaco.editor.create(domElement, {
model: null,
readOnly: false,
contextmenu: true,
scrollBeyondLastLine: false,
}),
this.dirtyDiffController = new DirtyDiffController(this.modelManager),
this.dirtyDiffController = new DirtyDiffController(
this.modelManager, this.decorationsController,
),
);
}
}