123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- import { Emitter } from '../../../base/common/event.js';
- import { Disposable } from '../../../base/common/lifecycle.js';
- export class ViewModelEventDispatcher extends Disposable {
- constructor() {
- super();
- this._onEvent = this._register(new Emitter());
- this.onEvent = this._onEvent.event;
- this._eventHandlers = [];
- this._viewEventQueue = null;
- this._isConsumingViewEventQueue = false;
- this._collector = null;
- this._collectorCnt = 0;
- this._outgoingEvents = [];
- }
- emitOutgoingEvent(e) {
- this._addOutgoingEvent(e);
- this._emitOutgoingEvents();
- }
- _addOutgoingEvent(e) {
- for (let i = 0, len = this._outgoingEvents.length; i < len; i++) {
- if (this._outgoingEvents[i].kind === e.kind) {
- this._outgoingEvents[i] = this._outgoingEvents[i].merge(e);
- return;
- }
- }
- // not merged
- this._outgoingEvents.push(e);
- }
- _emitOutgoingEvents() {
- while (this._outgoingEvents.length > 0) {
- if (this._collector || this._isConsumingViewEventQueue) {
- // right now collecting or emitting view events, so let's postpone emitting
- return;
- }
- const event = this._outgoingEvents.shift();
- if (event.isNoOp()) {
- continue;
- }
- this._onEvent.fire(event);
- }
- }
- addViewEventHandler(eventHandler) {
- for (let i = 0, len = this._eventHandlers.length; i < len; i++) {
- if (this._eventHandlers[i] === eventHandler) {
- console.warn('Detected duplicate listener in ViewEventDispatcher', eventHandler);
- }
- }
- this._eventHandlers.push(eventHandler);
- }
- removeViewEventHandler(eventHandler) {
- for (let i = 0; i < this._eventHandlers.length; i++) {
- if (this._eventHandlers[i] === eventHandler) {
- this._eventHandlers.splice(i, 1);
- break;
- }
- }
- }
- beginEmitViewEvents() {
- this._collectorCnt++;
- if (this._collectorCnt === 1) {
- this._collector = new ViewModelEventsCollector();
- }
- return this._collector;
- }
- endEmitViewEvents() {
- this._collectorCnt--;
- if (this._collectorCnt === 0) {
- const outgoingEvents = this._collector.outgoingEvents;
- const viewEvents = this._collector.viewEvents;
- this._collector = null;
- for (const outgoingEvent of outgoingEvents) {
- this._addOutgoingEvent(outgoingEvent);
- }
- if (viewEvents.length > 0) {
- this._emitMany(viewEvents);
- }
- }
- this._emitOutgoingEvents();
- }
- emitSingleViewEvent(event) {
- try {
- const eventsCollector = this.beginEmitViewEvents();
- eventsCollector.emitViewEvent(event);
- }
- finally {
- this.endEmitViewEvents();
- }
- }
- _emitMany(events) {
- if (this._viewEventQueue) {
- this._viewEventQueue = this._viewEventQueue.concat(events);
- }
- else {
- this._viewEventQueue = events;
- }
- if (!this._isConsumingViewEventQueue) {
- this._consumeViewEventQueue();
- }
- }
- _consumeViewEventQueue() {
- try {
- this._isConsumingViewEventQueue = true;
- this._doConsumeQueue();
- }
- finally {
- this._isConsumingViewEventQueue = false;
- }
- }
- _doConsumeQueue() {
- while (this._viewEventQueue) {
- // Empty event queue, as events might come in while sending these off
- const events = this._viewEventQueue;
- this._viewEventQueue = null;
- // Use a clone of the event handlers list, as they might remove themselves
- const eventHandlers = this._eventHandlers.slice(0);
- for (const eventHandler of eventHandlers) {
- eventHandler.handleEvents(events);
- }
- }
- }
- }
- export class ViewModelEventsCollector {
- constructor() {
- this.viewEvents = [];
- this.outgoingEvents = [];
- }
- emitViewEvent(event) {
- this.viewEvents.push(event);
- }
- emitOutgoingEvent(e) {
- this.outgoingEvents.push(e);
- }
- }
- export class ContentSizeChangedEvent {
- constructor(oldContentWidth, oldContentHeight, contentWidth, contentHeight) {
- this.kind = 0 /* ContentSizeChanged */;
- this._oldContentWidth = oldContentWidth;
- this._oldContentHeight = oldContentHeight;
- this.contentWidth = contentWidth;
- this.contentHeight = contentHeight;
- this.contentWidthChanged = (this._oldContentWidth !== this.contentWidth);
- this.contentHeightChanged = (this._oldContentHeight !== this.contentHeight);
- }
- isNoOp() {
- return (!this.contentWidthChanged && !this.contentHeightChanged);
- }
- merge(other) {
- if (other.kind !== 0 /* ContentSizeChanged */) {
- return this;
- }
- return new ContentSizeChangedEvent(this._oldContentWidth, this._oldContentHeight, other.contentWidth, other.contentHeight);
- }
- }
- export class FocusChangedEvent {
- constructor(oldHasFocus, hasFocus) {
- this.kind = 1 /* FocusChanged */;
- this.oldHasFocus = oldHasFocus;
- this.hasFocus = hasFocus;
- }
- isNoOp() {
- return (this.oldHasFocus === this.hasFocus);
- }
- merge(other) {
- if (other.kind !== 1 /* FocusChanged */) {
- return this;
- }
- return new FocusChangedEvent(this.oldHasFocus, other.hasFocus);
- }
- }
- export class ScrollChangedEvent {
- constructor(oldScrollWidth, oldScrollLeft, oldScrollHeight, oldScrollTop, scrollWidth, scrollLeft, scrollHeight, scrollTop) {
- this.kind = 2 /* ScrollChanged */;
- this._oldScrollWidth = oldScrollWidth;
- this._oldScrollLeft = oldScrollLeft;
- this._oldScrollHeight = oldScrollHeight;
- this._oldScrollTop = oldScrollTop;
- this.scrollWidth = scrollWidth;
- this.scrollLeft = scrollLeft;
- this.scrollHeight = scrollHeight;
- this.scrollTop = scrollTop;
- this.scrollWidthChanged = (this._oldScrollWidth !== this.scrollWidth);
- this.scrollLeftChanged = (this._oldScrollLeft !== this.scrollLeft);
- this.scrollHeightChanged = (this._oldScrollHeight !== this.scrollHeight);
- this.scrollTopChanged = (this._oldScrollTop !== this.scrollTop);
- }
- isNoOp() {
- return (!this.scrollWidthChanged && !this.scrollLeftChanged && !this.scrollHeightChanged && !this.scrollTopChanged);
- }
- merge(other) {
- if (other.kind !== 2 /* ScrollChanged */) {
- return this;
- }
- return new ScrollChangedEvent(this._oldScrollWidth, this._oldScrollLeft, this._oldScrollHeight, this._oldScrollTop, other.scrollWidth, other.scrollLeft, other.scrollHeight, other.scrollTop);
- }
- }
- export class ViewZonesChangedEvent {
- constructor() {
- this.kind = 3 /* ViewZonesChanged */;
- }
- isNoOp() {
- return false;
- }
- merge(other) {
- return this;
- }
- }
- export class HiddenAreasChangedEvent {
- constructor() {
- this.kind = 4 /* HiddenAreasChanged */;
- }
- isNoOp() {
- return false;
- }
- merge(other) {
- return this;
- }
- }
- export class CursorStateChangedEvent {
- constructor(oldSelections, selections, oldModelVersionId, modelVersionId, source, reason, reachedMaxCursorCount) {
- this.kind = 6 /* CursorStateChanged */;
- this.oldSelections = oldSelections;
- this.selections = selections;
- this.oldModelVersionId = oldModelVersionId;
- this.modelVersionId = modelVersionId;
- this.source = source;
- this.reason = reason;
- this.reachedMaxCursorCount = reachedMaxCursorCount;
- }
- static _selectionsAreEqual(a, b) {
- if (!a && !b) {
- return true;
- }
- if (!a || !b) {
- return false;
- }
- const aLen = a.length;
- const bLen = b.length;
- if (aLen !== bLen) {
- return false;
- }
- for (let i = 0; i < aLen; i++) {
- if (!a[i].equalsSelection(b[i])) {
- return false;
- }
- }
- return true;
- }
- isNoOp() {
- return (CursorStateChangedEvent._selectionsAreEqual(this.oldSelections, this.selections)
- && this.oldModelVersionId === this.modelVersionId);
- }
- merge(other) {
- if (other.kind !== 6 /* CursorStateChanged */) {
- return this;
- }
- return new CursorStateChangedEvent(this.oldSelections, other.selections, this.oldModelVersionId, other.modelVersionId, other.source, other.reason, this.reachedMaxCursorCount || other.reachedMaxCursorCount);
- }
- }
- export class ReadOnlyEditAttemptEvent {
- constructor() {
- this.kind = 5 /* ReadOnlyEditAttempt */;
- }
- isNoOp() {
- return false;
- }
- merge(other) {
- return this;
- }
- }
|