avm2: Add flash.utils.[set|clear][Timeout|Interval](...)
This commit is contained in:
parent
5c29da6707
commit
e86efd5c63
|
@ -0,0 +1,5 @@
|
|||
// This is a stub - the actual class is defined in `function.rs`
|
||||
package {
|
||||
public final class Function {
|
||||
}
|
||||
}
|
|
@ -3,4 +3,8 @@ package flash.utils {
|
|||
public native function getQualifiedClassName(value:*):String;
|
||||
public native function getQualifiedSuperclassName(value:*):String;
|
||||
public native function getTimer():int;
|
||||
public native function setInterval(closure:Function, delay:Number, ... arguments):uint;
|
||||
public native function clearInterval(id:uint):void;
|
||||
public native function setTimeout(closure:Function, delay:Number, ... arguments):uint;
|
||||
public native function clearTimeout(id:uint):void;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,92 @@ pub fn get_timer<'gc>(
|
|||
.into())
|
||||
}
|
||||
|
||||
/// Implements `flash.utils.setInterval`
|
||||
pub fn set_interval<'gc>(
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
if args.len() < 2 {
|
||||
return Err(Error::from("setInterval: not enough arguments"));
|
||||
}
|
||||
let (args, params) = args.split_at(2);
|
||||
let callback = crate::timer::TimerCallback::Avm2Callback {
|
||||
closure: args
|
||||
.get(0)
|
||||
.expect("setInterval: not enough arguments")
|
||||
.as_object()
|
||||
.ok_or("setInterval: argument 0 is not an object")?,
|
||||
params: params.to_vec(),
|
||||
};
|
||||
let interval = args
|
||||
.get(1)
|
||||
.expect("setInterval: not enough arguments")
|
||||
.coerce_to_number(activation)?;
|
||||
Ok(Value::Integer(activation.context.timers.add_timer(
|
||||
callback,
|
||||
interval as i32,
|
||||
false,
|
||||
)))
|
||||
}
|
||||
|
||||
/// Implements `flash.utils.clearInterval`
|
||||
pub fn clear_interval<'gc>(
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
let id = args
|
||||
.get(0)
|
||||
.ok_or("clearInterval: not enough arguments")?
|
||||
.coerce_to_number(activation)?;
|
||||
activation.context.timers.remove(id as i32);
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// Implements `flash.utils.setTimeout`
|
||||
pub fn set_timeout<'gc>(
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
if args.len() < 2 {
|
||||
return Err(Error::from("setTimeout: not enough arguments"));
|
||||
}
|
||||
let (args, params) = args.split_at(2);
|
||||
let callback = crate::timer::TimerCallback::Avm2Callback {
|
||||
closure: args
|
||||
.get(0)
|
||||
.expect("setTimeout: not enough arguments")
|
||||
.as_object()
|
||||
.ok_or("setTimeout: argument 0 is not an object")?,
|
||||
params: params.to_vec(),
|
||||
};
|
||||
let interval = args
|
||||
.get(1)
|
||||
.expect("setTimeout: not enough arguments")
|
||||
.coerce_to_number(activation)?;
|
||||
Ok(Value::Integer(activation.context.timers.add_timer(
|
||||
callback,
|
||||
interval as i32,
|
||||
true,
|
||||
)))
|
||||
}
|
||||
|
||||
/// Implements `flash.utils.clearTimeout`
|
||||
pub fn clear_timeout<'gc>(
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
_this: Option<Object<'gc>>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
let id = args
|
||||
.get(0)
|
||||
.ok_or("clearTimeout: not enough arguments")?
|
||||
.coerce_to_number(activation)?;
|
||||
activation.context.timers.remove(id as i32);
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// Implements `flash.utils.getQualifiedClassName`
|
||||
pub fn get_qualified_class_name<'gc>(
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
|
|
|
@ -66,7 +66,10 @@ pub fn start<'gc>(
|
|||
)?
|
||||
.coerce_to_object(activation)?;
|
||||
let id = activation.context.timers.add_timer(
|
||||
TimerCallback::Avm2Callback(on_update),
|
||||
TimerCallback::Avm2Callback {
|
||||
closure: on_update,
|
||||
params: vec![],
|
||||
},
|
||||
delay as _,
|
||||
false,
|
||||
);
|
||||
|
|
|
@ -15,6 +15,7 @@ include "flash/display/LoaderInfo.as"
|
|||
include "flash/events/EventDispatcher.as"
|
||||
include "flash/system/ApplicationDomain.as"
|
||||
include "flash/utils/ByteArray.as"
|
||||
include "Function.as"
|
||||
include "Number.as"
|
||||
include "String.as"
|
||||
include "int.as"
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::avm1::{
|
|||
Activation, ActivationIdentifier, Object as Avm1Object, TObject as _, Value as Avm1Value,
|
||||
};
|
||||
use crate::avm2::object::TObject;
|
||||
use crate::avm2::{Activation as Avm2Activation, Object as Avm2Object};
|
||||
use crate::avm2::{Activation as Avm2Activation, Object as Avm2Object, Value as Avm2Value};
|
||||
use crate::context::UpdateContext;
|
||||
use crate::string::AvmString;
|
||||
use gc_arena::Collect;
|
||||
|
@ -108,10 +108,11 @@ impl<'gc> Timers<'gc> {
|
|||
);
|
||||
false
|
||||
}
|
||||
TimerCallback::Avm2Callback(obj) => {
|
||||
TimerCallback::Avm2Callback { closure, params } => {
|
||||
let mut avm2_activation =
|
||||
Avm2Activation::from_nothing(activation.context.reborrow());
|
||||
obj.call(None, &[], &mut avm2_activation)
|
||||
closure
|
||||
.call(None, ¶ms, &mut avm2_activation)
|
||||
.unwrap()
|
||||
.coerce_to_boolean()
|
||||
}
|
||||
|
@ -296,5 +297,8 @@ pub enum TimerCallback<'gc> {
|
|||
params: Vec<Avm1Value<'gc>>,
|
||||
},
|
||||
|
||||
Avm2Callback(Avm2Object<'gc>),
|
||||
Avm2Callback {
|
||||
closure: Avm2Object<'gc>,
|
||||
params: Vec<Avm2Value<'gc>>,
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue