Sequence.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.timing.Sequence"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.timing.Sequence"] = true;
  8. dojo.provide("dojox.timing.Sequence");
  9. dojo.experimental("dojox.timing.Sequence");
  10. dojo.declare("dojox.timing.Sequence", null, {
  11. // summary:
  12. // This class provides functionality to really sequentialize
  13. // function calls. You need to provide a list of functions and
  14. // some parameters for each (like: pauseBefore) and they will
  15. // be run one after another. This can be very useful for slideshows
  16. // or alike things.
  17. //
  18. // description:
  19. // This array will contain the sequence defines resolved, so that
  20. // ie. repeat:10 will result in 10 elements in the sequence, so
  21. // the repeat handling is easier and we don't need to handle that
  22. // many extra cases. Also the doneFunction, if given is added at the
  23. // end of the resolved-sequences.
  24. /*=====
  25. // _defsResolved: Array
  26. // The resolved sequence, for easier handling.
  27. _defsResolved: [],
  28. =====*/
  29. // This is the time to wait before goOn() calls _go(), which
  30. // mostly results from a pauseAfter for a function that returned
  31. // false and is later continued by the external goOn() call.
  32. // The time to wait needs to be waited in goOn() where the
  33. // sequence is continued.
  34. // _goOnPause: Integer
  35. // The pause to wait before really going on.
  36. _goOnPause: 0,
  37. _running: false,
  38. constructor: function(){
  39. this._defsResolved = [];
  40. },
  41. go: function(/* Array */defs, /* Function|Array? */doneFunction){
  42. // summary: Run the passed sequence definition
  43. //
  44. // defs: Array
  45. // The sequence of actions
  46. // doneFunction: Function|Array?
  47. // The function to call when done
  48. this._running = true;
  49. dojo.forEach(defs, function(cur){
  50. if(cur.repeat > 1){
  51. var repeat = cur.repeat;
  52. for(var j = 0; j < repeat; j++){
  53. cur.repeat = 1;
  54. this._defsResolved.push(cur);
  55. }
  56. }else{
  57. this._defsResolved.push(cur);
  58. }
  59. }, this);
  60. var last = defs[defs.length - 1];
  61. if(doneFunction){
  62. this._defsResolved.push({ func: doneFunction });
  63. }
  64. // stop the sequence, this actually just sets this._running to false
  65. this._defsResolved.push({ func: [this.stop, this] });
  66. this._curId = 0;
  67. this._go();
  68. },
  69. _go: function(){
  70. // summary: Execute one task of this._defsResolved.
  71. // if _running was set to false stop the sequence, this is the
  72. // case when i.e. stop() was called.
  73. if(!this._running){
  74. return;
  75. }
  76. var cur = this._defsResolved[this._curId];
  77. this._curId += 1;
  78. // create the function to call, the func property might be an array, which means
  79. // [function, context, parameter1, parameter2, ...]
  80. function resolveAndCallFunc(func) {
  81. var ret = null;
  82. if(dojo.isArray(func)){
  83. // Two elements might only be given when the function+context
  84. // is given, this is nice for using this, ie: [this.func, this]
  85. if(func.length>2){
  86. ret = func[0].apply(func[1], func.slice(2));
  87. }else{
  88. ret = func[0].apply(func[1]);
  89. }
  90. }else{
  91. ret = func();
  92. }
  93. return ret;
  94. }
  95. if(this._curId >= this._defsResolved.length){
  96. resolveAndCallFunc(cur.func); // call the last function, since it is the doneFunction we dont need to handle pause stuff
  97. // don't go on and call this._go() again, we are done
  98. return;
  99. }
  100. if(cur.pauseAfter){
  101. if(resolveAndCallFunc(cur.func) !== false){
  102. setTimeout(dojo.hitch(this, "_go"), cur.pauseAfter);
  103. }else{
  104. this._goOnPause = cur.pauseAfter;
  105. }
  106. }else if(cur.pauseBefore){
  107. var x = dojo.hitch(this,function(){
  108. if(resolveAndCallFunc(cur.func) !== false){
  109. this._go()
  110. }
  111. });
  112. setTimeout(x, cur.pauseBefore);
  113. }else{
  114. if(resolveAndCallFunc(cur.func) !== false){
  115. this._go();
  116. }
  117. }
  118. },
  119. goOn: function(){
  120. // summary: This method just provides a hook from the outside, so that
  121. // an interrupted sequence can be continued.
  122. if(this._goOnPause){
  123. setTimeout(dojo.hitch(this, "_go"), this._goOnPause);
  124. this._goOnPause = 0; // reset it, so if the next one doesnt set it we dont use the old pause
  125. }else{ this._go(); }
  126. },
  127. stop: function(){
  128. // summary: Stop the currently running sequence.
  129. //
  130. // description:
  131. // This can only interrupt the sequence not the last function that
  132. // had been started. If the last function was i.e. a slideshow
  133. // that is handled inside a function that you have given as
  134. // one sequence item it cant be stopped, since it is not controlled
  135. // by this object here. In this case it would be smarter to
  136. // run the slideshow using a sequence object so you can also stop
  137. // it using this method.
  138. this._running = false;
  139. }
  140. });
  141. }