Commit 809a27e6 authored by Phil Hughes's avatar Phil Hughes

started move to web worker for diff calculation

parent 7c04e408
...@@ -10,12 +10,12 @@ export default { ...@@ -10,12 +10,12 @@ export default {
this.editor.dispose(); this.editor.dispose();
}, },
mounted() { mounted() {
this.editor = Editor.create();
if (this.monaco) { if (this.monaco) {
this.initMonaco(); this.initMonaco();
} else { } else {
monacoLoader(['vs/editor/editor.main'], () => { monacoLoader(['vs/editor/editor.main'], () => {
this.editor = Editor.create(monaco);
this.initMonaco(); this.initMonaco();
}); });
} }
...@@ -35,7 +35,7 @@ export default { ...@@ -35,7 +35,7 @@ export default {
this.editor.createInstance(this.$el); this.editor.createInstance(this.$el);
}) })
.then(() => this.setupEditor()) .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() { setupEditor() {
if (!this.activeFile) return; if (!this.activeFile) return;
......
...@@ -2,25 +2,25 @@ ...@@ -2,25 +2,25 @@
import Disposable from './disposable'; import Disposable from './disposable';
export default class Model { export default class Model {
constructor(file) { constructor(monaco, file) {
this.monaco = monaco;
this.disposable = new Disposable(); this.disposable = new Disposable();
this.file = file; this.file = file;
this.content = file.content !== '' ? file.content : file.raw; this.content = file.content !== '' ? file.content : file.raw;
this.disposable.add( this.disposable.add(
this.originalModel = monaco.editor.createModel( this.originalModel = this.monaco.editor.createModel(
this.content, this.file.raw,
undefined, 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, this.content,
undefined, 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(); this.events = new Map();
} }
...@@ -37,19 +37,18 @@ export default class Model { ...@@ -37,19 +37,18 @@ export default class Model {
} }
get diffModel() { get diffModel() {
return { return Model.getDiffModel(this.model);
url: this.model.uri.toString(),
versionId: this.model.getVersionId(),
lines: this.model.getLinesContent(),
EOL: '\n',
};
} }
get originalDiffModel() { get originalDiffModel() {
return Model.getDiffModel(this.originalModel);
}
static getDiffModel(model) {
return { return {
url: this.originalModel.uri.toString(), url: model.uri.toString(),
versionId: this.originalModel.getVersionId(), versionId: model.getVersionId(),
lines: this.originalModel.getLinesContent(), lines: model.getLinesContent(),
EOL: '\n', EOL: '\n',
}; };
} }
...@@ -62,21 +61,17 @@ export default class Model { ...@@ -62,21 +61,17 @@ export default class Model {
return this.originalModel; return this.originalModel;
} }
setAttachedToWorker(val) {
this.attachedToWorker = val;
}
onChange(cb) { onChange(cb) {
this.events.set( this.events.set(
this.file.path, this.file.path,
this.disposable.add(
this.model.onDidChangeContent(e => cb(this.model, e)), this.model.onDidChangeContent(e => cb(this.model, e)),
),
); );
} }
dispose() { dispose() {
this.disposable.dispose(); this.disposable.dispose();
this.events.forEach(disposer => disposer.dispose());
this.events.clear(); this.events.clear();
} }
} }
...@@ -2,7 +2,8 @@ import Disposable from './disposable'; ...@@ -2,7 +2,8 @@ import Disposable from './disposable';
import Model from './model'; import Model from './model';
export default class ModelManager { export default class ModelManager {
constructor() { constructor(monaco) {
this.monaco = monaco;
this.disposable = new Disposable(); this.disposable = new Disposable();
this.models = new Map(); this.models = new Map();
} }
...@@ -16,7 +17,7 @@ export default class ModelManager { ...@@ -16,7 +17,7 @@ export default class ModelManager {
return this.models.get(file.path); 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.models.set(model.path, model);
this.disposable.add(model); this.disposable.add(model);
......
import editor from '../editor'; export default class DecorationsController {
constructor(editor) {
class DecorationsController { this.editor = editor;
constructor() {
this.decorations = new Map(); this.decorations = new Map();
this.editorDecorations = new Map(); this.editorDecorations = new Map();
} }
...@@ -33,7 +32,7 @@ class DecorationsController { ...@@ -33,7 +32,7 @@ class DecorationsController {
this.editorDecorations.set( this.editorDecorations.set(
model.url, model.url,
editor.editorInstance.instance.deltaDecorations(oldDecorations, decorations), this.editor.instance.deltaDecorations(oldDecorations, decorations),
); );
} }
...@@ -42,5 +41,3 @@ class DecorationsController { ...@@ -42,5 +41,3 @@ class DecorationsController {
this.editorDecorations.clear(); this.editorDecorations.clear();
} }
} }
export default new DecorationsController();
/* global monaco */ /* global monaco */
import DirtyDiffWorker from './worker'; import DirtyDiffWorker from './diff';
console.log(DirtyDiffWorker);
import Disposable from '../common/disposable'; import Disposable from '../common/disposable';
import decorationsController from '../decorations/controller';
export const getDiffChangeType = (change) => { export const getDiffChangeType = (change) => {
if (change.modified) { if (change.modified) {
...@@ -28,17 +28,14 @@ export const getDecorator = change => ({ ...@@ -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 { export default class DirtyDiffController {
constructor(modelManager) { constructor(modelManager, decorationsController) {
this.disposable = new Disposable(); this.disposable = new Disposable();
this.editorSimpleWorker = null; this.editorSimpleWorker = null;
this.modelManager = modelManager; this.modelManager = modelManager;
this.dirtyDiffWorker = new DirtyDiffWorker(); this.decorationsController = decorationsController;
console.log(DirtyDiffWorker);
// this.dirtyDiffWorker = new DirtyDiffWorker();
} }
attachModel(model) { attachModel(model) {
...@@ -46,12 +43,17 @@ export default class DirtyDiffController { ...@@ -46,12 +43,17 @@ export default class DirtyDiffController {
} }
computeDiff(model) { computeDiff(model) {
decorate(model, this.dirtyDiffWorker.compute(model)); this.decorate(model, this.dirtyDiffWorker.compute(model));
} }
// eslint-disable-next-line class-methods-use-this // eslint-disable-next-line class-methods-use-this
reDecorate(model) { 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() { dispose() {
......
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;
// }
// }
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;
}, []);
}
}
/* global monaco */ import DecorationsController from './decorations/controller';
import DirtyDiffController from './diff/controller'; import DirtyDiffController from './diff/controller';
import Disposable from './common/disposable'; import Disposable from './common/disposable';
import ModelManager from './common/model_manager'; import ModelManager from './common/model_manager';
export default class Editor { export default class Editor {
static create() { static create(monaco) {
this.editorInstance = new Editor(); this.editorInstance = new Editor(monaco);
return this.editorInstance; return this.editorInstance;
} }
constructor() { constructor(monaco) {
this.monaco = monaco;
this.currentModel = null; this.currentModel = null;
this.instance = null; this.instance = null;
this.dirtyDiffController = null; this.dirtyDiffController = null;
this.disposable = new Disposable(); this.disposable = new Disposable();
this.disposable.add( this.disposable.add(
this.modelManager = new ModelManager(), this.modelManager = new ModelManager(this.monaco),
this.decorationsController = new DecorationsController(this),
); );
} }
createInstance(domElement) { createInstance(domElement) {
if (!this.instance) { if (!this.instance) {
this.disposable.add( this.disposable.add(
this.instance = monaco.editor.create(domElement, { this.instance = this.monaco.editor.create(domElement, {
model: null, model: null,
readOnly: false, readOnly: false,
contextmenu: true, contextmenu: true,
scrollBeyondLastLine: false, scrollBeyondLastLine: false,
}), }),
this.dirtyDiffController = new DirtyDiffController(this.modelManager), this.dirtyDiffController = new DirtyDiffController(
this.modelManager, this.decorationsController,
),
); );
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment