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._delay = value;
|
||||
if (this.running) {
|
||||
this.stop();
|
||||
this.start();
|
||||
this.updateDelay();
|
||||
}
|
||||
}
|
||||
|
||||
private native function updateDelay():void;
|
||||
|
||||
public function get repeatCount(): int {
|
||||
return this._repeatCount;
|
||||
}
|
||||
|
|
|
@ -81,3 +81,32 @@ pub fn start<'gc>(
|
|||
}
|
||||
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
|
||||
}
|
||||
|
||||
/// 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>> {
|
||||
self.timers.peek()
|
||||
}
|
||||
|
@ -286,7 +309,7 @@ unsafe impl<'gc> Collect for Timers<'gc> {
|
|||
}
|
||||
/// A timer created via `setInterval`/`setTimeout`.
|
||||
/// Runs a callback when it ticks.
|
||||
#[derive(Collect)]
|
||||
#[derive(Clone, Collect)]
|
||||
#[collect(no_drop)]
|
||||
pub struct Timer<'gc> {
|
||||
/// The ID of the timer.
|
||||
|
|
Loading…
Reference in New Issue