EventDispatcher.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. class EventDispatcher {
  2. constructor() {
  3. this._listeners = {};
  4. this._IDcount = 0n;
  5. this._IDmap = new Map();
  6. };
  7. hasEventListener(type, listener) {
  8. return !!(this._listeners[type] && this._listeners[type].find(o => o.listener === listener));
  9. };
  10. addEventListener(type, listener, {
  11. once = false,
  12. } = {}) {
  13. if (typeof listener !== "function") return console.warn("Cannot bind a non-function as an event listener!");
  14. const listeners = this._listeners[type] || [];
  15. this._listeners[type] = listeners;
  16. let i = listeners.findIndex(o => o.listener === listener);
  17. if (i !== -1) return this._IDmap[listeners[i].id];
  18. let t = { listener, once, type, id: this._IDcount++ };
  19. this._IDmap.set(t.id, t);
  20. listeners.push(t);
  21. return t.id;
  22. };
  23. removeEventListenerByID(id) {
  24. if (typeof id !== "bigint" || !this._IDmap.has(id)) return false;
  25. let t = this._IDmap.get(id);
  26. this._IDmap.delete(id);
  27. let arr = this._listeners[t.type];
  28. arr.splice(arr.indexOf(t), 1);
  29. return true;
  30. };
  31. removeEventListener(typeOrID, listener) {
  32. if (this.removeEventListenerByID(typeOrID)) return true;
  33. const type = typeOrID;
  34. if (!(type in this._listeners)) return false;
  35. let arr = this._listeners[type],
  36. i = arr.findIndex(o => o.listener === listener);
  37. if (i !== -1) {
  38. this._IDmap.delete(arr[i].id);
  39. arr.splice(i, 1);
  40. }
  41. return true;
  42. };
  43. dispatchEvent(type, ...datas) {
  44. if (!(type in this._listeners)) return;
  45. return this._listeners[type].slice(0).map(o => {
  46. o.listener(...datas);
  47. if (o.once) this.removeEventListenerByID(o.id);
  48. });
  49. };
  50. };
  51. class EventDispatcherManager {
  52. constructor() {
  53. this._eventDispatchers = {};
  54. };
  55. hasEventDispatcher(name) {
  56. return !!this._eventDispatchers[name];
  57. };
  58. addEventDispatcher(name, eventDispatcher = new EventDispatcher()) {
  59. return this._eventDispatchers[name] = eventDispatcher;
  60. };
  61. getOrNewEventDispatcher(name) {
  62. if (!(name in this._eventDispatchers))
  63. this.addEventDispatcher(name);
  64. return this._eventDispatchers[name];
  65. };
  66. removeEventDispatcher(name) {
  67. delete this._eventDispatchers[name];
  68. };
  69. };
  70. const eventDispatcherManager = new EventDispatcherManager();
  71. export {
  72. EventDispatcher,
  73. eventDispatcherManager,
  74. eventDispatcherManager as edm,
  75. };