未验证 提交 6ff4290a 编写于 作者: A Alex Dima

Add ViewModelEventDispatcher

上级 a1ed3861
......@@ -258,14 +258,13 @@ export class TextAreaHandler extends ViewPart {
const lineNumber = this._selections[0].startLineNumber;
const column = this._selections[0].startColumn - (e.moveOneCharacterLeft ? 1 : 0);
this._context.privateViewEventBus.emit(new viewEvents.ViewRevealRangeRequestEvent(
this._context.model.revealRange(
'keyboard',
true,
new Range(lineNumber, column, lineNumber, column),
null,
viewEvents.VerticalRevealType.Simple,
true,
ScrollType.Immediate
));
);
// Find range pixel position
const visibleRange = this._viewHelper.visibleRangeForPositionRelativeToEditor(lineNumber, column);
......@@ -308,12 +307,10 @@ export class TextAreaHandler extends ViewPart {
this._register(this._textAreaInput.onFocus(() => {
this._context.model.setHasFocus(true);
this._context.privateViewEventBus.emit(new viewEvents.ViewFocusChangedEvent(true));
}));
this._register(this._textAreaInput.onBlur(() => {
this._context.model.setHasFocus(false);
this._context.privateViewEventBus.emit(new viewEvents.ViewFocusChangedEvent(false));
}));
}
......
......@@ -42,7 +42,6 @@ import { Range } from 'vs/editor/common/core/range';
import { IConfiguration, ScrollType } from 'vs/editor/common/editorCommon';
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
import { ViewContext } from 'vs/editor/common/view/viewContext';
import { ViewEventDispatcher } from 'vs/editor/common/view/viewEventDispatcher';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
......@@ -64,8 +63,6 @@ export interface IOverlayWidgetData {
export class View extends ViewEventHandler {
private readonly eventDispatcher: ViewEventDispatcher;
private _scrollbar: EditorScrollbar;
private readonly _context: ViewContext;
private _selections: Selection[];
......@@ -107,18 +104,15 @@ export class View extends ViewEventHandler {
const viewController = new ViewController(configuration, model, this.outgoingEvents, commandDelegate);
// The event dispatcher will always go through _renderOnce before dispatching any events
this.eventDispatcher = new ViewEventDispatcher((callback: () => void) => this._renderOnce(callback));
// The view context is passed on to most classes (basically to reduce param. counts in ctors)
this._context = new ViewContext(configuration, themeService.getColorTheme(), model);
// Ensure the view is the first event handler in order to update the layout
this.eventDispatcher.addEventHandler(this);
// The view context is passed on to most classes (basically to reduce param. counts in ctors)
this._context = new ViewContext(configuration, themeService.getColorTheme(), model, this.eventDispatcher);
this._context.addEventHandler(this);
this._register(themeService.onDidColorThemeChange(theme => {
this._context.theme.update(theme);
this.eventDispatcher.emit(new viewEvents.ViewThemeChangedEvent());
this._context.model.onDidColorThemeChange();
this.render(true, false);
}));
......@@ -224,10 +218,6 @@ export class View extends ViewEventHandler {
// Pointer handler
this.pointerHandler = this._register(new PointerHandler(this._context, viewController, this.createPointerHandlerHelper()));
this._register(model.addViewEventListener((events: viewEvents.ViewEvent[]) => {
this.eventDispatcher.emitMany(events);
}));
}
private _flushAccumulatedAndRenderNow(): void {
......@@ -300,7 +290,10 @@ export class View extends ViewEventHandler {
}
// --- begin event handlers
public handleEvents(events: viewEvents.ViewEvent[]): void {
super.handleEvents(events);
this._scheduleRender();
}
public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
this.domNode.setClassName(this.getEditorClassName());
this._applyLayout();
......@@ -340,7 +333,7 @@ export class View extends ViewEventHandler {
this._renderAnimationFrame = null;
}
this.eventDispatcher.removeEventHandler(this);
this._context.removeEventHandler(this);
this.outgoingEvents.dispose();
this.viewLines.dispose();
......@@ -354,12 +347,6 @@ export class View extends ViewEventHandler {
super.dispose();
}
private _renderOnce<T>(callback: () => T): T {
const r = safeInvokeNoArg(callback);
this._scheduleRender();
return r;
}
private _scheduleRender(): void {
if (this._renderAnimationFrame === null) {
this._renderAnimationFrame = dom.runAtThisOrScheduleAtNextAnimationFrame(this._onRenderScheduled.bind(this), 100);
......@@ -477,13 +464,9 @@ export class View extends ViewEventHandler {
}
public change(callback: (changeAccessor: IViewZoneChangeAccessor) => any): boolean {
return this._renderOnce(() => {
const zonesHaveChanged = this.viewZones.changeViewZones(callback);
if (zonesHaveChanged) {
this._context.privateViewEventBus.emit(new viewEvents.ViewZonesChangedEvent());
}
return zonesHaveChanged;
});
const hadAChange = this.viewZones.changeViewZones(callback);
this._scheduleRender();
return hadAChange;
}
public render(now: boolean, everything: boolean): void {
......
......@@ -1011,14 +1011,13 @@ export class Minimap extends ViewPart implements IMinimapModel {
if (this._samplingState) {
lineNumber = this._samplingState.minimapLines[lineNumber - 1];
}
this._context.privateViewEventBus.emit(new viewEvents.ViewRevealRangeRequestEvent(
this._context.model.revealRange(
'mouse',
false,
new Range(lineNumber, 1, lineNumber, 1),
null,
viewEvents.VerticalRevealType.Center,
false,
ScrollType.Smooth
));
);
}
public setScrollTop(scrollTop: number): void {
......
......@@ -222,8 +222,6 @@ export class ViewZones extends ViewPart {
changeAccessor.addZone = invalidFunc;
changeAccessor.removeZone = invalidFunc;
changeAccessor.layoutZone = invalidFunc;
return zonesHaveChanged;
});
return zonesHaveChanged;
......
......@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import { IConfiguration } from 'vs/editor/common/editorCommon';
import { ViewEventDispatcher } from 'vs/editor/common/view/viewEventDispatcher';
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
import { IViewLayout, IViewModel } from 'vs/editor/common/viewModel/viewModel';
import { IColorTheme, ThemeType } from 'vs/platform/theme/common/themeService';
......@@ -37,27 +36,24 @@ export class ViewContext {
public readonly configuration: IConfiguration;
public readonly model: IViewModel;
public readonly viewLayout: IViewLayout;
public readonly privateViewEventBus: ViewEventDispatcher;
public readonly theme: EditorTheme;
constructor(
configuration: IConfiguration,
theme: IColorTheme,
model: IViewModel,
privateViewEventBus: ViewEventDispatcher
model: IViewModel
) {
this.configuration = configuration;
this.theme = new EditorTheme(theme);
this.model = model;
this.viewLayout = model.viewLayout;
this.privateViewEventBus = privateViewEventBus;
}
public addEventHandler(eventHandler: ViewEventHandler): void {
this.privateViewEventBus.addEventHandler(eventHandler);
this.model.addViewEventHandler(eventHandler);
}
public removeEventHandler(eventHandler: ViewEventHandler): void {
this.privateViewEventBus.removeEventHandler(eventHandler);
this.model.removeViewEventHandler(eventHandler);
}
}
......@@ -3,8 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as errors from 'vs/base/common/errors';
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { ViewModelEventDispatcher } from 'vs/editor/common/viewModel/viewModelEventDispatcher';
import { Disposable } from 'vs/base/common/lifecycle';
import { ScrollEvent } from 'vs/base/common/scrollable';
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
import { Range } from 'vs/editor/common/core/range';
......@@ -330,27 +330,16 @@ export interface IViewEventListener {
(events: ViewEvent[]): void;
}
export interface IViewEventEmitter {
addViewEventListener(listener: IViewEventListener): IDisposable;
}
export class ViewEventEmitter extends Disposable implements IViewEventEmitter {
private _listeners: IViewEventListener[];
export class ViewEventEmitter extends Disposable {
private _collector: ViewEventsCollector | null;
private _collectorCnt: number;
constructor() {
super();
this._listeners = [];
this._collector = null;
this._collectorCnt = 0;
}
public dispose(): void {
this._listeners = [];
super.dispose();
}
protected _beginEmitViewEvents(): ViewEventsCollector {
this._collectorCnt++;
if (this._collectorCnt === 1) {
......@@ -359,45 +348,25 @@ export class ViewEventEmitter extends Disposable implements IViewEventEmitter {
return this._collector!;
}
protected _endEmitViewEvents(): void {
protected _endEmitViewEvents(eventDispatcher: ViewModelEventDispatcher): void {
this._collectorCnt--;
if (this._collectorCnt === 0) {
const events = this._collector!.finalize();
this._collector = null;
if (events.length > 0) {
this._emit(events);
eventDispatcher.emitMany(events);
}
}
}
protected _emitSingleViewEvent(event: ViewEvent): void {
protected _emitSingleViewEvent(eventDispatcher: ViewModelEventDispatcher, event: ViewEvent): void {
try {
const eventsCollector = this._beginEmitViewEvents();
eventsCollector.emit(event);
} finally {
this._endEmitViewEvents();
}
}
private _emit(events: ViewEvent[]): void {
const listeners = this._listeners.slice(0);
for (let i = 0, len = listeners.length; i < len; i++) {
safeInvokeListener(listeners[i], events);
this._endEmitViewEvents(eventDispatcher);
}
}
public addViewEventListener(listener: IViewEventListener): IDisposable {
this._listeners.push(listener);
return toDisposable(() => {
let listeners = this._listeners;
for (let i = 0, len = listeners.length; i < len; i++) {
if (listeners[i] === listener) {
listeners.splice(i, 1);
break;
}
}
});
}
}
export class ViewEventsCollector {
......@@ -421,11 +390,3 @@ export class ViewEventsCollector {
}
}
function safeInvokeListener(listener: IViewEventListener, events: ViewEvent[]): void {
try {
listener(events);
} catch (e) {
errors.onUnexpectedError(e);
}
}
......@@ -353,11 +353,12 @@ export class ViewLayout extends Disposable implements IViewLayout {
}
// ---- IVerticalLayoutProvider
public changeWhitespace(callback: (accessor: IWhitespaceChangeAccessor) => void): void {
public changeWhitespace(callback: (accessor: IWhitespaceChangeAccessor) => void): boolean {
const hadAChange = this._linesLayout.changeWhitespace(callback);
if (hadAChange) {
this.onHeightMaybeChanged();
}
return hadAChange;
}
public getVerticalOffsetForLineNumber(lineNumber: number): number {
return this._linesLayout.getVerticalOffsetForLineNumber(lineNumber);
......
......@@ -10,12 +10,13 @@ import { IPosition, Position } from 'vs/editor/common/core/position';
import { IRange, Range } from 'vs/editor/common/core/range';
import { INewScrollPosition, ScrollType } from 'vs/editor/common/editorCommon';
import { EndOfLinePreference, IActiveIndentGuideInfo, IModelDecorationOptions, TextModelResolvedOptions, ITextModel } from 'vs/editor/common/model';
import { IViewEventEmitter, VerticalRevealType } from 'vs/editor/common/view/viewEvents';
import { VerticalRevealType } from 'vs/editor/common/view/viewEvents';
import { IPartialViewLinesViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
import { IEditorWhitespace, IWhitespaceChangeAccessor } from 'vs/editor/common/viewLayout/linesLayout';
import { EditorTheme } from 'vs/editor/common/view/viewContext';
import { ICursorSimpleModel, PartialCursorState, CursorState, IColumnSelectData, EditOperationType, CursorConfiguration } from 'vs/editor/common/controller/cursorCommon';
import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents';
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
export interface IViewWhitespaceViewportData {
readonly id: string;
......@@ -83,7 +84,7 @@ export interface ICoordinatesConverter {
modelPositionIsVisible(modelPosition: Position): boolean;
}
export interface IViewModel extends IViewEventEmitter, ICursorSimpleModel {
export interface IViewModel extends ICursorSimpleModel {
readonly model: ITextModel;
......@@ -93,12 +94,16 @@ export interface IViewModel extends IViewEventEmitter, ICursorSimpleModel {
readonly cursorConfig: CursorConfiguration;
addViewEventHandler(eventHandler: ViewEventHandler): void;
removeViewEventHandler(eventHandler: ViewEventHandler): void;
/**
* Gives a hint that a lot of requests are about to come in for these line numbers.
*/
setViewport(startLineNumber: number, endLineNumber: number, centeredLineNumber: number): void;
tokenizeViewport(): void;
setHasFocus(hasFocus: boolean): void;
onDidColorThemeChange(): void;
getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[];
getViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData;
......
......@@ -3,24 +3,25 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ViewEvent } from 'vs/editor/common/view/viewEvents';
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
import { ViewEvent } from 'vs/editor/common/view/viewEvents';
import { IContentSizeChangedEvent } from 'vs/editor/common/editorCommon';
export class ViewEventDispatcher {
export class ViewModelEventDispatcher {
private readonly _eventHandlerGateKeeper: (callback: () => void) => void;
private readonly _eventHandlers: ViewEventHandler[];
private _eventQueue: ViewEvent[] | null;
private _isConsumingQueue: boolean;
private _viewEventQueue: ViewEvent[] | null;
private _isConsumingViewEventQueue: boolean;
// private _outgoingContentSizeChangedEvent: OutgoingContentSizeChangedEvent | null;
constructor(eventHandlerGateKeeper: (callback: () => void) => void) {
this._eventHandlerGateKeeper = eventHandlerGateKeeper;
constructor() {
this._eventHandlers = [];
this._eventQueue = null;
this._isConsumingQueue = false;
this._viewEventQueue = null;
this._isConsumingViewEventQueue = false;
// this._outgoingContentSizeChangedEvent = null;
}
public addEventHandler(eventHandler: ViewEventHandler): void {
public addViewEventHandler(eventHandler: ViewEventHandler): void {
for (let i = 0, len = this._eventHandlers.length; i < len; i++) {
if (this._eventHandlers[i] === eventHandler) {
console.warn('Detected duplicate listener in ViewEventDispatcher', eventHandler);
......@@ -29,7 +30,7 @@ export class ViewEventDispatcher {
this._eventHandlers.push(eventHandler);
}
public removeEventHandler(eventHandler: ViewEventHandler): void {
public removeViewEventHandler(eventHandler: ViewEventHandler): void {
for (let i = 0; i < this._eventHandlers.length; i++) {
if (this._eventHandlers[i] === eventHandler) {
this._eventHandlers.splice(i, 1);
......@@ -38,55 +39,58 @@ export class ViewEventDispatcher {
}
}
public emit(event: ViewEvent): void {
if (this._eventQueue) {
this._eventQueue.push(event);
} else {
this._eventQueue = [event];
}
if (!this._isConsumingQueue) {
this.consumeQueue();
}
}
public emitMany(events: ViewEvent[]): void {
if (this._eventQueue) {
this._eventQueue = this._eventQueue.concat(events);
if (this._viewEventQueue) {
this._viewEventQueue = this._viewEventQueue.concat(events);
} else {
this._eventQueue = events;
this._viewEventQueue = events;
}
if (!this._isConsumingQueue) {
this.consumeQueue();
if (!this._isConsumingViewEventQueue) {
this._consumeViewEventQueue();
}
}
private consumeQueue(): void {
this._eventHandlerGateKeeper(() => {
try {
this._isConsumingQueue = true;
this._doConsumeQueue();
} finally {
this._isConsumingQueue = false;
}
});
private _consumeViewEventQueue(): void {
try {
this._isConsumingViewEventQueue = true;
this._doConsumeQueue();
} finally {
this._isConsumingViewEventQueue = false;
}
}
private _doConsumeQueue(): void {
while (this._eventQueue) {
while (this._viewEventQueue) {
// Empty event queue, as events might come in while sending these off
let events = this._eventQueue;
this._eventQueue = null;
const events = this._viewEventQueue;
this._viewEventQueue = null;
// Use a clone of the event handlers list, as they might remove themselves
let eventHandlers = this._eventHandlers.slice(0);
for (let i = 0, len = eventHandlers.length; i < len; i++) {
eventHandlers[i].handleEvents(events);
const eventHandlers = this._eventHandlers.slice(0);
for (const eventHandler of eventHandlers) {
eventHandler.handleEvents(events);
}
}
}
}
export class OutgoingContentSizeChangedEvent implements IContentSizeChangedEvent {
private readonly _oldContentWidth: number;
private readonly _oldContentHeight: number;
readonly contentWidth: number;
readonly contentHeight: number;
readonly contentWidthChanged: boolean;
readonly contentHeightChanged: boolean;
constructor(oldContentWidth: number, oldContentHeight: number, contentWidth: number, contentHeight: number) {
this._oldContentWidth = oldContentWidth;
this._oldContentHeight = oldContentHeight;
this.contentWidth = contentWidth;
this.contentHeight = contentHeight;
this.contentWidthChanged = (this._oldContentWidth !== this.contentWidth);
this.contentHeightChanged = (this._oldContentHeight !== this.contentHeight);
}
}
......@@ -29,6 +29,8 @@ import { Cursor } from 'vs/editor/common/controller/cursor';
import { PartialCursorState, CursorState, IColumnSelectData, EditOperationType, CursorConfiguration } from 'vs/editor/common/controller/cursorCommon';
import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents';
import { IWhitespaceChangeAccessor } from 'vs/editor/common/viewLayout/linesLayout';
import { ViewModelEventDispatcher } from 'vs/editor/common/viewModel/viewModelEventDispatcher';
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
const USE_IDENTITY_LINES_COLLECTION = true;
......@@ -37,6 +39,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
private readonly editorId: number;
private readonly configuration: IConfiguration;
public readonly model: ITextModel;
private readonly _eventDispatcher: ViewModelEventDispatcher;
public cursorConfig: CursorConfiguration;
private readonly _tokenizeViewportSoon: RunOnceScheduler;
private readonly _updateConfigurationViewLineCount: RunOnceScheduler;
......@@ -63,6 +66,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
this.editorId = editorId;
this.configuration = configuration;
this.model = model;
this._eventDispatcher = new ViewModelEventDispatcher();
this.cursorConfig = new CursorConfiguration(this.model.getLanguageIdentifier(), this.model.getOptions(), this.configuration);
this._tokenizeViewportSoon = this._register(new RunOnceScheduler(() => this.tokenizeViewport(), 50));
this._updateConfigurationViewLineCount = this._register(new RunOnceScheduler(() => this._updateConfigurationViewLineCountNow(), 0));
......@@ -104,11 +108,11 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
if (e.scrollTopChanged) {
this._tokenizeViewportSoon.schedule();
}
this._emitSingleViewEvent(new viewEvents.ViewScrollChangedEvent(e));
this._emitSingleViewEvent(this._eventDispatcher, new viewEvents.ViewScrollChangedEvent(e));
}));
this._register(this.viewLayout.onDidContentSizeChange((e) => {
this._emitSingleViewEvent(new viewEvents.ViewContentSizeChangedEvent(e));
this._emitSingleViewEvent(this._eventDispatcher, new viewEvents.ViewContentSizeChangedEvent(e));
}));
this.decorations = new ViewModelDecorations(this.editorId, this.model, this.configuration, this.lines, this.coordinatesConverter);
......@@ -120,12 +124,12 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
const eventsCollector = this._beginEmitViewEvents();
this._onConfigurationChanged(eventsCollector, e);
} finally {
this._endEmitViewEvents();
this._endEmitViewEvents(this._eventDispatcher);
}
}));
this._register(MinimapTokensColorTracker.getInstance().onDidChange(() => {
this._emitSingleViewEvent(new viewEvents.ViewTokensColorsChangedEvent());
this._emitSingleViewEvent(this._eventDispatcher, new viewEvents.ViewTokensColorsChangedEvent());
}));
this._updateConfigurationViewLineCountNow();
......@@ -141,6 +145,14 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
this.viewportStartLineTrackedRange = this.model._setTrackedRange(this.viewportStartLineTrackedRange, null, TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges);
}
public addViewEventHandler(eventHandler: ViewEventHandler): void {
this._eventDispatcher.addViewEventHandler(eventHandler);
}
public removeViewEventHandler(eventHandler: ViewEventHandler): void {
this._eventDispatcher.removeViewEventHandler(eventHandler);
}
private _updateConfigurationViewLineCountNow(): void {
this.configuration.setViewLineCount(this.lines.getViewLineCount());
}
......@@ -155,6 +167,11 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
public setHasFocus(hasFocus: boolean): void {
this.hasFocus = hasFocus;
this.cursor.setHasFocus(hasFocus);
this._emitSingleViewEvent(this._eventDispatcher, new viewEvents.ViewFocusChangedEvent(hasFocus));
}
public onDidColorThemeChange(): void {
this._emitSingleViewEvent(this._eventDispatcher, new viewEvents.ViewThemeChangedEvent());
}
private _onConfigurationChanged(eventsCollector: viewEvents.ViewEventsCollector, e: ConfigurationChangedEvent): void {
......@@ -308,7 +325,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
this.decorations.onLineMappingChanged();
}
} finally {
this._endEmitViewEvents();
this._endEmitViewEvents(this._eventDispatcher);
}
// Update the configuration and reset the centered view line
......@@ -330,7 +347,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
const eventsCollector = this._beginEmitViewEvents();
this.cursor.onModelContentChanged(eventsCollector, e);
} finally {
this._endEmitViewEvents();
this._endEmitViewEvents(this._eventDispatcher);
}
}));
......@@ -345,7 +362,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
toLineNumber: viewEndLineNumber
};
}
this._emitSingleViewEvent(new viewEvents.ViewTokensChangedEvent(viewRanges));
this._emitSingleViewEvent(this._eventDispatcher, new viewEvents.ViewTokensChangedEvent(viewRanges));
if (e.tokenizationSupportChanged) {
this._tokenizeViewportSoon.schedule();
......@@ -353,7 +370,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
}));
this._register(this.model.onDidChangeLanguageConfiguration((e) => {
this._emitSingleViewEvent(new viewEvents.ViewLanguageConfigurationEvent());
this._emitSingleViewEvent(this._eventDispatcher, new viewEvents.ViewLanguageConfigurationEvent());
this.cursorConfig = new CursorConfiguration(this.model.getLanguageIdentifier(), this.model.getOptions(), this.configuration);
this.cursor.updateConfiguration(this.cursorConfig);
}));
......@@ -375,7 +392,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
this.decorations.onLineMappingChanged();
this.viewLayout.onFlushed(this.getLineCount());
} finally {
this._endEmitViewEvents();
this._endEmitViewEvents(this._eventDispatcher);
}
this._updateConfigurationViewLineCount.schedule();
}
......@@ -386,7 +403,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
this._register(this.model.onDidChangeDecorations((e) => {
this.decorations.onModelDecorationsChanged();
this._emitSingleViewEvent(new viewEvents.ViewDecorationsChangedEvent(e));
this._emitSingleViewEvent(this._eventDispatcher, new viewEvents.ViewDecorationsChangedEvent(e));
}));
}
......@@ -404,7 +421,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
this.viewLayout.onHeightMaybeChanged();
}
} finally {
this._endEmitViewEvents();
this._endEmitViewEvents(this._eventDispatcher);
}
this._updateConfigurationViewLineCount.schedule();
}
......@@ -951,7 +968,10 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
this.viewLayout.deltaScrollNow(deltaScrollLeft, deltaScrollTop);
}
public changeWhitespace(callback: (accessor: IWhitespaceChangeAccessor) => void): void {
return this.viewLayout.changeWhitespace(callback);
const hadAChange = this.viewLayout.changeWhitespace(callback);
if (hadAChange) {
this._emitSingleViewEvent(this._eventDispatcher, new viewEvents.ViewZonesChangedEvent());
}
}
public setMaxLineWidth(maxLineWidth: number): void {
this.viewLayout.setMaxLineWidth(maxLineWidth);
......@@ -963,7 +983,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
const eventsCollector = this._beginEmitViewEvents();
callback(eventsCollector);
} finally {
this._endEmitViewEvents();
this._endEmitViewEvents(this._eventDispatcher);
}
}
}
......@@ -7,6 +7,8 @@ import * as assert from 'assert';
import { Range } from 'vs/editor/common/core/range';
import { EndOfLineSequence } from 'vs/editor/common/model';
import { testViewModel } from 'vs/editor/test/common/viewModel/testViewModel';
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
import { ViewEvent } from 'vs/editor/common/view/viewEvents';
suite('ViewModel', () => {
......@@ -63,9 +65,11 @@ suite('ViewModel', () => {
let viewLineCount: number[] = [];
viewLineCount.push(viewModel.getLineCount());
viewModel.addViewEventListener((events) => {
// Access the view model
viewLineCount.push(viewModel.getLineCount());
viewModel.addViewEventHandler(new class extends ViewEventHandler {
handleEvents(events: ViewEvent[]): void {
// Access the view model
viewLineCount.push(viewModel.getLineCount());
}
});
model.undo();
viewLineCount.push(viewModel.getLineCount());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册