707 lines
25 KiB
JavaScript
Executable File
707 lines
25 KiB
JavaScript
Executable File
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
var __extends = (this && this.__extends) || (function () {
|
|
var extendStatics = function (d, b) {
|
|
extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
|
return extendStatics(d, b);
|
|
};
|
|
return function (d, b) {
|
|
extendStatics(d, b);
|
|
function __() { this.constructor = d; }
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
};
|
|
})();
|
|
import { onUnexpectedError } from './errors.js';
|
|
import { once as onceFn } from './functional.js';
|
|
import { combinedDisposable, Disposable, toDisposable } from './lifecycle.js';
|
|
import { LinkedList } from './linkedList.js';
|
|
export var Event;
|
|
(function (Event) {
|
|
var _disposable = { dispose: function () { } };
|
|
Event.None = function () { return _disposable; };
|
|
/**
|
|
* Given an event, returns another event which only fires once.
|
|
*/
|
|
function once(event) {
|
|
return function (listener, thisArgs, disposables) {
|
|
if (thisArgs === void 0) { thisArgs = null; }
|
|
// we need this, in case the event fires during the listener call
|
|
var didFire = false;
|
|
var result;
|
|
result = event(function (e) {
|
|
if (didFire) {
|
|
return;
|
|
}
|
|
else if (result) {
|
|
result.dispose();
|
|
}
|
|
else {
|
|
didFire = true;
|
|
}
|
|
return listener.call(thisArgs, e);
|
|
}, null, disposables);
|
|
if (didFire) {
|
|
result.dispose();
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
Event.once = once;
|
|
/**
|
|
* Given an event and a `map` function, returns another event which maps each element
|
|
* throught the mapping function.
|
|
*/
|
|
function map(event, map) {
|
|
return snapshot(function (listener, thisArgs, disposables) {
|
|
if (thisArgs === void 0) { thisArgs = null; }
|
|
return event(function (i) { return listener.call(thisArgs, map(i)); }, null, disposables);
|
|
});
|
|
}
|
|
Event.map = map;
|
|
/**
|
|
* Given an event and an `each` function, returns another identical event and calls
|
|
* the `each` function per each element.
|
|
*/
|
|
function forEach(event, each) {
|
|
return snapshot(function (listener, thisArgs, disposables) {
|
|
if (thisArgs === void 0) { thisArgs = null; }
|
|
return event(function (i) { each(i); listener.call(thisArgs, i); }, null, disposables);
|
|
});
|
|
}
|
|
Event.forEach = forEach;
|
|
function filter(event, filter) {
|
|
return snapshot(function (listener, thisArgs, disposables) {
|
|
if (thisArgs === void 0) { thisArgs = null; }
|
|
return event(function (e) { return filter(e) && listener.call(thisArgs, e); }, null, disposables);
|
|
});
|
|
}
|
|
Event.filter = filter;
|
|
/**
|
|
* Given an event, returns the same event but typed as `Event<void>`.
|
|
*/
|
|
function signal(event) {
|
|
return event;
|
|
}
|
|
Event.signal = signal;
|
|
/**
|
|
* Given a collection of events, returns a single event which emits
|
|
* whenever any of the provided events emit.
|
|
*/
|
|
function any() {
|
|
var events = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
events[_i] = arguments[_i];
|
|
}
|
|
return function (listener, thisArgs, disposables) {
|
|
if (thisArgs === void 0) { thisArgs = null; }
|
|
return combinedDisposable(events.map(function (event) { return event(function (e) { return listener.call(thisArgs, e); }, null, disposables); }));
|
|
};
|
|
}
|
|
Event.any = any;
|
|
/**
|
|
* Given an event and a `merge` function, returns another event which maps each element
|
|
* and the cummulative result throught the `merge` function. Similar to `map`, but with memory.
|
|
*/
|
|
function reduce(event, merge, initial) {
|
|
var output = initial;
|
|
return map(event, function (e) {
|
|
output = merge(output, e);
|
|
return output;
|
|
});
|
|
}
|
|
Event.reduce = reduce;
|
|
/**
|
|
* Given a chain of event processing functions (filter, map, etc), each
|
|
* function will be invoked per event & per listener. Snapshotting an event
|
|
* chain allows each function to be invoked just once per event.
|
|
*/
|
|
function snapshot(event) {
|
|
var listener;
|
|
var emitter = new Emitter({
|
|
onFirstListenerAdd: function () {
|
|
listener = event(emitter.fire, emitter);
|
|
},
|
|
onLastListenerRemove: function () {
|
|
listener.dispose();
|
|
}
|
|
});
|
|
return emitter.event;
|
|
}
|
|
Event.snapshot = snapshot;
|
|
function debounce(event, merge, delay, leading, leakWarningThreshold) {
|
|
if (delay === void 0) { delay = 100; }
|
|
if (leading === void 0) { leading = false; }
|
|
var subscription;
|
|
var output = undefined;
|
|
var handle = undefined;
|
|
var numDebouncedCalls = 0;
|
|
var emitter = new Emitter({
|
|
leakWarningThreshold: leakWarningThreshold,
|
|
onFirstListenerAdd: function () {
|
|
subscription = event(function (cur) {
|
|
numDebouncedCalls++;
|
|
output = merge(output, cur);
|
|
if (leading && !handle) {
|
|
emitter.fire(output);
|
|
}
|
|
clearTimeout(handle);
|
|
handle = setTimeout(function () {
|
|
var _output = output;
|
|
output = undefined;
|
|
handle = undefined;
|
|
if (!leading || numDebouncedCalls > 1) {
|
|
emitter.fire(_output);
|
|
}
|
|
numDebouncedCalls = 0;
|
|
}, delay);
|
|
});
|
|
},
|
|
onLastListenerRemove: function () {
|
|
subscription.dispose();
|
|
}
|
|
});
|
|
return emitter.event;
|
|
}
|
|
Event.debounce = debounce;
|
|
/**
|
|
* Given an event, it returns another event which fires only once and as soon as
|
|
* the input event emits. The event data is the number of millis it took for the
|
|
* event to fire.
|
|
*/
|
|
function stopwatch(event) {
|
|
var start = new Date().getTime();
|
|
return map(once(event), function (_) { return new Date().getTime() - start; });
|
|
}
|
|
Event.stopwatch = stopwatch;
|
|
/**
|
|
* Given an event, it returns another event which fires only when the event
|
|
* element changes.
|
|
*/
|
|
function latch(event) {
|
|
var firstCall = true;
|
|
var cache;
|
|
return filter(event, function (value) {
|
|
var shouldEmit = firstCall || value !== cache;
|
|
firstCall = false;
|
|
cache = value;
|
|
return shouldEmit;
|
|
});
|
|
}
|
|
Event.latch = latch;
|
|
/**
|
|
* Buffers the provided event until a first listener comes
|
|
* along, at which point fire all the events at once and
|
|
* pipe the event from then on.
|
|
*
|
|
* ```typescript
|
|
* const emitter = new Emitter<number>();
|
|
* const event = emitter.event;
|
|
* const bufferedEvent = buffer(event);
|
|
*
|
|
* emitter.fire(1);
|
|
* emitter.fire(2);
|
|
* emitter.fire(3);
|
|
* // nothing...
|
|
*
|
|
* const listener = bufferedEvent(num => console.log(num));
|
|
* // 1, 2, 3
|
|
*
|
|
* emitter.fire(4);
|
|
* // 4
|
|
* ```
|
|
*/
|
|
function buffer(event, nextTick, _buffer) {
|
|
if (nextTick === void 0) { nextTick = false; }
|
|
if (_buffer === void 0) { _buffer = []; }
|
|
var buffer = _buffer.slice();
|
|
var listener = event(function (e) {
|
|
if (buffer) {
|
|
buffer.push(e);
|
|
}
|
|
else {
|
|
emitter.fire(e);
|
|
}
|
|
});
|
|
var flush = function () {
|
|
if (buffer) {
|
|
buffer.forEach(function (e) { return emitter.fire(e); });
|
|
}
|
|
buffer = null;
|
|
};
|
|
var emitter = new Emitter({
|
|
onFirstListenerAdd: function () {
|
|
if (!listener) {
|
|
listener = event(function (e) { return emitter.fire(e); });
|
|
}
|
|
},
|
|
onFirstListenerDidAdd: function () {
|
|
if (buffer) {
|
|
if (nextTick) {
|
|
setTimeout(flush);
|
|
}
|
|
else {
|
|
flush();
|
|
}
|
|
}
|
|
},
|
|
onLastListenerRemove: function () {
|
|
if (listener) {
|
|
listener.dispose();
|
|
}
|
|
listener = null;
|
|
}
|
|
});
|
|
return emitter.event;
|
|
}
|
|
Event.buffer = buffer;
|
|
var ChainableEvent = /** @class */ (function () {
|
|
function ChainableEvent(event) {
|
|
this.event = event;
|
|
}
|
|
ChainableEvent.prototype.map = function (fn) {
|
|
return new ChainableEvent(map(this.event, fn));
|
|
};
|
|
ChainableEvent.prototype.forEach = function (fn) {
|
|
return new ChainableEvent(forEach(this.event, fn));
|
|
};
|
|
ChainableEvent.prototype.filter = function (fn) {
|
|
return new ChainableEvent(filter(this.event, fn));
|
|
};
|
|
ChainableEvent.prototype.reduce = function (merge, initial) {
|
|
return new ChainableEvent(reduce(this.event, merge, initial));
|
|
};
|
|
ChainableEvent.prototype.latch = function () {
|
|
return new ChainableEvent(latch(this.event));
|
|
};
|
|
ChainableEvent.prototype.on = function (listener, thisArgs, disposables) {
|
|
return this.event(listener, thisArgs, disposables);
|
|
};
|
|
ChainableEvent.prototype.once = function (listener, thisArgs, disposables) {
|
|
return once(this.event)(listener, thisArgs, disposables);
|
|
};
|
|
return ChainableEvent;
|
|
}());
|
|
function chain(event) {
|
|
return new ChainableEvent(event);
|
|
}
|
|
Event.chain = chain;
|
|
function fromNodeEventEmitter(emitter, eventName, map) {
|
|
if (map === void 0) { map = function (id) { return id; }; }
|
|
var fn = function () {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
return result.fire(map.apply(void 0, args));
|
|
};
|
|
var onFirstListenerAdd = function () { return emitter.on(eventName, fn); };
|
|
var onLastListenerRemove = function () { return emitter.removeListener(eventName, fn); };
|
|
var result = new Emitter({ onFirstListenerAdd: onFirstListenerAdd, onLastListenerRemove: onLastListenerRemove });
|
|
return result.event;
|
|
}
|
|
Event.fromNodeEventEmitter = fromNodeEventEmitter;
|
|
function fromPromise(promise) {
|
|
var emitter = new Emitter();
|
|
var shouldEmit = false;
|
|
promise
|
|
.then(undefined, function () { return null; })
|
|
.then(function () {
|
|
if (!shouldEmit) {
|
|
setTimeout(function () { return emitter.fire(undefined); }, 0);
|
|
}
|
|
else {
|
|
emitter.fire(undefined);
|
|
}
|
|
});
|
|
shouldEmit = true;
|
|
return emitter.event;
|
|
}
|
|
Event.fromPromise = fromPromise;
|
|
function toPromise(event) {
|
|
return new Promise(function (c) { return once(event)(c); });
|
|
}
|
|
Event.toPromise = toPromise;
|
|
})(Event || (Event = {}));
|
|
var _globalLeakWarningThreshold = -1;
|
|
var LeakageMonitor = /** @class */ (function () {
|
|
function LeakageMonitor(customThreshold, name) {
|
|
if (name === void 0) { name = Math.random().toString(18).slice(2, 5); }
|
|
this.customThreshold = customThreshold;
|
|
this.name = name;
|
|
this._warnCountdown = 0;
|
|
}
|
|
LeakageMonitor.prototype.dispose = function () {
|
|
if (this._stacks) {
|
|
this._stacks.clear();
|
|
}
|
|
};
|
|
LeakageMonitor.prototype.check = function (listenerCount) {
|
|
var _this = this;
|
|
var threshold = _globalLeakWarningThreshold;
|
|
if (typeof this.customThreshold === 'number') {
|
|
threshold = this.customThreshold;
|
|
}
|
|
if (threshold <= 0 || listenerCount < threshold) {
|
|
return undefined;
|
|
}
|
|
if (!this._stacks) {
|
|
this._stacks = new Map();
|
|
}
|
|
var stack = new Error().stack.split('\n').slice(3).join('\n');
|
|
var count = (this._stacks.get(stack) || 0);
|
|
this._stacks.set(stack, count + 1);
|
|
this._warnCountdown -= 1;
|
|
if (this._warnCountdown <= 0) {
|
|
// only warn on first exceed and then every time the limit
|
|
// is exceeded by 50% again
|
|
this._warnCountdown = threshold * 0.5;
|
|
// find most frequent listener and print warning
|
|
var topStack_1;
|
|
var topCount_1 = 0;
|
|
this._stacks.forEach(function (count, stack) {
|
|
if (!topStack_1 || topCount_1 < count) {
|
|
topStack_1 = stack;
|
|
topCount_1 = count;
|
|
}
|
|
});
|
|
console.warn("[" + this.name + "] potential listener LEAK detected, having " + listenerCount + " listeners already. MOST frequent listener (" + topCount_1 + "):");
|
|
console.warn(topStack_1);
|
|
}
|
|
return function () {
|
|
var count = (_this._stacks.get(stack) || 0);
|
|
_this._stacks.set(stack, count - 1);
|
|
};
|
|
};
|
|
return LeakageMonitor;
|
|
}());
|
|
/**
|
|
* The Emitter can be used to expose an Event to the public
|
|
* to fire it from the insides.
|
|
* Sample:
|
|
class Document {
|
|
|
|
private _onDidChange = new Emitter<(value:string)=>any>();
|
|
|
|
public onDidChange = this._onDidChange.event;
|
|
|
|
// getter-style
|
|
// get onDidChange(): Event<(value:string)=>any> {
|
|
// return this._onDidChange.event;
|
|
// }
|
|
|
|
private _doIt() {
|
|
//...
|
|
this._onDidChange.fire(value);
|
|
}
|
|
}
|
|
*/
|
|
var Emitter = /** @class */ (function () {
|
|
function Emitter(options) {
|
|
this._disposed = false;
|
|
this._options = options;
|
|
this._leakageMon = _globalLeakWarningThreshold > 0
|
|
? new LeakageMonitor(this._options && this._options.leakWarningThreshold)
|
|
: undefined;
|
|
}
|
|
Object.defineProperty(Emitter.prototype, "event", {
|
|
/**
|
|
* For the public to allow to subscribe
|
|
* to events from this Emitter
|
|
*/
|
|
get: function () {
|
|
var _this = this;
|
|
if (!this._event) {
|
|
this._event = function (listener, thisArgs, disposables) {
|
|
if (!_this._listeners) {
|
|
_this._listeners = new LinkedList();
|
|
}
|
|
var firstListener = _this._listeners.isEmpty();
|
|
if (firstListener && _this._options && _this._options.onFirstListenerAdd) {
|
|
_this._options.onFirstListenerAdd(_this);
|
|
}
|
|
var remove = _this._listeners.push(!thisArgs ? listener : [listener, thisArgs]);
|
|
if (firstListener && _this._options && _this._options.onFirstListenerDidAdd) {
|
|
_this._options.onFirstListenerDidAdd(_this);
|
|
}
|
|
if (_this._options && _this._options.onListenerDidAdd) {
|
|
_this._options.onListenerDidAdd(_this, listener, thisArgs);
|
|
}
|
|
// check and record this emitter for potential leakage
|
|
var removeMonitor;
|
|
if (_this._leakageMon) {
|
|
removeMonitor = _this._leakageMon.check(_this._listeners.size);
|
|
}
|
|
var result;
|
|
result = {
|
|
dispose: function () {
|
|
if (removeMonitor) {
|
|
removeMonitor();
|
|
}
|
|
result.dispose = Emitter._noop;
|
|
if (!_this._disposed) {
|
|
remove();
|
|
if (_this._options && _this._options.onLastListenerRemove) {
|
|
var hasListeners = (_this._listeners && !_this._listeners.isEmpty());
|
|
if (!hasListeners) {
|
|
_this._options.onLastListenerRemove(_this);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
if (Array.isArray(disposables)) {
|
|
disposables.push(result);
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
return this._event;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
/**
|
|
* To be kept private to fire an event to
|
|
* subscribers
|
|
*/
|
|
Emitter.prototype.fire = function (event) {
|
|
if (this._listeners) {
|
|
// put all [listener,event]-pairs into delivery queue
|
|
// then emit all event. an inner/nested event might be
|
|
// the driver of this
|
|
if (!this._deliveryQueue) {
|
|
this._deliveryQueue = new LinkedList();
|
|
}
|
|
for (var iter = this._listeners.iterator(), e = iter.next(); !e.done; e = iter.next()) {
|
|
this._deliveryQueue.push([e.value, event]);
|
|
}
|
|
while (this._deliveryQueue.size > 0) {
|
|
var _a = this._deliveryQueue.shift(), listener = _a[0], event_1 = _a[1];
|
|
try {
|
|
if (typeof listener === 'function') {
|
|
listener.call(undefined, event_1);
|
|
}
|
|
else {
|
|
listener[0].call(listener[1], event_1);
|
|
}
|
|
}
|
|
catch (e) {
|
|
onUnexpectedError(e);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
Emitter.prototype.dispose = function () {
|
|
if (this._listeners) {
|
|
this._listeners.clear();
|
|
}
|
|
if (this._deliveryQueue) {
|
|
this._deliveryQueue.clear();
|
|
}
|
|
if (this._leakageMon) {
|
|
this._leakageMon.dispose();
|
|
}
|
|
this._disposed = true;
|
|
};
|
|
Emitter._noop = function () { };
|
|
return Emitter;
|
|
}());
|
|
export { Emitter };
|
|
var PauseableEmitter = /** @class */ (function (_super) {
|
|
__extends(PauseableEmitter, _super);
|
|
function PauseableEmitter(options) {
|
|
var _this = _super.call(this, options) || this;
|
|
_this._isPaused = 0;
|
|
_this._eventQueue = new LinkedList();
|
|
_this._mergeFn = options && options.merge;
|
|
return _this;
|
|
}
|
|
PauseableEmitter.prototype.pause = function () {
|
|
this._isPaused++;
|
|
};
|
|
PauseableEmitter.prototype.resume = function () {
|
|
if (this._isPaused !== 0 && --this._isPaused === 0) {
|
|
if (this._mergeFn) {
|
|
// use the merge function to create a single composite
|
|
// event. make a copy in case firing pauses this emitter
|
|
var events = this._eventQueue.toArray();
|
|
this._eventQueue.clear();
|
|
_super.prototype.fire.call(this, this._mergeFn(events));
|
|
}
|
|
else {
|
|
// no merging, fire each event individually and test
|
|
// that this emitter isn't paused halfway through
|
|
while (!this._isPaused && this._eventQueue.size !== 0) {
|
|
_super.prototype.fire.call(this, this._eventQueue.shift());
|
|
}
|
|
}
|
|
}
|
|
};
|
|
PauseableEmitter.prototype.fire = function (event) {
|
|
if (this._listeners) {
|
|
if (this._isPaused !== 0) {
|
|
this._eventQueue.push(event);
|
|
}
|
|
else {
|
|
_super.prototype.fire.call(this, event);
|
|
}
|
|
}
|
|
};
|
|
return PauseableEmitter;
|
|
}(Emitter));
|
|
export { PauseableEmitter };
|
|
var EventMultiplexer = /** @class */ (function () {
|
|
function EventMultiplexer() {
|
|
var _this = this;
|
|
this.hasListeners = false;
|
|
this.events = [];
|
|
this.emitter = new Emitter({
|
|
onFirstListenerAdd: function () { return _this.onFirstListenerAdd(); },
|
|
onLastListenerRemove: function () { return _this.onLastListenerRemove(); }
|
|
});
|
|
}
|
|
Object.defineProperty(EventMultiplexer.prototype, "event", {
|
|
get: function () {
|
|
return this.emitter.event;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
EventMultiplexer.prototype.add = function (event) {
|
|
var _this = this;
|
|
var e = { event: event, listener: null };
|
|
this.events.push(e);
|
|
if (this.hasListeners) {
|
|
this.hook(e);
|
|
}
|
|
var dispose = function () {
|
|
if (_this.hasListeners) {
|
|
_this.unhook(e);
|
|
}
|
|
var idx = _this.events.indexOf(e);
|
|
_this.events.splice(idx, 1);
|
|
};
|
|
return toDisposable(onceFn(dispose));
|
|
};
|
|
EventMultiplexer.prototype.onFirstListenerAdd = function () {
|
|
var _this = this;
|
|
this.hasListeners = true;
|
|
this.events.forEach(function (e) { return _this.hook(e); });
|
|
};
|
|
EventMultiplexer.prototype.onLastListenerRemove = function () {
|
|
var _this = this;
|
|
this.hasListeners = false;
|
|
this.events.forEach(function (e) { return _this.unhook(e); });
|
|
};
|
|
EventMultiplexer.prototype.hook = function (e) {
|
|
var _this = this;
|
|
e.listener = e.event(function (r) { return _this.emitter.fire(r); });
|
|
};
|
|
EventMultiplexer.prototype.unhook = function (e) {
|
|
if (e.listener) {
|
|
e.listener.dispose();
|
|
}
|
|
e.listener = null;
|
|
};
|
|
EventMultiplexer.prototype.dispose = function () {
|
|
this.emitter.dispose();
|
|
};
|
|
return EventMultiplexer;
|
|
}());
|
|
export { EventMultiplexer };
|
|
/**
|
|
* The EventBufferer is useful in situations in which you want
|
|
* to delay firing your events during some code.
|
|
* You can wrap that code and be sure that the event will not
|
|
* be fired during that wrap.
|
|
*
|
|
* ```
|
|
* const emitter: Emitter;
|
|
* const delayer = new EventDelayer();
|
|
* const delayedEvent = delayer.wrapEvent(emitter.event);
|
|
*
|
|
* delayedEvent(console.log);
|
|
*
|
|
* delayer.bufferEvents(() => {
|
|
* emitter.fire(); // event will not be fired yet
|
|
* });
|
|
*
|
|
* // event will only be fired at this point
|
|
* ```
|
|
*/
|
|
var EventBufferer = /** @class */ (function () {
|
|
function EventBufferer() {
|
|
this.buffers = [];
|
|
}
|
|
EventBufferer.prototype.wrapEvent = function (event) {
|
|
var _this = this;
|
|
return function (listener, thisArgs, disposables) {
|
|
return event(function (i) {
|
|
var buffer = _this.buffers[_this.buffers.length - 1];
|
|
if (buffer) {
|
|
buffer.push(function () { return listener.call(thisArgs, i); });
|
|
}
|
|
else {
|
|
listener.call(thisArgs, i);
|
|
}
|
|
}, undefined, disposables);
|
|
};
|
|
};
|
|
EventBufferer.prototype.bufferEvents = function (fn) {
|
|
var buffer = [];
|
|
this.buffers.push(buffer);
|
|
var r = fn();
|
|
this.buffers.pop();
|
|
buffer.forEach(function (flush) { return flush(); });
|
|
return r;
|
|
};
|
|
return EventBufferer;
|
|
}());
|
|
export { EventBufferer };
|
|
/**
|
|
* A Relay is an event forwarder which functions as a replugabble event pipe.
|
|
* Once created, you can connect an input event to it and it will simply forward
|
|
* events from that input event through its own `event` property. The `input`
|
|
* can be changed at any point in time.
|
|
*/
|
|
var Relay = /** @class */ (function () {
|
|
function Relay() {
|
|
var _this = this;
|
|
this.listening = false;
|
|
this.inputEvent = Event.None;
|
|
this.inputEventListener = Disposable.None;
|
|
this.emitter = new Emitter({
|
|
onFirstListenerDidAdd: function () {
|
|
_this.listening = true;
|
|
_this.inputEventListener = _this.inputEvent(_this.emitter.fire, _this.emitter);
|
|
},
|
|
onLastListenerRemove: function () {
|
|
_this.listening = false;
|
|
_this.inputEventListener.dispose();
|
|
}
|
|
});
|
|
this.event = this.emitter.event;
|
|
}
|
|
Object.defineProperty(Relay.prototype, "input", {
|
|
set: function (event) {
|
|
this.inputEvent = event;
|
|
if (this.listening) {
|
|
this.inputEventListener.dispose();
|
|
this.inputEventListener = event(this.emitter.fire, this.emitter);
|
|
}
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Relay.prototype.dispose = function () {
|
|
this.inputEventListener.dispose();
|
|
this.emitter.dispose();
|
|
};
|
|
return Relay;
|
|
}());
|
|
export { Relay };
|