core,avm2: Make Timer.setDelay not change the timer ID. Fix #15005.
This commit is contained in:
parent
e288375543
commit
ee0c1f42ff
|
@ -32,11 +32,12 @@ package flash.utils {
|
||||||
this.checkDelay(delay);
|
this.checkDelay(delay);
|
||||||
this._delay = value;
|
this._delay = value;
|
||||||
if (this.running) {
|
if (this.running) {
|
||||||
this.stop();
|
this.updateDelay();
|
||||||
this.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private native function updateDelay():void;
|
||||||
|
|
||||||
public function get repeatCount(): int {
|
public function get repeatCount(): int {
|
||||||
return this._repeatCount;
|
return this._repeatCount;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,3 +81,32 @@ pub fn start<'gc>(
|
||||||
}
|
}
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implements `Timer.updateDelay`
|
||||||
|
pub fn update_delay<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let id = this
|
||||||
|
.get_property(
|
||||||
|
&Multiname::new(activation.avm2().flash_utils_internal, "_timerId"),
|
||||||
|
activation,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.coerce_to_i32(activation)?;
|
||||||
|
|
||||||
|
let delay = this
|
||||||
|
.get_property(
|
||||||
|
&Multiname::new(activation.avm2().flash_utils_internal, "_delay"),
|
||||||
|
activation,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.coerce_to_i32(activation)?;
|
||||||
|
|
||||||
|
if id != -1 {
|
||||||
|
activation.context.timers.set_delay(id, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
|
@ -258,6 +258,29 @@ impl<'gc> Timers<'gc> {
|
||||||
len < old_len
|
len < old_len
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Changes the delay of a timer.
|
||||||
|
pub fn set_delay(&mut self, id: i32, interval: i32) {
|
||||||
|
// SANITY: Set a minimum interval so we don't spam too much.
|
||||||
|
let interval = interval.max(Self::MIN_INTERVAL) as u64 * (Self::TIMER_SCALE as u64);
|
||||||
|
|
||||||
|
// Due to the limitations of `BinaryHeap`, we have to do this in a slightly roundabout way.
|
||||||
|
let mut timer = None;
|
||||||
|
for t in self.timers.iter() {
|
||||||
|
if t.id == id {
|
||||||
|
timer = Some(t.clone());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(mut timer) = timer {
|
||||||
|
self.remove(id);
|
||||||
|
timer.interval = interval;
|
||||||
|
self.timers.push(timer);
|
||||||
|
} else {
|
||||||
|
panic!("Changing delay of non-existent timer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn peek(&self) -> Option<&Timer<'gc>> {
|
fn peek(&self) -> Option<&Timer<'gc>> {
|
||||||
self.timers.peek()
|
self.timers.peek()
|
||||||
}
|
}
|
||||||
|
@ -286,7 +309,7 @@ unsafe impl<'gc> Collect for Timers<'gc> {
|
||||||
}
|
}
|
||||||
/// A timer created via `setInterval`/`setTimeout`.
|
/// A timer created via `setInterval`/`setTimeout`.
|
||||||
/// Runs a callback when it ticks.
|
/// Runs a callback when it ticks.
|
||||||
#[derive(Collect)]
|
#[derive(Clone, Collect)]
|
||||||
#[collect(no_drop)]
|
#[collect(no_drop)]
|
||||||
pub struct Timer<'gc> {
|
pub struct Timer<'gc> {
|
||||||
/// The ID of the timer.
|
/// The ID of the timer.
|
||||||
|
|
Loading…
Reference in New Issue