A pixel art painter geared specifically at NES pixel art. Includes export for .chr binary file as well as palette and namespace data.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

194 行
6.3KB

  1. /**
  2. * Event caller/listener system. Intended to be extended by classes which require
  3. * an event callback system.
  4. */
  5. export class EventCaller{
  6. constructor(){
  7. this.__listeners = {};
  8. }
  9. /**
  10. * @type {number}
  11. */
  12. get totalListeners(){
  13. var count = 0;
  14. for (key in Object.keys(this.__listeners)){
  15. count += this.__listeners[key].length
  16. }
  17. return count;
  18. }
  19. /**
  20. * Returns true if the given callback is listening for the given event, and false otherwise.
  21. * @param {string} eventName - The name of the event to check.
  22. * @param {Function} callback - The function/method to check for
  23. * @param {Object} [owner=null] - The object to use as "this" when calling the callback function.
  24. * @returns {bool}
  25. */
  26. is_listening(eventName, callback, owner=null){
  27. if (typeof(eventName) !== 'string')
  28. throw new TypeError("Expected eventName to be string.");
  29. if (eventName.length <= 0)
  30. throw new ValueError("Argument eventName cannot be a zero-length string.");
  31. if (this.__listeners.hasOwnProperty(eventName)){
  32. if (typeof(callback) !== 'function')
  33. throw new TypeError("Expected callback argument to be a function or class method.");
  34. for (var i=0; i < this.__listeners[eventName].length; i++){
  35. if (this.__listeners[eventName][i][0] === callback &&
  36. this.__listeners[eventName][i][1] === owner){
  37. return true;
  38. }
  39. }
  40. }
  41. return false;
  42. }
  43. /**
  44. * Sets the given callback to listen for the given event.
  45. * If [once] is true, the callback will be cleared from the listeners list after the named
  46. * event has been emitted.
  47. * @param {string} eventName - The name of the event to listen for.
  48. * @param {Function} callback - The function to call when the given event is emitted.
  49. * @param {Object} [owner=null] - The owner to use when calling the callback.
  50. * @param {bool} [once=false] - If true, the callback will be cleared after the next emit of the given event.
  51. * @returns {this}
  52. */
  53. listen(eventName, callback, owner=null, once=false){
  54. try{
  55. if (!this.is_listening(eventName, callback, owner)){
  56. if (!this.__listeners.hasOwnProperty(eventName)){
  57. this.__listeners[eventName] = [];
  58. }
  59. this.__listeners[eventName].push([callback, owner, once]);
  60. }
  61. } catch (e) {
  62. throw e;
  63. }
  64. return this;
  65. }
  66. /**
  67. * Removes the given callback from the given event.
  68. * NOTE: If the listener callback was set with it's owner, that owner must be included
  69. * to remove the listener callback successfully.
  70. * @param {string} eventName - The name of the event to remove from.
  71. * @param {Function} callback - The function/method to remove.
  72. * @param {Object} [owner=null] - The owner of the callback.
  73. * @returns {this}
  74. */
  75. unlisten(eventName, callback, owner=null){
  76. if (typeof(eventName) !== 'string')
  77. throw new TypeError("Expected eventName to be string.");
  78. if (eventName.length <= 0)
  79. throw new ValueError("Argument eventName cannot be a zero-length string.");
  80. if (this.__listeners.hasOwnProperty(eventName)){
  81. if (typeof(callback) !== 'function')
  82. throw new TypeError("Expected callback argument to be a function or class method.");
  83. for (var i=0; i < this.__listeners[eventName].length; i++){
  84. if (this.__listeners[eventName][i][0] === callback &&
  85. this.__listeners[eventName][i][1] === owner){
  86. this.__listeners[eventName].splice(i, 1);
  87. if (this.__listeners[eventName].length <= 0)
  88. delete this.__listeners[eventName];
  89. break;
  90. }
  91. }
  92. }
  93. return this;
  94. }
  95. /**
  96. * Removes all listeners from the given event.
  97. * @param {string} eventName - The name of the event to clear listeners from.
  98. * @returns {this}
  99. */
  100. unlisten_event(eventName){
  101. if (typeof(eventName) !== 'string')
  102. throw new TypeError("Expected eventName to be string.");
  103. if (eventName.length <= 0)
  104. throw new ValueError("Argument eventName cannot be a zero-length string.");
  105. if (this.__listener.hasOwnProperty(eventName))
  106. delete this.__listener[eventName];
  107. return this;
  108. }
  109. /**
  110. * Removes all listeners.
  111. * @returns {this}
  112. */
  113. unlisten_all(){
  114. // NOTE: Perhaps it's better to loop through and delete each property? This should do for now though.
  115. this.__listeners = {};
  116. return this;
  117. }
  118. /**
  119. * Returns the count of listeners attached to the given event.
  120. * @param {string} eventName - The name of the event to get the count of.
  121. * @returns {number}
  122. */
  123. event_listener_count(eventName){
  124. if (typeof(eventName) !== 'string')
  125. throw new TypeError("Expected eventName to be string.");
  126. if (eventName.length <= 0)
  127. throw new ValueError("Argument eventName cannot be a zero-length string.");
  128. if (this.__listener.hasOwnProperty(eventName)){
  129. return this.__listener.length;
  130. }
  131. return 0;
  132. }
  133. /**
  134. * Emits the given event, calling all listener callbacks attached to the event and passing each
  135. * the arguments (if any) given.
  136. * NOTE: All listeners of the given event designated to only listen once will be removed after
  137. * this call.
  138. * @param {string} eventName - The name of the event to emit.
  139. * @param {...*} args - The arguments to pass to every listener of this event.
  140. * @returns {this}
  141. */
  142. emit(){
  143. var args = Array.from(arguments);
  144. if (args.length <= 0)
  145. throw new Error("Missing required eventName argument.");
  146. var eventName = args[0];
  147. args = args.slice(1);
  148. if (typeof(eventName) !== 'string')
  149. throw new TypeError("Expected eventName to be string.");
  150. if (eventName.length <= 0)
  151. throw new ValueError("Argument eventName cannot be a zero-length string.");
  152. var once = [];
  153. if (this.__listeners.hasOwnProperty(eventName)){
  154. for (var i=0; i < this.__listeners[eventName].length; i++){
  155. var cb = this.__listeners[eventName][i][0];
  156. var own = this.__listeners[eventName][i][1];
  157. if (this.__listeners[eventName][i][2] === true)
  158. once.push([cb, own]);
  159. cb.apply(own, args);
  160. }
  161. if (once.length > 0){
  162. for (var i=0; i < once.length; i++){
  163. this.unlisten(eventName, once[i][0], once[i][1]);
  164. }
  165. }
  166. }
  167. return this;
  168. }
  169. }