avm2: Fix handling of completed timers
It's possible to call 'start()' on a timer that has currentCount >= repeatCount. This will cause the timer to tick exactly once, and then stop agian. We were incorrectly reporting 'timer.running' in such a scenario: 'running' should be reported as 'true' up until just before the 'TimerEvent.TIMER_COMPLETE' is fired. This fixes gaining money from bloon popping / level completion in BTD5.
This commit is contained in:
parent
92776645b8
commit
b27bcf367c
|
@ -49,7 +49,7 @@ package flash.utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get running(): Boolean {
|
public function get running(): Boolean {
|
||||||
return this._timerId != -1 && (this.repeatCount == 0 || this._currentCount < this._repeatCount);
|
return this._timerId != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reset():void {
|
public function reset():void {
|
||||||
|
@ -65,6 +65,8 @@ package flash.utils {
|
||||||
this._currentCount += 1;
|
this._currentCount += 1;
|
||||||
this.dispatchEvent(new TimerEvent(TimerEvent.TIMER, false, false));
|
this.dispatchEvent(new TimerEvent(TimerEvent.TIMER, false, false));
|
||||||
if (this.repeatCount != 0 && this._currentCount >= this._repeatCount) {
|
if (this.repeatCount != 0 && this._currentCount >= this._repeatCount) {
|
||||||
|
// This will make 'running' return false in a TIMER_COMPLETE event handler
|
||||||
|
this._timerId = -1;
|
||||||
this.dispatchEvent(new TimerEvent(TimerEvent.TIMER_COMPLETE, false, false));
|
this.dispatchEvent(new TimerEvent(TimerEvent.TIMER_COMPLETE, false, false));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,9 @@ pub fn start<'gc>(
|
||||||
activation,
|
activation,
|
||||||
)?
|
)?
|
||||||
.coerce_to_object(activation)?;
|
.coerce_to_object(activation)?;
|
||||||
|
// Note - we deliberately do *not* check if currentCount is less than repeatCount.
|
||||||
|
// Calling 'start' on a timer that has currentCount >= repeatCount will tick exactly
|
||||||
|
// once, and then stop immediately. This is handeld by Timer.onUpdate
|
||||||
let id = activation.context.timers.add_timer(
|
let id = activation.context.timers.add_timer(
|
||||||
TimerCallback::Avm2Callback {
|
TimerCallback::Avm2Callback {
|
||||||
closure: on_update,
|
closure: on_update,
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package {
|
||||||
|
import flash.events.TimerEvent;
|
||||||
|
import flash.utils.Timer;
|
||||||
|
import flash.utils.setTimeout;
|
||||||
|
|
||||||
|
public class Test {
|
||||||
|
public function Test() {
|
||||||
|
var timer = new Timer(100, 2);
|
||||||
|
timer.addEventListener(TimerEvent.TIMER, function(e) {
|
||||||
|
trace("TimerEvent.TIMER: timer.running=" + timer.running + " timer.currentCount=" + timer.currentCount + " timer.repeatCount=" + timer.repeatCount);
|
||||||
|
});
|
||||||
|
timer.addEventListener(TimerEvent.TIMER_COMPLETE, function(e) {
|
||||||
|
trace("TimerEvent.TIMER_COMPLETE: timer.running=" + timer.running + " timer.currentCount=" + timer.currentCount + " timer.repeatCount=" + timer.repeatCount);
|
||||||
|
})
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
trace("After 300ms: timer.running=" + timer.running + " timer.currentCount=" + timer.currentCount + " timer.repeatCount=" + timer.repeatCount);
|
||||||
|
trace("Starting timer again");
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
trace("After 200ms: timer.running=" + timer.running + " timer.currentCount=" + timer.currentCount + " timer.repeatCount=" + timer.repeatCount);
|
||||||
|
trace("Stopping/Starting timer again");
|
||||||
|
timer.stop();
|
||||||
|
timer.start();
|
||||||
|
}, 200);
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
TimerEvent.TIMER: timer.running=true timer.currentCount=1 timer.repeatCount=2
|
||||||
|
TimerEvent.TIMER: timer.running=true timer.currentCount=2 timer.repeatCount=2
|
||||||
|
TimerEvent.TIMER_COMPLETE: timer.running=false timer.currentCount=2 timer.repeatCount=2
|
||||||
|
After 300ms: timer.running=false timer.currentCount=2 timer.repeatCount=2
|
||||||
|
Starting timer again
|
||||||
|
TimerEvent.TIMER: timer.running=true timer.currentCount=3 timer.repeatCount=2
|
||||||
|
TimerEvent.TIMER_COMPLETE: timer.running=false timer.currentCount=3 timer.repeatCount=2
|
||||||
|
After 200ms: timer.running=false timer.currentCount=3 timer.repeatCount=2
|
||||||
|
Stopping/Starting timer again
|
||||||
|
TimerEvent.TIMER: timer.running=true timer.currentCount=4 timer.repeatCount=2
|
||||||
|
TimerEvent.TIMER_COMPLETE: timer.running=false timer.currentCount=4 timer.repeatCount=2
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
num_frames = 16
|
Loading…
Reference in New Issue