1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2008-2010 Ricardo Quesada 4 Copyright (c) 2011 Zynga 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("element type is wrong!"); 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 this.timers = timers; 146 this.target = target; 147 this.timerIndex = timerIndex; 148 this.currentTimer = currentTimer; 149 this.currentTimerSalvaged = currentTimerSalvaged; 150 this.paused = paused; 151 this.hh = hh; 152 }; 153 154 /** 155 * Light weight timer 156 * @class 157 * @extends cc.Class 158 */ 159 cc.Timer = cc.Class.extend(/** @lends cc.Timer# */{ 160 _interval:0.0, 161 _callback:null,//is called _callback before 162 163 _target:null,//target of _callback 164 _elapsed:0.0, 165 166 _runForever:false, 167 _useDelay:false, 168 _timesExecuted:0, 169 _repeat:0, //0 = once, 1 is 2 x executed 170 _delay:0, 171 172 /** 173 * @return {Number} returns interval of timer 174 */ 175 getInterval : function(){return this._interval;}, 176 /** 177 * @param {Number} interval set interval in seconds 178 */ 179 setInterval : function(interval){this._interval = interval;}, 180 181 /** 182 * @return {String|function} returns callback 183 */ 184 getCallback : function(){return this._callback}, 185 186 187 /** 188 * cc.Timer's Constructor 189 * @constructor 190 * @param {cc.Class} target target 191 * @param {String|function} selector Selector 192 * @param {Number} [seconds=0] second 193 * @param {Number} [repeat=cc.REPEAT_FOREVER] repeat times 194 * @param {Number} [delay=0] delay 195 */ 196 ctor:function (target, callback, interval, repeat, delay) { 197 var self = this; 198 self._target = target; 199 self._callback = callback; 200 self._elapsed = -1; 201 self._interval = interval || 0; 202 self._delay = delay || 0; 203 self._useDelay = self._delay > 0; 204 self._repeat = (repeat == null) ? cc.REPEAT_FOREVER : repeat; 205 self._runForever = (self._repeat == cc.REPEAT_FOREVER); 206 }, 207 208 _doCallback:function(){ 209 var self = this; 210 if (typeof(self._callback) == "string") 211 self._target[self._callback](self._elapsed); 212 else // if (typeof(this._callback) == "function") { 213 self._callback.call(self._target, self._elapsed); 214 }, 215 216 /** 217 * triggers the timer 218 * @param {Number} dt delta time 219 */ 220 update:function (dt) { 221 var self = this; 222 if (self._elapsed == -1) { 223 self._elapsed = 0; 224 self._timesExecuted = 0; 225 } else { 226 var locTarget = self._target, locCallback = self._callback; 227 self._elapsed += dt;//standard timer usage 228 if (self._runForever && !self._useDelay) { 229 if (self._elapsed >= self._interval) { 230 if (locTarget && locCallback) 231 self._doCallback(); 232 self._elapsed = 0; 233 } 234 } else { 235 //advanced usage 236 if (self._useDelay) { 237 if (self._elapsed >= self._delay) { 238 if (locTarget && locCallback) 239 self._doCallback(); 240 241 self._elapsed = self._elapsed - self._delay; 242 self._timesExecuted += 1; 243 self._useDelay = false; 244 } 245 } else { 246 if (self._elapsed >= self._interval) { 247 if (locTarget && locCallback) 248 self._doCallback(); 249 250 self._elapsed = 0; 251 self._timesExecuted += 1; 252 } 253 } 254 255 if (self._timesExecuted > self._repeat) 256 cc.director.getScheduler().unscheduleCallbackForTarget(locTarget, locCallback); 257 } 258 } 259 } 260 }); 261 262 /** 263 * <p> 264 * Scheduler is responsible of triggering the scheduled callbacks.<br/> 265 * You should not use NSTimer. Instead use this class.<br/> 266 * <br/> 267 * There are 2 different types of callbacks (selectors):<br/> 268 * - update callback: the 'update' callback will be called every frame. You can customize the priority.<br/> 269 * - custom callback: A custom callback will be called every frame, or with a custom interval of time<br/> 270 * <br/> 271 * The 'custom selectors' should be avoided when possible. It is faster, and consumes less memory to use the 'update callback'. * 272 * </p> 273 * @class 274 * @extends cc.Class 275 * 276 * @example 277 * //register a schedule to scheduler 278 * cc.director.getScheduler().scheduleSelector(callback, this, interval, !this._isRunning); 279 */ 280 cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{ 281 _timeScale:1.0, 282 283 _updates : null, //_updates[0] list of priority < 0, _updates[1] list of priority == 0, _updates[2] list of priority > 0, 284 285 _hashForUpdates:null, // hash used to fetch quickly the list entries for pause,delete,etc 286 _arrayForUpdates:null, 287 288 _hashForTimers:null, //Used for "selectors with interval" 289 _arrayForTimes:null, 290 291 _currentTarget:null, 292 _currentTargetSalvaged:false, 293 _updateHashLocked:false, //If true unschedule will not remove anything from a hash. Elements will only be marked for deletion. 294 295 /** 296 * Constructor 297 */ 298 ctor:function () { 299 var self = this; 300 self._timeScale = 1.0; 301 self._updates = [[], [], []]; 302 303 self._hashForUpdates = {}; 304 self._arrayForUpdates = []; 305 306 self._hashForTimers = {}; 307 self._arrayForTimers = []; 308 309 self._currentTarget = null; 310 self._currentTargetSalvaged = false; 311 self._updateHashLocked = false; 312 }, 313 314 //-----------------------private method---------------------- 315 _removeHashElement:function (element) { 316 delete this._hashForTimers[element.target.__instanceId]; 317 cc.arrayRemoveObject(this._arrayForTimers, element); 318 element.Timer = null; 319 element.target = null; 320 element = null; 321 }, 322 323 _removeUpdateFromHash:function (entry) { 324 var self = this, element = self._hashForUpdates[entry.target.__instanceId]; 325 if (element) { 326 //list entry 327 cc.arrayRemoveObject(element.list, element.entry); 328 329 delete self._hashForUpdates[element.target.__instanceId]; 330 cc.arrayRemoveObject(self._arrayForUpdates, element); 331 element.entry = null; 332 333 //hash entry 334 element.target = null; 335 } 336 }, 337 338 _priorityIn:function (ppList, target, priority, paused) { 339 var self = this, listElement = new cc.ListEntry(null, null, target, priority, paused, false); 340 341 // empey list ? 342 if (!ppList) { 343 ppList = []; 344 ppList.push(listElement); 345 } else { 346 var index2Insert = ppList.length - 1; 347 for(var i = 0; i <= index2Insert; i++){ 348 if (priority < ppList[i].priority) { 349 index2Insert = i; 350 break; 351 } 352 } 353 ppList.splice(i, 0, listElement); 354 } 355 356 //update hash entry for quick access 357 var hashElement = new cc.HashUpdateEntry(ppList, listElement, target, null); 358 self._arrayForUpdates.push(hashElement); 359 self._hashForUpdates[target.__instanceId] = hashElement; 360 361 return ppList; 362 }, 363 364 _appendIn:function (ppList, target, paused) { 365 var self = this, listElement = new cc.ListEntry(null, null, target, 0, paused, false); 366 ppList.push(listElement); 367 368 //update hash entry for quicker access 369 var hashElement = new cc.HashUpdateEntry(ppList, listElement, target, null); 370 self._arrayForUpdates.push(hashElement); 371 self._hashForUpdates[target.__instanceId] = hashElement; 372 }, 373 374 //-----------------------public method------------------------- 375 /** 376 * <p> 377 * Modifies the time of all scheduled callbacks.<br/> 378 * You can use this property to create a 'slow motion' or 'fast forward' effect.<br/> 379 * Default is 1.0. To create a 'slow motion' effect, use values below 1.0.<br/> 380 * To create a 'fast forward' effect, use values higher than 1.0.<br/> 381 * @warning It will affect EVERY scheduled selector / action. 382 * </p> 383 * @param {Number} timeScale 384 */ 385 setTimeScale:function (timeScale) { 386 this._timeScale = timeScale; 387 }, 388 389 /** 390 * returns time scale of scheduler 391 * @return {Number} 392 */ 393 getTimeScale:function () { 394 return this._timeScale; 395 }, 396 397 /** 398 * 'update' the scheduler. (You should NEVER call this method, unless you know what you are doing.) 399 * @param {Number} dt delta time 400 */ 401 update:function (dt) { 402 var self = this; 403 var locUpdates = self._updates, locArrayForTimers = self._arrayForTimers; 404 var tmpEntry, elt; 405 self._updateHashLocked = true; 406 407 if (this._timeScale != 1.0) { 408 dt *= this._timeScale; 409 } 410 411 for(var i = 0, li = locUpdates.length; i < li && i >= 0; i++){ 412 var update = self._updates[i]; 413 for(var j = 0, lj = update.length; j < lj; j++){ 414 tmpEntry = update[j]; 415 if ((!tmpEntry.paused) && (!tmpEntry.markedForDeletion)) tmpEntry.target.update(dt); 416 } 417 } 418 419 //Interate all over the custom callbacks 420 for(var i = 0, li = locArrayForTimers.length; i < li; i++){ 421 elt = locArrayForTimers[i]; 422 if(!elt) break; 423 self._currentTarget = elt; 424 self._currentTargetSalvaged = false; 425 426 if (!elt.paused) { 427 // The 'timers' array may change while inside this loop 428 for (elt.timerIndex = 0; elt.timerIndex < elt.timers.length; elt.timerIndex++) { 429 elt.currentTimer = elt.timers[elt.timerIndex]; 430 elt.currentTimerSalvaged = false; 431 432 elt.currentTimer.update(dt); 433 elt.currentTimer = null; 434 } 435 } 436 437 if ((self._currentTargetSalvaged) && (elt.timers.length == 0)){ 438 self._removeHashElement(elt); 439 i--; 440 } 441 } 442 443 for(var i = 0, li = locUpdates.length; i < li; i++){ 444 var update = self._updates[i]; 445 for(var j = 0, lj = update.length; j < lj; ){ 446 tmpEntry = update[j]; 447 if(!tmpEntry) break; 448 if (tmpEntry.markedForDeletion) self._removeUpdateFromHash(tmpEntry); 449 else j++; 450 } 451 } 452 453 self._updateHashLocked = false; 454 self._currentTarget = null; 455 }, 456 457 /** 458 * <p> 459 * The scheduled method will be called every 'interval' seconds.</br> 460 * If paused is YES, then it won't be called until it is resumed.<br/> 461 * If 'interval' is 0, it will be called every frame, but if so, it recommended to use 'scheduleUpdateForTarget:' instead.<br/> 462 * If the callback function is already scheduled, then only the interval parameter will be updated without re-scheduling it again.<br/> 463 * repeat let the action be repeated repeat + 1 times, use cc.REPEAT_FOREVER to let the action run continuously<br/> 464 * delay is the amount of time the action will wait before it'll start<br/> 465 * </p> 466 * @param {cc.Class} target 467 * @param {function} callback_fn 468 * @param {Number} interval 469 * @param {Number} repeat 470 * @param {Number} delay 471 * @param {Boolean} paused 472 * @example 473 * //register a schedule to scheduler 474 * cc.director.getScheduler().scheduleCallbackForTarget(this, function, interval, repeat, delay, !this._isRunning ); 475 */ 476 scheduleCallbackForTarget:function (target, callback_fn, interval, repeat, delay, paused) { 477 if(!callback_fn) 478 throw "cc.scheduler.scheduleCallbackForTarget(): callback_fn should be non-null."; 479 480 if(!target) 481 throw "cc.scheduler.scheduleCallbackForTarget(): target should be non-null."; 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("CCSheduler#scheduleCallback. Callback already scheduled. Updating interval from:" 506 + timer.getInterval().toFixed(4) + " to " + interval.toFixed(4)); 507 timer._interval = interval; 508 return; 509 } 510 } 511 } 512 513 timer = new cc.Timer(target, callback_fn, interval, repeat, delay); 514 element.timers.push(timer); 515 }, 516 517 /** 518 * <p> 519 * Schedules the 'update' callback_fn for a given target with a given priority.<br/> 520 * The 'update' callback_fn will be called every frame.<br/> 521 * The lower the priority, the earlier it is called. 522 * </p> 523 * @param {cc.Class} target 524 * @param {Number} priority 525 * @param {Boolean} paused 526 * @example 527 * //register this object to scheduler 528 * cc.director.getScheduler().scheduleUpdateForTarget(this, priority, !this._isRunning ); 529 */ 530 scheduleUpdateForTarget:function (target, priority, paused) { 531 var self = this, locUpdates = self._updates; 532 var hashElement = self._hashForUpdates[target.__instanceId]; 533 534 if (hashElement) { 535 // TODO: check if priority has changed! 536 hashElement.entry.markedForDeletion = false; 537 return; 538 } 539 540 // most of the updates are going to be 0, that's way there 541 // is an special list for updates with priority 0 542 if (priority == 0) { 543 self._appendIn(locUpdates[1], target, paused); 544 } else if (priority < 0) { 545 locUpdates[0] = self._priorityIn(locUpdates[0], target, priority, paused); 546 } else { 547 // priority > 0 548 locUpdates[2] = self._priorityIn(locUpdates[2], target, priority, paused); 549 } 550 }, 551 552 /** 553 * <p> 554 * Unschedule a callback function for a given target.<br/> 555 * If you want to unschedule the "update", use unscheudleUpdateForTarget. 556 * </p> 557 * @param {cc.Class} target 558 * @param {function} callback_fn 559 * @example 560 * //unschedule a callback of target 561 * cc.director.getScheduler().unscheduleCallbackForTarget(function, this); 562 */ 563 unscheduleCallbackForTarget:function (target, callback_fn) { 564 // explicity handle nil arguments when removing an object 565 if ((target == null) || (callback_fn == null)) { 566 return; 567 } 568 569 var self = this, element = self._hashForTimers[target.__instanceId]; 570 if (element) { 571 var timers = element.timers; 572 for(var i = 0, li = timers.length; i < li; i++){ 573 var timer = timers[i]; 574 if (callback_fn == timer._callback) { 575 if ((timer == element.currentTimer) && (!element.currentTimerSalvaged)) { 576 element.currentTimerSalvaged = true; 577 } 578 timers.splice(i, 1) 579 //update timerIndex in case we are in tick;, looping over the actions 580 if (element.timerIndex >= i) { 581 element.timerIndex--; 582 } 583 584 if (timers.length == 0) { 585 if (self._currentTarget == element) { 586 self._currentTargetSalvaged = true; 587 } else { 588 self._removeHashElement(element); 589 } 590 } 591 return; 592 } 593 } 594 } 595 }, 596 597 /** 598 * Unschedules the update callback function for a given target 599 * @param {cc.Class} target 600 * @example 601 * //unschedules the "update" method. 602 * cc.director.getScheduler().unscheduleUpdateForTarget(this); 603 */ 604 unscheduleUpdateForTarget:function (target) { 605 if (target == null) { 606 return; 607 } 608 609 var self = this, element = self._hashForUpdates[target.__instanceId]; 610 if (element != null) { 611 if (self._updateHashLocked) { 612 element.entry.markedForDeletion = true; 613 } else { 614 self._removeUpdateFromHash(element.entry); 615 } 616 } 617 }, 618 619 /** 620 * Unschedules all function callbacks for a given target. This also includes the "update" callback function. 621 * @param {cc.Class} target 622 */ 623 unscheduleAllCallbacksForTarget:function (target) { 624 //explicit NULL handling 625 if (target == null) { 626 return; 627 } 628 629 var self = this, element = self._hashForTimers[target.__instanceId]; 630 if (element) { 631 var timers = element.timers; 632 if ((!element.currentTimerSalvaged) && (timers.indexOf(element.currentTimer) >= 0)) { 633 element.currentTimerSalvaged = true; 634 } 635 timers.length = 0; 636 637 if (self._currentTarget == element) { 638 self._currentTargetSalvaged = true; 639 } else { 640 self._removeHashElement(element); 641 } 642 } 643 // update callback 644 self.unscheduleUpdateForTarget(target); 645 }, 646 647 /** 648 * <p> 649 * Unschedules all function callbacks from all targets. <br/> 650 * You should NEVER call this method, unless you know what you are doing. 651 * </p> 652 */ 653 unscheduleAllCallbacks:function () { 654 this.unscheduleAllCallbacksWithMinPriority(cc.Scheduler.PRIORITY_SYSTEM); 655 }, 656 657 /** 658 * <p> 659 * Unschedules all function callbacks from all targets with a minimum priority.<br/> 660 * You should only call this with kCCPriorityNonSystemMin or higher. 661 * </p> 662 * @param {Number} minPriority 663 */ 664 unscheduleAllCallbacksWithMinPriority:function (minPriority) { 665 // Custom Selectors 666 var self = this, locArrayForTimers = self._arrayForTimers, locUpdates = self._updates; 667 for(var i = 0, li = locArrayForTimers.length; i < li; i++){ 668 // element may be removed in unscheduleAllCallbacksForTarget 669 self.unscheduleAllCallbacksForTarget(locArrayForTimers[i].target); 670 } 671 for(var i = 2; i >= 0; i--){ 672 if((i == 1 && minPriority > 0) || (i == 0 && minPriority >= 0)) continue; 673 var updates = locUpdates[i]; 674 for(var j = 0, lj = updates.length; j < lj; j++){ 675 self.unscheduleUpdateForTarget(updates[j].target); 676 } 677 } 678 }, 679 680 /** 681 * <p> 682 * Pause all selectors from all targets.<br/> 683 * You should NEVER call this method, unless you know what you are doing. 684 * </p> 685 */ 686 pauseAllTargets:function () { 687 return this.pauseAllTargetsWithMinPriority(cc.Scheduler.PRIORITY_SYSTEM); 688 }, 689 690 /** 691 * Pause all selectors from all targets with a minimum priority. <br/> 692 * You should only call this with kCCPriorityNonSystemMin or higher. 693 * @param minPriority 694 */ 695 pauseAllTargetsWithMinPriority:function (minPriority) { 696 var idsWithSelectors = []; 697 698 var self = this, element, locArrayForTimers = self._arrayForTimers, locUpdates = self._updates; 699 // Custom Selectors 700 for(var i = 0, li = locArrayForTimers.length; i < li; i++){ 701 element = locArrayForTimers[i]; 702 if (element) { 703 element.paused = true; 704 idsWithSelectors.push(element.target); 705 } 706 } 707 for(var i = 0, li = locUpdates.length; i < li; i++){ 708 var updates = locUpdates[i]; 709 for(var j = 0, lj = updates.length; j < lj; j++){ 710 element = updates[j]; 711 if (element) { 712 element.paused = true; 713 idsWithSelectors.push(element.target); 714 } 715 } 716 } 717 return idsWithSelectors; 718 }, 719 720 /** 721 * Resume selectors on a set of targets.<br/> 722 * This can be useful for undoing a call to pauseAllCallbacks. 723 * @param targetsToResume 724 */ 725 resumeTargets:function (targetsToResume) { 726 if (!targetsToResume) 727 return; 728 729 for (var i = 0; i < targetsToResume.length; i++) { 730 this.resumeTarget(targetsToResume[i]); 731 } 732 }, 733 734 /** 735 * <p> 736 * Pauses the target.<br/> 737 * All scheduled selectors/update for a given target won't be 'ticked' until the target is resumed.<br/> 738 * If the target is not present, nothing happens. 739 * </p> 740 * @param {cc.Class} target 741 */ 742 pauseTarget:function (target) { 743 if(!target) 744 throw "cc.Scheduler.pauseTarget():target should be non-null"; 745 746 //customer selectors 747 var self = this, element = self._hashForTimers[target.__instanceId]; 748 if (element) { 749 element.paused = true; 750 } 751 752 //update callback 753 var elementUpdate = self._hashForUpdates[target.__instanceId]; 754 if (elementUpdate) { 755 elementUpdate.entry.paused = true; 756 } 757 }, 758 759 /** 760 * Resumes the target.<br/> 761 * The 'target' will be unpaused, so all schedule selectors/update will be 'ticked' again.<br/> 762 * If the target is not present, nothing happens. 763 * @param {cc.Class} target 764 */ 765 resumeTarget:function (target) { 766 if(!target) 767 throw "cc.Scheduler.resumeTarget():target should be non-null"; 768 769 // custom selectors 770 var self = this, element = self._hashForTimers[target.__instanceId]; 771 772 if (element) { 773 element.paused = false; 774 } 775 776 //update callback 777 var elementUpdate = self._hashForUpdates[target.__instanceId]; 778 779 if (elementUpdate) { 780 elementUpdate.entry.paused = false; 781 } 782 }, 783 784 /** 785 * Returns whether or not the target is paused 786 * @param {cc.Class} target 787 * @return {Boolean} 788 */ 789 isTargetPaused:function (target) { 790 if(!target) 791 throw "cc.Scheduler.isTargetPaused():target should be non-null"; 792 793 // Custom selectors 794 var element = this._hashForTimers[target.__instanceId]; 795 if (element) { 796 return element.paused; 797 } 798 return false; 799 } 800 }); 801 /** 802 * Priority level reserved for system services. 803 * @constant 804 * @type Number 805 */ 806 cc.Scheduler.PRIORITY_SYSTEM = (-2147483647 - 1); 807