<commit_before>
const RG = require('./rg');

/* Event pool can be used to emit events and register callbacks for listeners.
 * This decouples the emitter and listener from each other.
 * Each emitted event can contain an object 'args', which is emitted with the
 * event. This object can contain any data.
 */
const EventPool = function() { // {{{2
    this._listeners = {};
    this._nListeners = 0;

    // const _poolID = RG.EventPool.id;
    this._listenerID = 0;

};
RG.POOL = new EventPool(); // Dangerous, global objects

EventPool.prototype.getNumListeners = function() {
    return this._nListeners;
};

/* Emits an event with given name. args must be in object-notation ie.
 * {data: "abcd"} */
EventPool.prototype.emitEvent = function(evtName, args) {
    if (!RG.isNullOrUndef([evtName])) {
        if (this._listeners.hasOwnProperty(evtName)) {
            const called = this._listeners[evtName];
            for (let i = 0; i < called.length; i++) {
                called[i].notify(evtName, args);
            }
        }
        else {
            ++this._nListeners;
        }
    }
    else {
        RG.nullOrUndefError('EventPool: emitEvent',
            'Event name must be given.', evtName);
    }
};

/* Register an event listener. */
EventPool.prototype.listenEvent = function(evtName, obj) {
    if (!RG.isNullOrUndef([evtName])) {
        if (obj.hasOwnProperty('notify') || obj.hasNotify) {
            if (this._listeners.hasOwnProperty(evtName)) {
                const index = this._listeners[evtName].indexOf(obj);
                if (index === -1) {
                    this._listeners[evtName].push(obj);
                }
            }
            else {
                this._listeners[evtName] = [];
                this._listeners[evtName].push(obj);
            }
            if (!obj.hasOwnProperty('listenerID')) {
                obj.listenerID = this._listenerID++;
            }
        }
        else {
            let msg = 'evtName: ' + evtName;
            msg += '\nprototype: ' + JSON.stringify(obj.prototype);
            msg += '\nCannot add object. Listener must implement notify()!';
            RG.err('EventPool', 'listenEvent', msg);
        }
    }
    else {
        RG.err('EventPool', 'listenEvent', 'Event name not well defined.');
    }
};

/* Removes the object from a list of event listeners. */
EventPool.prototype.removeListener = function(obj) {
    if (obj.hasOwnProperty('listenerID')) {
        let nRemoved = 0;
        const id = obj.listenerID;
        Reflect.ownKeys(this._listeners).forEach(evt => {
            const index = this._listeners[evt].findIndex(obj =>
                obj.listenerID === id);
            if (index >= 0) {
                this._listeners[evt].splice(index, 1);
                ++nRemoved;
            }
        });
        if (nRemoved === 0) {
            RG.warn('EventPool', 'removeListener',
                `ListenerID ${obj.listenerID} not found`);
        }
        delete obj.listenerID;
    }
    else {
        const json = JSON.stringify(obj);
        RG.err('EventPool', 'removeListener',
            `No prop listener ID from on object ${json}`);
    }
};

/* Returns listeners for the given event. */
EventPool.prototype.getListeners = function(evtName) {
    if (this._listeners.hasOwnProperty(evtName)) {
        return this._listeners[evtName].slice();
    }
    return [];
};

EventPool.prototype.printListeners = function() {
    Reflect.ownKeys(this._listeners).forEach(evt => {
        RG.diag(`Listeners for event ${evt}`);
        RG.diag(this._listeners[evt]);
    });
};


EventPool.id = 0;

module.exports = EventPool;
<commit_msg>Fixed a bug related num of listeners.<commit_after>
const RG = require('./rg');

/* Event pool can be used to emit events and register callbacks for listeners.
 * This decouples the emitter and listener from each other.
 * Each emitted event can contain an object 'args', which is emitted with the
 * event. This object can contain any data.
 */
const EventPool = function() { // {{{2
    this._listeners = {};
    this._nListeners = 0;

    // const _poolID = RG.EventPool.id;
    this._listenerID = 0;

};
RG.POOL = new EventPool(); // Dangerous, global objects

EventPool.prototype.getNumListeners = function() {
    return this._nListeners;
};

/* Emits an event with given name. args must be in object-notation ie.
 * {data: "abcd"} */
EventPool.prototype.emitEvent = function(evtName, args) {
    if (!RG.isNullOrUndef([evtName])) {
        if (this._listeners.hasOwnProperty(evtName)) {
            const called = this._listeners[evtName];
            for (let i = 0, len = called.length; i < len; i++) {
                called[i].notify(evtName, args);
            }
        }
    }
    else {
        RG.nullOrUndefError('EventPool: emitEvent',
            'Event name must be given.', evtName);
    }
};

/* Register an event listener. */
EventPool.prototype.listenEvent = function(evtName, obj) {
    if (!RG.isNullOrUndef([evtName])) {
        if (obj.hasOwnProperty('notify') || obj.hasNotify) {
            if (this._listeners.hasOwnProperty(evtName)) {
                const index = this._listeners[evtName].indexOf(obj);
                if (index === -1) {
                    this._listeners[evtName].push(obj);
                }
            }
            else {
                this._listeners[evtName] = [];
                this._listeners[evtName].push(obj);
            }
            ++this._nListeners;
            if (!obj.hasOwnProperty('listenerID')) {
                obj.listenerID = this._listenerID++;
            }
        }
        else {
            let msg = 'evtName: ' + evtName;
            msg += '\nprototype: ' + JSON.stringify(obj.prototype);
            msg += '\nCannot add object. Listener must implement notify()!';
            RG.err('EventPool', 'listenEvent', msg);
        }
    }
    else {
        RG.err('EventPool', 'listenEvent', 'Event name not well defined.');
    }
};

/* Removes the object from a list of event listeners. */
EventPool.prototype.removeListener = function(obj) {
    if (obj.hasOwnProperty('listenerID')) {
        let nRemoved = 0;
        const id = obj.listenerID;
        Reflect.ownKeys(this._listeners).forEach(evt => {
            const index = this._listeners[evt].findIndex(obj =>
                obj.listenerID === id);
            if (index >= 0) {
                this._listeners[evt].splice(index, 1);
                ++nRemoved;
                --this._nListeners;
            }
        });
        if (nRemoved === 0) {
            RG.warn('EventPool', 'removeListener',
                `ListenerID ${obj.listenerID} not found`);
        }
        delete obj.listenerID;
    }
    else {
        const json = JSON.stringify(obj);
        RG.err('EventPool', 'removeListener',
            `No prop listener ID from on object ${json}`);
    }
};

/* Returns listeners for the given event. */
EventPool.prototype.getListeners = function(evtName) {
    if (this._listeners.hasOwnProperty(evtName)) {
        return this._listeners[evtName].slice();
    }
    return [];
};

EventPool.prototype.printListeners = function() {
    Reflect.ownKeys(this._listeners).forEach(evt => {
        RG.diag(`Listeners for event ${evt}`);
        RG.diag(this._listeners[evt]);
    });
};


EventPool.id = 0;

module.exports = EventPool;

{'fraction_non_alphanumeric': 0.13582089552238805, 'fraction_numerical': 0.0027137042062415195, 'mean_word_length': 2.0918624161073827, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1966830', 'n_tokens_mistral': 2155, 'n_tokens_neox': 2164, 'n_words': 504}