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文字以内のものにしてください。

201 行
6.4KB

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