export default function () {
     let listeners = new Map();
     return {
         emit (label, ...args) {
             let curListeners = listeners.get(label);
             if (curListeners && curListeners.length) {
                 curListeners.forEach((listener) => {
                     listener.callback.call(listener.vm,...args);
                     listener.once && this.off(label, listener.callback, listener.vm);
                 });
             }
         },

         on (key, fn, that) {
             listeners.has(key) || listeners.set(key, []);
             listeners.get(key).push({callback: fn, vm: that || this});
         },

         off (key, fn, that) {
             let lo_listeners = listeners.get(key);
             if (lo_listeners && lo_listeners.length) {
                 let index = lo_listeners.findIndex(listener => typeof listener.callback === 'function' && listener.callback === fn && listener.vm === (that || this));
                 if (index > -1) {
                     lo_listeners.splice(index, 1);
                     listeners.set(key, lo_listeners);
                 }
             }
         },

         once (key, fn, that) {
             listeners.has(key) || listeners.set(key, []);
             listeners.get(key).push({callback: fn, vm: that || this, once:true});
         },

         clear () {
             listeners.clear();
         }
     };
 }
