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 getQualifiedClassName(value:*):String;
|
||||||
public native function getQualifiedSuperclassName(value:*):String;
|
public native function getQualifiedSuperclassName(value:*):String;
|
||||||
public native function getTimer():int;
|
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())
|
.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`
|
/// Implements `flash.utils.getQualifiedClassName`
|
||||||
pub fn get_qualified_class_name<'gc>(
|
pub fn get_qualified_class_name<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
|
|
@ -66,7 +66,10 @@ pub fn start<'gc>(
|
||||||
)?
|
)?
|
||||||
.coerce_to_object(activation)?;
|
.coerce_to_object(activation)?;
|
||||||
let id = activation.context.timers.add_timer(
|
let id = activation.context.timers.add_timer(
|
||||||
TimerCallback::Avm2Callback(on_update),
|
TimerCallback::Avm2Callback {
|
||||||
|
closure: on_update,
|
||||||
|
params: vec![],
|
||||||
|
},
|
||||||
delay as _,
|
delay as _,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
|
@ -15,6 +15,7 @@ include "flash/display/LoaderInfo.as"
|
||||||
include "flash/events/EventDispatcher.as"
|
include "flash/events/EventDispatcher.as"
|
||||||
include "flash/system/ApplicationDomain.as"
|
include "flash/system/ApplicationDomain.as"
|
||||||
include "flash/utils/ByteArray.as"
|
include "flash/utils/ByteArray.as"
|
||||||
|
include "Function.as"
|
||||||
include "Number.as"
|
include "Number.as"
|
||||||
include "String.as"
|
include "String.as"
|
||||||
include "int.as"
|
include "int.as"
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::avm1::{
|
||||||
Activation, ActivationIdentifier, Object as Avm1Object, TObject as _, Value as Avm1Value,
|
Activation, ActivationIdentifier, Object as Avm1Object, TObject as _, Value as Avm1Value,
|
||||||
};
|
};
|
||||||
use crate::avm2::object::TObject;
|
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::context::UpdateContext;
|
||||||
use crate::string::AvmString;
|
use crate::string::AvmString;
|
||||||
use gc_arena::Collect;
|
use gc_arena::Collect;
|
||||||
|
@ -108,10 +108,11 @@ impl<'gc> Timers<'gc> {
|
||||||
);
|
);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
TimerCallback::Avm2Callback(obj) => {
|
TimerCallback::Avm2Callback { closure, params } => {
|
||||||
let mut avm2_activation =
|
let mut avm2_activation =
|
||||||
Avm2Activation::from_nothing(activation.context.reborrow());
|
Avm2Activation::from_nothing(activation.context.reborrow());
|
||||||
obj.call(None, &[], &mut avm2_activation)
|
closure
|
||||||
|
.call(None, ¶ms, &mut avm2_activation)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.coerce_to_boolean()
|
.coerce_to_boolean()
|
||||||
}
|
}
|
||||||
|
@ -296,5 +297,8 @@ pub enum TimerCallback<'gc> {
|
||||||
params: Vec<Avm1Value<'gc>>,
|
params: Vec<Avm1Value<'gc>>,
|
||||||
},
|
},
|
||||||
|
|
||||||
Avm2Callback(Avm2Object<'gc>),
|
Avm2Callback {
|
||||||
|
closure: Avm2Object<'gc>,
|
||||||
|
params: Vec<Avm2Value<'gc>>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue