--- /dev/null
+"use strict";
+/* --------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ * ------------------------------------------------------------------------------------------ */
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Emitter = exports.Event = void 0;
+const ral_1 = require("./ral");
+var Event;
+(function (Event) {
+ const _disposable = { dispose() { } };
+ Event.None = function () { return _disposable; };
+})(Event = exports.Event || (exports.Event = {}));
+class CallbackList {
+ add(callback, context = null, bucket) {
+ if (!this._callbacks) {
+ this._callbacks = [];
+ this._contexts = [];
+ }
+ this._callbacks.push(callback);
+ this._contexts.push(context);
+ if (Array.isArray(bucket)) {
+ bucket.push({ dispose: () => this.remove(callback, context) });
+ }
+ }
+ remove(callback, context = null) {
+ if (!this._callbacks) {
+ return;
+ }
+ let foundCallbackWithDifferentContext = false;
+ for (let i = 0, len = this._callbacks.length; i < len; i++) {
+ if (this._callbacks[i] === callback) {
+ if (this._contexts[i] === context) {
+ // callback & context match => remove it
+ this._callbacks.splice(i, 1);
+ this._contexts.splice(i, 1);
+ return;
+ }
+ else {
+ foundCallbackWithDifferentContext = true;
+ }
+ }
+ }
+ if (foundCallbackWithDifferentContext) {
+ throw new Error('When adding a listener with a context, you should remove it with the same context');
+ }
+ }
+ invoke(...args) {
+ if (!this._callbacks) {
+ return [];
+ }
+ const ret = [], callbacks = this._callbacks.slice(0), contexts = this._contexts.slice(0);
+ for (let i = 0, len = callbacks.length; i < len; i++) {
+ try {
+ ret.push(callbacks[i].apply(contexts[i], args));
+ }
+ catch (e) {
+ // eslint-disable-next-line no-console
+ ral_1.default().console.error(e);
+ }
+ }
+ return ret;
+ }
+ isEmpty() {
+ return !this._callbacks || this._callbacks.length === 0;
+ }
+ dispose() {
+ this._callbacks = undefined;
+ this._contexts = undefined;
+ }
+}
+class Emitter {
+ constructor(_options) {
+ this._options = _options;
+ }
+ /**
+ * For the public to allow to subscribe
+ * to events from this Emitter
+ */
+ get event() {
+ if (!this._event) {
+ this._event = (listener, thisArgs, disposables) => {
+ if (!this._callbacks) {
+ this._callbacks = new CallbackList();
+ }
+ if (this._options && this._options.onFirstListenerAdd && this._callbacks.isEmpty()) {
+ this._options.onFirstListenerAdd(this);
+ }
+ this._callbacks.add(listener, thisArgs);
+ const result = {
+ dispose: () => {
+ if (!this._callbacks) {
+ // disposable is disposed after emitter is disposed.
+ return;
+ }
+ this._callbacks.remove(listener, thisArgs);
+ result.dispose = Emitter._noop;
+ if (this._options && this._options.onLastListenerRemove && this._callbacks.isEmpty()) {
+ this._options.onLastListenerRemove(this);
+ }
+ }
+ };
+ if (Array.isArray(disposables)) {
+ disposables.push(result);
+ }
+ return result;
+ };
+ }
+ return this._event;
+ }
+ /**
+ * To be kept private to fire an event to
+ * subscribers
+ */
+ fire(event) {
+ if (this._callbacks) {
+ this._callbacks.invoke.call(this._callbacks, event);
+ }
+ }
+ dispose() {
+ if (this._callbacks) {
+ this._callbacks.dispose();
+ this._callbacks = undefined;
+ }
+ }
+}
+exports.Emitter = Emitter;
+Emitter._noop = function () { };
+//# sourceMappingURL=events.js.map
\ No newline at end of file