/demo/project/source/as/extraclasses/hype/framework/rhythm/RhythmManager.as

https://github.com/netoleal/ASDevs.MVC · ActionScript · 331 lines · 260 code · 68 blank · 3 comment · 82 complexity · 15901bda32a7f9e2e2fdce923841d514 MD5 · raw file

  1. package hype.framework.rhythm {
  2. import hype.framework.core.TimeType;
  3. import flash.display.Sprite;
  4. import flash.events.Event;
  5. import flash.utils.Dictionary;
  6. import flash.utils.clearInterval;
  7. import flash.utils.setInterval;
  8. /**
  9. * @private
  10. */
  11. public class RhythmManager {
  12. private static var instanceTable:Object = new Object();
  13. private var _rhythmTable:Dictionary;
  14. private var _enterFrameHead:RhythmInfo;
  15. private var _enterFrameTail:RhythmInfo;
  16. private var _exitFrameHead:RhythmInfo;
  17. private var _exitFrameTail:RhythmInfo;
  18. private var _processingFlag:Boolean;
  19. private var _removeList:Array;
  20. private var _helperSprite:Sprite;
  21. public function RhythmManager() {
  22. _rhythmTable = new Dictionary(false);
  23. _helperSprite = new Sprite();
  24. _processingFlag = false;
  25. _removeList = new Array();
  26. }
  27. public static function getManager(name:String="default"):RhythmManager {
  28. if (instanceTable[name] == null) {
  29. instanceTable[name] = new RhythmManager();
  30. }
  31. return instanceTable[name];
  32. }
  33. public function toString():String {
  34. var str:String = "ENTER_FRAME\n";
  35. var t:RhythmInfo = _enterFrameHead;
  36. while (t != _enterFrameTail) {
  37. str += t.toString() + "\n";
  38. t = t.next;
  39. }
  40. str += t.toString() + "\n\n";
  41. str += "EXIT_FRAME\n";
  42. t = _exitFrameHead;
  43. while (t != _exitFrameTail) {
  44. str += t.toString() + "\n";
  45. t = t.next;
  46. }
  47. str += t.toString() + "\n\n";
  48. return str;
  49. }
  50. public function addRhythm(rhythm:Object, method:Function=null):Boolean {
  51. if (_rhythmTable[rhythm] == null) {
  52. if (method == null) {
  53. method = rhythm["run"];
  54. }
  55. _rhythmTable[rhythm] = new RhythmInfo(this, rhythm, method);
  56. return true;
  57. } else {
  58. return false;
  59. }
  60. }
  61. public function removeRhythm(rhythm:Object):Boolean {
  62. if (_rhythmTable[rhythm] != null) {
  63. if (_processingFlag) {
  64. _removeList.push(rhythm);
  65. } else {
  66. stopRhythm(rhythm);
  67. _rhythmTable[rhythm] = null;
  68. delete _rhythmTable[rhythm];
  69. }
  70. return true;
  71. } else {
  72. return false;
  73. }
  74. }
  75. public function getRhythmInfo(rhythm:Object):RhythmInfo {
  76. return _rhythmTable[rhythm];
  77. }
  78. public function getRhythmsOfType(classType:Class):Array {
  79. var result:Array = new Array();
  80. for (var p:* in _rhythmTable) {
  81. if (p is classType) {
  82. result.push(p);
  83. }
  84. }
  85. return result;
  86. }
  87. public function startRhythm(rhythm:Object, type:String=null, interval:int=-1):Boolean {
  88. var rhythmInfo:RhythmInfo;
  89. rhythmInfo = _rhythmTable[rhythm];
  90. if (type == null) {
  91. type = rhythmInfo.type;
  92. }
  93. if (interval == -1) {
  94. interval = rhythmInfo.interval;
  95. }
  96. if (type == null || interval == -1) {
  97. throw new Error("HYPE Error: You must either reuse a RhythmInfo object or specify a type and interval for the rhythm");
  98. }
  99. if (rhythmInfo != null && !rhythmInfo.isRunning && interval > 0) {
  100. switch (type) {
  101. case TimeType.ENTER_FRAME:
  102. if (_enterFrameHead == null) {
  103. _enterFrameHead =
  104. _enterFrameTail = rhythmInfo;
  105. } else {
  106. _enterFrameTail.next = rhythmInfo;
  107. rhythmInfo.prev = _enterFrameTail;
  108. _enterFrameTail = rhythmInfo;
  109. }
  110. if (_enterFrameHead == _enterFrameTail) {
  111. _helperSprite.addEventListener(Event.ENTER_FRAME, processEnterFrame);
  112. }
  113. rhythmInfo.isRunning = true;
  114. rhythmInfo.type = type;
  115. rhythmInfo.interval = interval;
  116. break;
  117. case TimeType.EXIT_FRAME:
  118. if (_exitFrameHead == null) {
  119. _exitFrameHead =
  120. _exitFrameTail = rhythmInfo;
  121. } else {
  122. _exitFrameTail.next = rhythmInfo;
  123. rhythmInfo.prev = _exitFrameTail;
  124. _exitFrameTail = rhythmInfo;
  125. }
  126. if (_exitFrameHead == _exitFrameTail) {
  127. _helperSprite.addEventListener(Event.EXIT_FRAME, processExitFrame);
  128. }
  129. rhythmInfo.isRunning = true;
  130. rhythmInfo.type = type;
  131. rhythmInfo.interval = interval;
  132. break;
  133. case TimeType.TIME:
  134. rhythmInfo.isRunning = true;
  135. rhythmInfo.type = type;
  136. rhythmInfo.interval = interval;
  137. rhythmInfo.timerId = setInterval(rhythmInfo.method, interval);
  138. rhythmInfo.type = type;
  139. rhythmInfo.interval = interval;
  140. break;
  141. default:
  142. return false;
  143. break;
  144. }
  145. return true;
  146. } else {
  147. return false;
  148. }
  149. }
  150. public function stopRhythm(rhythm:Object):Boolean {
  151. var rhythmInfo:RhythmInfo;
  152. rhythmInfo = _rhythmTable[rhythm];
  153. if (rhythmInfo != null && rhythmInfo.isRunning) {
  154. switch (rhythmInfo.type) {
  155. case (TimeType.ENTER_FRAME):
  156. if (_enterFrameHead == _enterFrameTail) {
  157. _helperSprite.removeEventListener(Event.ENTER_FRAME, processEnterFrame);
  158. _enterFrameHead =
  159. _enterFrameTail = null;
  160. } else {
  161. if (rhythmInfo.prev != null) {
  162. rhythmInfo.prev.next = rhythmInfo.next;
  163. if (_enterFrameTail == rhythmInfo) {
  164. _enterFrameTail = rhythmInfo.prev;
  165. _enterFrameTail.next = null;
  166. } else {
  167. rhythmInfo.next.prev = rhythmInfo.prev;
  168. }
  169. }
  170. if (rhythmInfo.next != null) {
  171. rhythmInfo.next.prev = rhythmInfo.prev;
  172. if (_enterFrameHead == rhythmInfo) {
  173. _enterFrameHead = rhythmInfo.next;
  174. _enterFrameHead.prev = null;
  175. } else {
  176. rhythmInfo.prev.next = rhythmInfo.next;
  177. }
  178. }
  179. }
  180. break;
  181. case (TimeType.EXIT_FRAME):
  182. if (_exitFrameHead == _exitFrameTail) {
  183. _helperSprite.removeEventListener(Event.EXIT_FRAME, processExitFrame);
  184. _exitFrameHead =
  185. _exitFrameTail = null;
  186. } else {
  187. if (rhythmInfo.prev != null) {
  188. rhythmInfo.prev.next = rhythmInfo.next;
  189. if (_exitFrameTail == rhythmInfo) {
  190. _exitFrameTail = rhythmInfo.prev;
  191. _exitFrameTail.next = null;
  192. } else {
  193. rhythmInfo.next.prev = rhythmInfo.prev;
  194. }
  195. }
  196. if (rhythmInfo.next != null) {
  197. rhythmInfo.next.prev = rhythmInfo.prev;
  198. if (_exitFrameHead == rhythmInfo) {
  199. _exitFrameHead = rhythmInfo.next;
  200. _enterFrameHead.prev = null;
  201. } else {
  202. rhythmInfo.prev.next = rhythmInfo.next;
  203. }
  204. }
  205. }
  206. break;
  207. case (TimeType.TIME):
  208. clearInterval(rhythmInfo.timerId);
  209. break;
  210. }
  211. rhythmInfo.isRunning = false;
  212. rhythmInfo.next = null;
  213. rhythmInfo.prev = null;
  214. return true;
  215. } else {
  216. return false;
  217. }
  218. }
  219. protected function processEnterFrame(event:Event):void {
  220. var rhythmInfo:RhythmInfo = _enterFrameHead;
  221. var nextRhythmInfo:RhythmInfo;
  222. _processingFlag = true;
  223. while (rhythmInfo != null) {
  224. nextRhythmInfo = rhythmInfo.next;
  225. ++rhythmInfo.counter;
  226. if (rhythmInfo.counter == rhythmInfo.interval) {
  227. rhythmInfo.counter = 0;
  228. rhythmInfo.method();
  229. }
  230. rhythmInfo = nextRhythmInfo;
  231. }
  232. _processingFlag = false;
  233. processRemovalQueue();
  234. }
  235. protected function processExitFrame(event:Event):void {
  236. var rhythmInfo:RhythmInfo = _exitFrameHead;
  237. var nextRhythmInfo:RhythmInfo;
  238. _processingFlag = true;
  239. while (rhythmInfo != null) {
  240. nextRhythmInfo = rhythmInfo.next;
  241. ++rhythmInfo.counter;
  242. if (rhythmInfo.counter == rhythmInfo.interval) {
  243. rhythmInfo.counter = 0;
  244. rhythmInfo.method();
  245. }
  246. rhythmInfo = nextRhythmInfo;
  247. }
  248. _processingFlag = false;
  249. processRemovalQueue();
  250. }
  251. protected function processRemovalQueue():void {
  252. var max:int = _removeList.length;
  253. var rhythm:Object;
  254. var i:int;
  255. for (i=0; i<max; ++i) {
  256. rhythm = _removeList.pop();
  257. stopRhythm(rhythm);
  258. _rhythmTable[rhythm] = null;
  259. delete _rhythmTable[rhythm];
  260. }
  261. }
  262. }
  263. }