1 /**************************************************************************** 2 Copyright (c) 2008-2010 Ricardo Quesada 3 Copyright (c) 2011-2012 cocos2d-x.org 4 Copyright (c) 2013-2014 Chukong Technologies Inc. 5 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 27 28 /** 29 * Minimum priority level for user scheduling. 30 * @constant 31 * @type Number 32 */ 33 cc.PRIORITY_NON_SYSTEM = cc.PRIORITY_SYSTEM + 1; 34 35 /** 36 * Verify Array's Type 37 * @param {Array} arr 38 * @param {function} type 39 * @return {Boolean} 40 * @function 41 */ 42 cc.arrayVerifyType = function (arr, type) { 43 if (arr && arr.length > 0) { 44 for (var i = 0; i < arr.length; i++) { 45 if (!(arr[i] instanceof type)) { 46 cc.log(cc._LogInfos.arrayVerifyType); 47 return false; 48 } 49 } 50 } 51 return true; 52 }; 53 54 /** 55 * Searches for the first occurance of object and removes it. If object is not found the function has no effect. 56 * @function 57 * @param {Array} arr Source Array 58 * @param {*} delObj remove object 59 */ 60 cc.arrayRemoveObject = function (arr, delObj) { 61 for (var i = 0, l = arr.length; i < l; i++) { 62 if (arr[i] == delObj) { 63 arr.splice(i, 1); 64 break; 65 } 66 } 67 }; 68 69 /** 70 * Removes from arr all values in minusArr. For each Value in minusArr, the first matching instance in arr will be removed. 71 * @function 72 * @param {Array} arr Source Array 73 * @param {Array} minusArr minus Array 74 */ 75 cc.arrayRemoveArray = function (arr, minusArr) { 76 for (var i = 0, l = minusArr.length; i < l; i++) { 77 cc.arrayRemoveObject(arr, minusArr[i]); 78 } 79 }; 80 81 /** 82 * Inserts some objects at index 83 * @function 84 * @param {Array} arr 85 * @param {Array} addObjs 86 * @param {Number} index 87 * @return {Array} 88 */ 89 cc.arrayAppendObjectsToIndex = function(arr, addObjs,index){ 90 arr.splice.apply(arr, [index, 0].concat(addObjs)); 91 return arr; 92 }; 93 94 //data structures 95 /** 96 * A list double-linked list used for "updates with priority" 97 * @Class 98 * @Construct 99 * @param {cc.ListEntry} prev 100 * @param {cc.ListEntry} next 101 * @param {cc.Class} target not retained (retained by hashUpdateEntry) 102 * @param {Number} priority 103 * @param {Boolean} paused 104 * @param {Boolean} markedForDeletion selector will no longer be called and entry will be removed at end of the next tick 105 */ 106 cc.ListEntry = function (prev, next, target, priority, paused, markedForDeletion) { 107 this.prev = prev; 108 this.next = next; 109 this.target = target; 110 this.priority = priority; 111 this.paused = paused; 112 this.markedForDeletion = markedForDeletion; 113 }; 114 115 /** 116 * a update entry list 117 * @Class 118 * @Construct 119 * @param {cc.ListEntry} list Which list does it belong to ? 120 * @param {cc.ListEntry} entry entry in the list 121 * @param {cc.Class} target hash key (retained) 122 * @param {Array} hh 123 */ 124 cc.HashUpdateEntry = function (list, entry, target, hh) { 125 this.list = list; 126 this.entry = entry; 127 this.target = target; 128 this.hh = hh; 129 }; 130 131 // 132 /** 133 * Hash Element used for "selectors with interval" 134 * @Class 135 * @Construct 136 * @param {Array} timers 137 * @param {cc.Class} target hash key (retained) 138 * @param {Number} timerIndex 139 * @param {cc.Timer} currentTimer 140 * @param {Boolean} currentTimerSalvaged 141 * @param {Boolean} paused 142 * @param {Array} hh 143 */ 144 cc.HashTimerEntry = function (timers, target, timerIndex, currentTimer, currentTimerSalvaged, paused, hh) { 145 var _t = this; 146 _t.timers = timers; 147 _t.target = target; 148 _t.timerIndex = timerIndex; 149 _t.currentTimer = currentTimer; 150 _t.currentTimerSalvaged = currentTimerSalvaged; 151 _t.paused = paused; 152 _t.hh = hh; 153 }; 154 155 /** 156 * Light weight timer 157 * @class 158 * @extends cc.Class 159 */ 160 cc.Timer = cc.Class.extend(/** @lends cc.Timer# */{ 161 _interval:0.0, 162 _callback:null,//is called _callback before 163 164 _target:null,//target of _callback 165 _elapsed:0.0, 166 167 _runForever:false, 168 _useDelay:false, 169 _timesExecuted:0, 170 _repeat:0, //0 = once, 1 is 2 x executed 171 _delay:0, 172 173 /** 174 * @return {Number} returns interval of timer 175 */ 176 getInterval : function(){return this._interval;}, 177 /** 178 * @param {Number} interval set interval in seconds 179 */ 180 setInterval : function(interval){this._interval = interval;}, 181 182 /** 183 * @return {String|function} returns callback 184 */ 185 getCallback : function(){return this._callback}, 186 187 188 /** 189 * cc.Timer's Constructor 190 * Constructor of cc.Timer 191 * @param {cc.Class} target target 192 * @param {String|function} callback Selector 193 * @param {Number} [interval=0] second 194 * @param {Number} [repeat=cc.REPEAT_FOREVER] repeat times 195 * @param {Number} [delay=0] delay 196 */ 197 ctor:function (target, callback, interval, repeat, delay) { 198 var self = this; 199 self._target = target; 200 self._callback = callback; 201 self._elapsed = -1; 202 self._interval = interval || 0; 203 self._delay = delay || 0; 204 self._useDelay = self._delay > 0; 205 self._repeat = (repeat == null) ? cc.REPEAT_FOREVER : repeat; 206 self._runForever = (self._repeat == cc.REPEAT_FOREVER); 207 }, 208 209 _doCallback:function(){ 210 var self = this; 211 if (typeof(self._callback) == "string") 212 self._target[self._callback](self._elapsed); 213 else // if (typeof(this._callback) == "function") { 214 self._callback.call(self._target, self._elapsed); 215 }, 216 217 /** 218 * triggers the timer 219 * @param {Number} dt delta time 220 */ 221 update:function (dt) { 222 var self = this; 223 if (self._elapsed == -1) { 224 self._elapsed = 0; 225 self._timesExecuted = 0; 226 } else { 227 var locTarget = self._target, locCallback = self._callback; 228 self._elapsed += dt;//standard timer usage 229 if (self._runForever && !self._useDelay) { 230 if (self._elapsed >= self._interval) { 231 if (locTarget && locCallback) 232 self._doCallback(); 233 self._elapsed = 0; 234 } 235 } else { 236 //advanced usage 237 if (self._useDelay) { 238 if (self._elapsed >= self._delay) { 239 if (locTarget && locCallback) 240 self._doCallback(); 241 242 self._elapsed = self._elapsed - self._delay; 243 self._timesExecuted += 1; 244 self._useDelay = false; 245 } 246 } else { 247 if (self._elapsed >= self._interval) { 248 if (locTarget && locCallback) 249 self._doCallback(); 250 251 self._elapsed = 0; 252 self._timesExecuted += 1; 253 } 254 } 255 256 if (self._timesExecuted > self._repeat) 257 cc.director.getScheduler().unscheduleCallbackForTarget(locTarget, locCallback); 258 } 259 } 260 } 261 }); 262 263 /** 264 * <p> 265 * Scheduler is responsible of triggering the scheduled callbacks.<br/> 266 * You should not use NSTimer. Instead use this class.<br/> 267 * <br/> 268 * There are 2 different types of callbacks (selectors):<br/> 269 * - update callback: the 'update' callback will be called every frame. You can customize the priority.<br/> 270 * - custom callback: A custom callback will be called every frame, or with a custom interval of time<br/> 271 * <br/> 272 * The 'custom selectors' should be avoided when possible. It is faster, and consumes less memory to use the 'update callback'. * 273 * </p> 274 * @class 275 * @extends cc.Class 276 * 277 * @example 278 * //register a schedule to scheduler 279 * cc.director.getScheduler().scheduleSelector(callback, this, interval, !this._isRunning); 280 */ 281 cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{ 282 _timeScale:1.0, 283 284 _updates : null, //_updates[0] list of priority < 0, _updates[1] list of priority == 0, _updates[2] list of priority > 0, 285 286 _hashForUpdates:null, // hash used to fetch quickly the list entries for pause,delete,etc 287 _arrayForUpdates:null, 288 289 _hashForTimers:null, //Used for "selectors with interval" 290 _arrayForTimes:null, 291 292 _currentTarget:null, 293 _currentTargetSalvaged:false, 294 _updateHashLocked:false, //If true unschedule will not remove anything from a hash. Elements will only be marked for deletion. 295 296 /** 297 * Constructor 298 */ 299 ctor:function () { 300 var self = this; 301 self._timeScale = 1.0; 302 self._updates = [[], [], []]; 303 304 self._hashForUpdates = {}; 305 self._arrayForUpdates = []; 306 307 self._hashForTimers = {}; 308 self._arrayForTimers = []; 309 310 self._currentTarget = null; 311 self._currentTargetSalvaged = false; 312 self._updateHashLocked = false; 313 }, 314 315 //-----------------------private method---------------------- 316 _removeHashElement:function (element) { 317 delete this._hashForTimers[element.target.__instanceId]; 318 cc.arrayRemoveObject(this._arrayForTimers, element); 319 element.Timer = null; 320 element.target = null; 321 element = null; 322 }, 323 324 _removeUpdateFromHash:function (entry) { 325 var self = this, element = self._hashForUpdates[entry.target.__instanceId]; 326 if (element) { 327 //list entry 328 cc.arrayRemoveObject(element.list, element.entry); 329 330 delete self._hashForUpdates[element.target.__instanceId]; 331 cc.arrayRemoveObject(self._arrayForUpdates, element); 332 element.entry = null; 333 334 //hash entry 335 element.target = null; 336 } 337 }, 338 339 _priorityIn:function (ppList, target, priority, paused) { 340 var self = this, listElement = new cc.ListEntry(null, null, target, priority, paused, false); 341 342 // empey list ? 343 if (!ppList) { 344 ppList = []; 345 ppList.push(listElement); 346 } else { 347 var index2Insert = ppList.length - 1; 348 for(var i = 0; i <= index2Insert; i++){ 349 if (priority < ppList[i].priority) { 350 index2Insert = i; 351 break; 352 } 353 } 354 ppList.splice(i, 0, listElement); 355 } 356 357 //update hash entry for quick access 358 var hashElement = new cc.HashUpdateEntry(ppList, listElement, target, null); 359 self._arrayForUpdates.push(hashElement); 360 self._hashForUpdates[target.__instanceId] = hashElement; 361 362 return ppList; 363 }, 364 365 _appendIn:function (ppList, target, paused) { 366 var self = this, listElement = new cc.ListEntry(null, null, target, 0, paused, false); 367 ppList.push(listElement); 368 369 //update hash entry for quicker access 370 var hashElement = new cc.HashUpdateEntry(ppList, listElement, target, null); 371 self._arrayForUpdates.push(hashElement); 372 self._hashForUpdates[target.__instanceId] = hashElement; 373 }, 374 375 //-----------------------public method------------------------- 376 /** 377 * <p> 378 * Modifies the time of all scheduled callbacks.<br/> 379 * You can use this property to create a 'slow motion' or 'fast forward' effect.<br/> 380 * Default is 1.0. To create a 'slow motion' effect, use values below 1.0.<br/> 381 * To create a 'fast forward' effect, use values higher than 1.0.<br/> 382 * @warning It will affect EVERY scheduled selector / action. 383 * </p> 384 * @param {Number} timeScale 385 */ 386 setTimeScale:function (timeScale) { 387 this._timeScale = timeScale; 388 }, 389 390 /** 391 * returns time scale of scheduler 392 * @return {Number} 393 */ 394 getTimeScale:function () { 395 return this._timeScale; 396 }, 397 398 /** 399 * 'update' the scheduler. (You should NEVER call this method, unless you know what you are doing.) 400 * @param {Number} dt delta time 401 */ 402 update:function (dt) { 403 var self = this; 404 var locUpdates = self._updates, locArrayForTimers = self._arrayForTimers; 405 var tmpEntry, elt, i, li; 406 self._updateHashLocked = true; 407 408 if (this._timeScale != 1.0) { 409 dt *= this._timeScale; 410 } 411 412 for(i = 0, li = locUpdates.length; i < li && i >= 0; i++){ 413 var update = self._updates[i]; 414 for(var j = 0, lj = update.length; j < lj; j++){ 415 tmpEntry = update[j]; 416 if ((!tmpEntry.paused) && (!tmpEntry.markedForDeletion)) tmpEntry.target.update(dt); 417 } 418 } 419 420 //Interate all over the custom callbacks 421 for(i = 0, li = locArrayForTimers.length; i < li; i++){ 422 elt = locArrayForTimers[i]; 423 if(!elt) break; 424 self._currentTarget = elt; 425 self._currentTargetSalvaged = false; 426 427 if (!elt.paused) { 428 // The 'timers' array may change while inside this loop 429 for (elt.timerIndex = 0; elt.timerIndex < elt.timers.length; elt.timerIndex++) { 430 elt.currentTimer = elt.timers[elt.timerIndex]; 431 elt.currentTimerSalvaged = false; 432 433 elt.currentTimer.update(dt); 434 elt.currentTimer = null; 435 } 436 } 437 438 if ((self._currentTargetSalvaged) && (elt.timers.length == 0)){ 439 self._removeHashElement(elt); 440 i--; 441 } 442 } 443 444 for(i = 0, li = locUpdates.length; i < li; i++){ 445 var update = self._updates[i]; 446 for(var j = 0, lj = update.length; j < lj; ){ 447 tmpEntry = update[j]; 448 if(!tmpEntry) break; 449 if (tmpEntry.markedForDeletion) self._removeUpdateFromHash(tmpEntry); 450 else j++; 451 } 452 } 453 454 self._updateHashLocked = false; 455 self._currentTarget = null; 456 }, 457 458 /** 459 * <p> 460 * The scheduled method will be called every 'interval' seconds.</br> 461 * If paused is YES, then it won't be called until it is resumed.<br/> 462 * If 'interval' is 0, it will be called every frame, but if so, it recommended to use 'scheduleUpdateForTarget:' instead.<br/> 463 * If the callback function is already scheduled, then only the interval parameter will be updated without re-scheduling it again.<br/> 464 * repeat let the action be repeated repeat + 1 times, use cc.REPEAT_FOREVER to let the action run continuously<br/> 465 * delay is the amount of time the action will wait before it'll start<br/> 466 * </p> 467 * @param {cc.Class} target 468 * @param {function} callback_fn 469 * @param {Number} interval 470 * @param {Number} repeat 471 * @param {Number} delay 472 * @param {Boolean} paused 473 * @example 474 * //register a schedule to scheduler 475 * cc.director.getScheduler().scheduleCallbackForTarget(this, function, interval, repeat, delay, !this._isRunning ); 476 */ 477 scheduleCallbackForTarget:function (target, callback_fn, interval, repeat, delay, paused) { 478 479 cc.assert(callback_fn, cc._LogInfos.Scheduler_scheduleCallbackForTarget_2); 480 481 cc.assert(target, cc._LogInfos.Scheduler_scheduleCallbackForTarget_3); 482 483 // default arguments 484 interval = interval || 0; 485 repeat = (repeat == null) ? cc.REPEAT_FOREVER : repeat; 486 delay = delay || 0; 487 paused = paused || false; 488 489 var self = this, timer; 490 var element = self._hashForTimers[target.__instanceId]; 491 492 if (!element) { 493 // Is this the 1st element ? Then set the pause level to all the callback_fns of this target 494 element = new cc.HashTimerEntry(null, target, 0, null, null, paused, null); 495 self._arrayForTimers.push(element); 496 self._hashForTimers[target.__instanceId] = element; 497 } 498 499 if (element.timers == null) { 500 element.timers = []; 501 } else { 502 for (var i = 0; i < element.timers.length; i++) { 503 timer = element.timers[i]; 504 if (callback_fn == timer._callback) { 505 cc.log(cc._LogInfos.Scheduler_scheduleCallbackForTarget, timer.getInterval().toFixed(4), interval.toFixed(4)); 506 timer._interval = interval; 507 return; 508 } 509 } 510 } 511 512 timer = new cc.Timer(target, callback_fn, interval, repeat, delay); 513 element.timers.push(timer); 514 }, 515 516 /** 517 * <p> 518 * Schedules the 'update' callback_fn for a given target with a given priority.<br/> 519 * The 'update' callback_fn will be called every frame.<br/> 520 * The lower the priority, the earlier it is called. 521 * </p> 522 * @param {cc.Class} target 523 * @param {Number} priority 524 * @param {Boolean} paused 525 * @example 526 * //register this object to scheduler 527 * cc.director.getScheduler().scheduleUpdateForTarget(this, priority, !this._isRunning ); 528 */ 529 scheduleUpdateForTarget:function (target, priority, paused) { 530 if(target === null) 531 return; 532 var self = this, locUpdates = self._updates; 533 var hashElement = self._hashForUpdates[target.__instanceId]; 534 535 if (hashElement) { 536 // TODO: check if priority has changed! 537 hashElement.entry.markedForDeletion = false; 538 return; 539 } 540 541 // most of the updates are going to be 0, that's way there 542 // is an special list for updates with priority 0 543 if (priority == 0) { 544 self._appendIn(locUpdates[1], target, paused); 545 } else if (priority < 0) { 546 locUpdates[0] = self._priorityIn(locUpdates[0], target, priority, paused); 547 } else { 548 // priority > 0 549 locUpdates[2] = self._priorityIn(locUpdates[2], target, priority, paused); 550 } 551 }, 552 553 /** 554 * <p> 555 * Unschedule a callback function for a given target.<br/> 556 * If you want to unschedule the "update", use unscheudleUpdateForTarget. 557 * </p> 558 * @param {cc.Class} target 559 * @param {function} callback_fn 560 * @example 561 * //unschedule a callback of target 562 * cc.director.getScheduler().unscheduleCallbackForTarget(function, this); 563 */ 564 unscheduleCallbackForTarget:function (target, callback_fn) { 565 // explicity handle nil arguments when removing an object 566 if ((target == null) || (callback_fn == null)) { 567 return; 568 } 569 570 var self = this, element = self._hashForTimers[target.__instanceId]; 571 if (element) { 572 var timers = element.timers; 573 for(var i = 0, li = timers.length; i < li; i++){ 574 var timer = timers[i]; 575 if (callback_fn == timer._callback) { 576 if ((timer == element.currentTimer) && (!element.currentTimerSalvaged)) { 577 element.currentTimerSalvaged = true; 578 } 579 timers.splice(i, 1) 580 //update timerIndex in case we are in tick;, looping over the actions 581 if (element.timerIndex >= i) { 582 element.timerIndex--; 583 } 584 585 if (timers.length == 0) { 586 if (self._currentTarget == element) { 587 self._currentTargetSalvaged = true; 588 } else { 589 self._removeHashElement(element); 590 } 591 } 592 return; 593 } 594 } 595 } 596 }, 597 598 /** 599 * Unschedules the update callback function for a given target 600 * @param {cc.Class} target 601 * @example 602 * //unschedules the "update" method. 603 * cc.director.getScheduler().unscheduleUpdateForTarget(this); 604 */ 605 unscheduleUpdateForTarget:function (target) { 606 if (target == null) { 607 return; 608 } 609 610 var self = this, element = self._hashForUpdates[target.__instanceId]; 611 if (element != null) { 612 if (self._updateHashLocked) { 613 element.entry.markedForDeletion = true; 614 } else { 615 self._removeUpdateFromHash(element.entry); 616 } 617 } 618 }, 619 620 /** 621 * Unschedules all function callbacks for a given target. This also includes the "update" callback function. 622 * @param {cc.Class} target 623 */ 624 unscheduleAllCallbacksForTarget:function (target) { 625 //explicit NULL handling 626 if (target == null) { 627 return; 628 } 629 630 var self = this, element = self._hashForTimers[target.__instanceId]; 631 if (element) { 632 var timers = element.timers; 633 if ((!element.currentTimerSalvaged) && (timers.indexOf(element.currentTimer) >= 0)) { 634 element.currentTimerSalvaged = true; 635 } 636 timers.length = 0; 637 638 if (self._currentTarget == element) { 639 self._currentTargetSalvaged = true; 640 } else { 641 self._removeHashElement(element); 642 } 643 } 644 // update callback 645 self.unscheduleUpdateForTarget(target); 646 }, 647 648 /** 649 * <p> 650 * Unschedules all function callbacks from all targets. <br/> 651 * You should NEVER call this method, unless you know what you are doing. 652 * </p> 653 */ 654 unscheduleAllCallbacks:function () { 655 this.unscheduleAllCallbacksWithMinPriority(cc.Scheduler.PRIORITY_SYSTEM); 656 }, 657 658 /** 659 * <p> 660 * Unschedules all function callbacks from all targets with a minimum priority.<br/> 661 * You should only call this with kCCPriorityNonSystemMin or higher. 662 * </p> 663 * @param {Number} minPriority 664 */ 665 unscheduleAllCallbacksWithMinPriority:function (minPriority) { 666 // Custom Selectors 667 var self = this, locArrayForTimers = self._arrayForTimers, locUpdates = self._updates; 668 for(var i = 0, li = locArrayForTimers.length; i < li; i++){ 669 // element may be removed in unscheduleAllCallbacksForTarget 670 self.unscheduleAllCallbacksForTarget(locArrayForTimers[i].target); 671 } 672 for(var i = 2; i >= 0; i--){ 673 if((i == 1 && minPriority > 0) || (i == 0 && minPriority >= 0)) continue; 674 var updates = locUpdates[i]; 675 for(var j = 0, lj = updates.length; j < lj; j++){ 676 self.unscheduleUpdateForTarget(updates[j].target); 677 } 678 } 679 }, 680 681 /** 682 * <p> 683 * Pause all selectors from all targets.<br/> 684 * You should NEVER call this method, unless you know what you are doing. 685 * </p> 686 */ 687 pauseAllTargets:function () { 688 return this.pauseAllTargetsWithMinPriority(cc.Scheduler.PRIORITY_SYSTEM); 689 }, 690 691 /** 692 * Pause all selectors from all targets with a minimum priority. <br/> 693 * You should only call this with kCCPriorityNonSystemMin or higher. 694 * @param minPriority 695 */ 696 pauseAllTargetsWithMinPriority:function (minPriority) { 697 var idsWithSelectors = []; 698 699 var self = this, element, locArrayForTimers = self._arrayForTimers, locUpdates = self._updates; 700 // Custom Selectors 701 for(var i = 0, li = locArrayForTimers.length; i < li; i++){ 702 element = locArrayForTimers[i]; 703 if (element) { 704 element.paused = true; 705 idsWithSelectors.push(element.target); 706 } 707 } 708 for(var i = 0, li = locUpdates.length; i < li; i++){ 709 var updates = locUpdates[i]; 710 for(var j = 0, lj = updates.length; j < lj; j++){ 711 element = updates[j]; 712 if (element) { 713 element.paused = true; 714 idsWithSelectors.push(element.target); 715 } 716 } 717 } 718 return idsWithSelectors; 719 }, 720 721 /** 722 * Resume selectors on a set of targets.<br/> 723 * This can be useful for undoing a call to pauseAllCallbacks. 724 * @param targetsToResume 725 */ 726 resumeTargets:function (targetsToResume) { 727 if (!targetsToResume) 728 return; 729 730 for (var i = 0; i < targetsToResume.length; i++) { 731 this.resumeTarget(targetsToResume[i]); 732 } 733 }, 734 735 /** 736 * <p> 737 * Pauses the target.<br/> 738 * All scheduled selectors/update for a given target won't be 'ticked' until the target is resumed.<br/> 739 * If the target is not present, nothing happens. 740 * </p> 741 * @param {cc.Class} target 742 */ 743 pauseTarget:function (target) { 744 745 cc.assert(target, cc._LogInfos.Scheduler_pauseTarget); 746 747 //customer selectors 748 var self = this, element = self._hashForTimers[target.__instanceId]; 749 if (element) { 750 element.paused = true; 751 } 752 753 //update callback 754 var elementUpdate = self._hashForUpdates[target.__instanceId]; 755 if (elementUpdate) { 756 elementUpdate.entry.paused = true; 757 } 758 }, 759 760 /** 761 * Resumes the target.<br/> 762 * The 'target' will be unpaused, so all schedule selectors/update will be 'ticked' again.<br/> 763 * If the target is not present, nothing happens. 764 * @param {cc.Class} target 765 */ 766 resumeTarget:function (target) { 767 768 cc.assert(target, cc._LogInfos.Scheduler_resumeTarget); 769 770 // custom selectors 771 var self = this, element = self._hashForTimers[target.__instanceId]; 772 773 if (element) { 774 element.paused = false; 775 } 776 777 //update callback 778 var elementUpdate = self._hashForUpdates[target.__instanceId]; 779 780 if (elementUpdate) { 781 elementUpdate.entry.paused = false; 782 } 783 }, 784 785 /** 786 * Returns whether or not the target is paused 787 * @param {cc.Class} target 788 * @return {Boolean} 789 */ 790 isTargetPaused:function (target) { 791 792 cc.assert(target, cc._LogInfos.Scheduler_isTargetPaused); 793 794 // Custom selectors 795 var element = this._hashForTimers[target.__instanceId]; 796 if (element) { 797 return element.paused; 798 } 799 return false; 800 } 801 }); 802 /** 803 * Priority level reserved for system services. 804 * @constant 805 * @type Number 806 */ 807 cc.Scheduler.PRIORITY_SYSTEM = (-2147483647 - 1); 808