Skip to content

Commit 9e26245

Browse files
committed
Fixed another annoyingly specific timer pausing bug. Added several more unit tests.
Former-commit-id: 35c4a33
1 parent 3a4f5ae commit 9e26245

File tree

3 files changed

+218
-48
lines changed

3 files changed

+218
-48
lines changed

UnitTests/CCSchedulerTests.m

Lines changed: 153 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
#import "cocos2d.h"
1111

1212

13+
// XCTAssertEqual() doesn't like comparing to the preprocessor token for some reason.
14+
static CCTime inf = INFINITY;
15+
16+
1317
@interface SequenceTester : NSObject<CCSchedulerTarget>
1418
@property(nonatomic, strong) NSMutableArray *sequence;
1519
@property(nonatomic, assign) NSInteger priority;
@@ -365,9 +369,6 @@ - (void)testLotsOfRepeatingTimers
365369

366370
- (void)testPauseTimer
367371
{
368-
// XCTAssertEqual() doesn't like comparing to the preprocessor token for some reason.
369-
CCTime inf = INFINITY;
370-
371372
CCScheduler *scheduler = [[CCScheduler alloc] init];
372373
scheduler.maxTimeStep = INFINITY;
373374
scheduler.fixedUpdateInterval = INFINITY;
@@ -380,13 +381,15 @@ - (void)testPauseTimer
380381
invokedTime = timer.invokeTime;
381382

382383
// deltaTime should not include paused time.
384+
XCTAssertEqual(timer.invokeTime, timer.scheduler.currentTime, @"");
383385
XCTAssertEqual(timer.deltaTime, 5.0, @"");
384386
} forTarget:nil withDelay:5.0];
385387
XCTAssertEqual(timer.invokeTime, 7.0, @"");
386388

387389
[scheduler update:2.0];
388390
XCTAssertEqual(timer.invokeTime, 7.0, @"");
389391

392+
timer.paused = YES;
390393
timer.paused = YES;
391394
XCTAssertEqual(timer.invokeTime, inf, @"");
392395
// After resuming the timer should have 3 seconds remaining.
@@ -401,19 +404,19 @@ - (void)testPauseTimer
401404
timer.paused = YES;
402405
XCTAssertEqual(timer.invokeTime, inf, @"");
403406

407+
timer.paused = NO;
404408
timer.paused = NO;
405409
XCTAssertEqual(timer.invokeTime, 17.0, @"");
406410

407411
[scheduler update:10.0];
408-
XCTAssertEqual(timer.invokeTime, 17.0, @"");
409412
XCTAssertEqual(invokedTime, 17.0, @"");
413+
414+
// The timer should have an infinite invoke time after it has expired.
415+
XCTAssertEqual(timer.invokeTime, inf, @"");
410416
}
411417

412418
- (void)testPauseTimerTarget
413419
{
414-
// XCTAssertEqual() doesn't like comparing to the preprocessor token for some reason.
415-
CCTime inf = INFINITY;
416-
417420
CCScheduler *scheduler = [[CCScheduler alloc] init];
418421
scheduler.maxTimeStep = INFINITY;
419422
scheduler.fixedUpdateInterval = INFINITY;
@@ -451,8 +454,10 @@ - (void)testPauseTimerTarget
451454
XCTAssertEqual(timer.invokeTime, 17.0, @"");
452455

453456
[scheduler update:10.0];
454-
XCTAssertEqual(timer.invokeTime, 17.0, @"");
455457
XCTAssertEqual(invokedTime, 17.0, @"");
458+
459+
// The timer should have an infinite invoke time after it has expired.
460+
XCTAssertEqual(timer.invokeTime, inf, @"");
456461
}
457462

458463
-(void)testTimerIncrement
@@ -511,28 +516,160 @@ -(void)testTimerPauseAtInvoke
511516
scheduler.maxTimeStep = INFINITY;
512517
scheduler.fixedUpdateInterval = INFINITY;
513518

514-
__block bool timer1Called = false;
515-
__block bool timer2Called = false;
519+
__block int timer1CallCount = 0;
520+
__block int timer2CallCount = 0;
516521

517522
// This target will be paused at exactly it's invocation time.
518-
CCTimer *timer = [scheduler scheduleBlock:^(CCTimer *timer){
519-
timer1Called = true;
523+
CCTimer *timer1 = [scheduler scheduleBlock:^(CCTimer *timer){
524+
timer1CallCount++;
520525
} forTarget:nil withDelay:1.0];
521526

527+
timer1.repeatCount = CCTimerRepeatForever;
528+
522529
// This is a high priority target and will be called first to pause the first timer.
523530
SequenceTester *target = [[SequenceTester alloc] init];
524531
target.priority = -1;
525532

526533
[scheduler setPaused:NO target:target];
527534

528535
[scheduler scheduleBlock:^(CCTimer *unused){
529-
timer.paused = true;
530-
timer2Called = true;
536+
timer1.paused = true;
537+
timer2CallCount++;
531538
} forTarget:target withDelay:1.0];
532539

533540
[scheduler update:10.0];
534-
XCTAssertTrue(timer1Called, @"");
535-
XCTAssertTrue(timer2Called, @"");
541+
XCTAssertEqual(timer1CallCount, 0, @"");
542+
XCTAssertEqual(timer2CallCount, 1, @"");
543+
}
544+
545+
-(void)testTimerPause1
546+
{
547+
CCScheduler *scheduler = [[CCScheduler alloc] init];
548+
scheduler.maxTimeStep = INFINITY;
549+
scheduler.fixedUpdateInterval = INFINITY;
550+
551+
CCTimer *timer = [scheduler scheduleBlock:^(CCTimer *t){
552+
XCTAssertEqual(t.deltaTime, 3.0, @"");
553+
XCTAssertEqual(t.invokeTime, 6.0, @"");
554+
XCTAssertEqual(t.scheduler.currentTime, 6.0, @"");
555+
} forTarget:nil withDelay:3.0];
556+
XCTAssertEqual(timer.invokeTime, 3.0, @"");
557+
558+
// Pause at 1.0
559+
[scheduler scheduleBlock:^(CCTimer *t){
560+
timer.paused = YES;
561+
XCTAssertEqual(timer.invokeTime, inf, @"");
562+
} forTarget:nil withDelay:1.0];
563+
564+
// Unpause at 4.0
565+
[scheduler scheduleBlock:^(CCTimer *t){
566+
timer.paused = NO;
567+
XCTAssertEqual(timer.invokeTime, 6.0, @"");
568+
} forTarget:nil withDelay:4.0];
569+
570+
[scheduler update:20.0];
571+
}
572+
573+
-(void)testTimerPause2
574+
{
575+
CCScheduler *scheduler = [[CCScheduler alloc] init];
576+
scheduler.maxTimeStep = INFINITY;
577+
scheduler.fixedUpdateInterval = INFINITY;
578+
579+
CCTimer *timer = [scheduler scheduleBlock:^(CCTimer *t){
580+
XCTAssertEqual(t.deltaTime, 3.0, @"");
581+
XCTAssertEqual(t.invokeTime, 4.0, @"");
582+
XCTAssertEqual(t.scheduler.currentTime, 4.0, @"");
583+
} forTarget:nil withDelay:3.0];
584+
XCTAssertEqual(timer.invokeTime, 3.0, @"");
585+
586+
// Pause at 1.0
587+
[scheduler scheduleBlock:^(CCTimer *t){
588+
timer.paused = YES;
589+
XCTAssertEqual(timer.invokeTime, inf, @"");
590+
} forTarget:nil withDelay:1.0];
591+
592+
// Unpause at 2.0
593+
[scheduler scheduleBlock:^(CCTimer *t){
594+
timer.paused = NO;
595+
XCTAssertEqual(timer.invokeTime, 4.0, @"");
596+
} forTarget:nil withDelay:2.0];
597+
598+
[scheduler update:20.0];
599+
}
600+
601+
-(void)testTimerPause3
602+
{
603+
CCScheduler *scheduler = [[CCScheduler alloc] init];
604+
scheduler.maxTimeStep = INFINITY;
605+
scheduler.fixedUpdateInterval = INFINITY;
606+
607+
CCTimer *timer = [scheduler scheduleBlock:^(CCTimer *t){
608+
XCTAssertEqual(t.deltaTime, 2.0, @"");
609+
XCTAssertEqual(t.invokeTime, 4.0, @"");
610+
XCTAssertEqual(t.scheduler.currentTime, 4.0, @"");
611+
} forTarget:nil withDelay:2.0];
612+
XCTAssertEqual(timer.invokeTime, 2.0, @"");
613+
614+
// Pause at 1.0
615+
[scheduler scheduleBlock:^(CCTimer *t){
616+
timer.paused = YES;
617+
XCTAssertEqual(timer.invokeTime, inf, @"");
618+
} forTarget:nil withDelay:1.0];
619+
620+
// Unpause at 3.0
621+
[scheduler scheduleBlock:^(CCTimer *t){
622+
timer.paused = NO;
623+
XCTAssertEqual(timer.invokeTime, 4.0, @"");
624+
} forTarget:nil withDelay:3.0];
625+
626+
[scheduler update:20.0];
627+
}
628+
629+
-(void)testTimerPause4
630+
{
631+
CCScheduler *scheduler = [[CCScheduler alloc] init];
632+
scheduler.maxTimeStep = INFINITY;
633+
scheduler.fixedUpdateInterval = INFINITY;
634+
635+
__block int invokeCount = 0;
636+
637+
CCTimer *timer = [scheduler scheduleBlock:^(CCTimer *t){
638+
XCTAssertEqual(t.deltaTime, 2.0, @"");
639+
XCTAssertEqual(fmod(t.invokeTime, 4.0), 0.0, @"");
640+
XCTAssertEqual(t.invokeTime, t.scheduler.currentTime, @"");
641+
642+
invokeCount++;
643+
} forTarget:nil withDelay:2.0];
644+
645+
timer.repeatCount = 2;
646+
647+
// Pause at 0.5 + 2i
648+
[scheduler scheduleBlock:^(CCTimer *pausingTimer){
649+
timer.paused = YES;
650+
XCTAssertEqual(timer.invokeTime, inf, @"");
651+
652+
[pausingTimer repeatOnceWithInterval:2.0];
653+
} forTarget:nil withDelay:0.5];
654+
655+
// Unpause at 1.5 + 2i
656+
[scheduler scheduleBlock:^(CCTimer *unpausingTimer){
657+
timer.paused = NO;
658+
659+
if(timer.invokeTime > 12.0){
660+
// After 12.0, the timer will stop repeating and become invalid.
661+
XCTAssertEqual(timer.invokeTime, inf, @"");
662+
} else if(fmod(unpausingTimer.invokeTime, 4.0) == 1.5){
663+
XCTAssertEqual(fmod(timer.invokeTime, 4.0), 3.0, @"");
664+
} else {
665+
XCTAssertEqual(fmod(timer.invokeTime, 4.0), 0.0, @"");
666+
}
667+
668+
[unpausingTimer repeatOnceWithInterval:2.0];
669+
} forTarget:nil withDelay:1.5];
670+
671+
[scheduler update:20.0];
672+
XCTAssertEqual(invokeCount, 3, @"");
536673
}
537674

538675
-(void)testRemoveScheduledUpdate

cocos2d-ui-tests/tests/CCSchedulerTest.m

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,28 @@ -(void)foo:(CCTime)delta
2828
NSLog(@"Foooo!");
2929
}
3030

31+
-(void)fooSingle:(CCTime)delta
32+
{
33+
NSLog(@"FooSingle!");
34+
}
35+
3136
-(void)onEnter
3237
{
3338
// Scheduling a method before calling [super onEnter] used to trigger a bug.
34-
[self schedule:@selector(foo:) interval:1.0];
39+
// [self schedule:@selector(foo:) interval:1.0];
40+
41+
[self scheduleBlock:^(CCTimer *timer){
42+
NSLog(@"Before");
43+
[timer repeatOnceWithInterval:2.0];
44+
} delay:0.0];
3545

3646
[super onEnter];
47+
48+
[self scheduleBlock:^(CCTimer *timer){
49+
NSLog(@"After");
50+
[timer repeatOnceWithInterval:2.0];
51+
} delay:0.0];
52+
3753
}
3854

3955
-(void)update:(CCTime)delta

0 commit comments

Comments
 (0)