128 lines
		
	
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			128 lines
		
	
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "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
 | |
|                 (0, 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 () { };
 | 
