core: Add ability to call out to ExternalInterfaceProviders

This commit is contained in:
Nathan Adams 2020-08-28 12:43:21 +02:00 committed by Mike Welsh
parent 502ea98ed4
commit e1b3ac79d6
6 changed files with 55 additions and 2 deletions

View File

@ -41,6 +41,21 @@ pub fn add_callback<'gc>(
} }
} }
pub fn call<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
_this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if args.is_empty() {
return Ok(Value::Null);
}
let name = args.get(0).unwrap().coerce_to_string(activation)?;
activation.context.external_interface.call_external(&name);
Ok(Value::Null)
}
pub fn create_external_interface_object<'gc>( pub fn create_external_interface_object<'gc>(
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
proto: Object<'gc>, proto: Object<'gc>,
@ -69,6 +84,14 @@ pub fn create_external_interface_object<'gc>(
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function(
"call",
call,
gc_context,
Attribute::DontDelete | Attribute::DontEnum,
Some(fn_proto),
);
object.into() object.into()
} }

View File

@ -36,7 +36,9 @@ impl<'gc> Callback<'gc> {
} }
} }
pub trait ExternalInterfaceProvider {} pub trait ExternalInterfaceProvider {
fn call(&self, name: &str) -> Option<()>;
}
#[derive(Default)] #[derive(Default)]
pub struct ExternalInterface<'gc> { pub struct ExternalInterface<'gc> {
@ -68,6 +70,14 @@ impl<'gc> ExternalInterface<'gc> {
self.callbacks.get(name).cloned() self.callbacks.get(name).cloned()
} }
pub fn call_external(&self, name: &str) {
for provider in &self.providers {
if provider.call(name).is_some() {
return;
}
}
}
pub fn available(&self) -> bool { pub fn available(&self) -> bool {
!self.providers.is_empty() !self.providers.is_empty()
} }

View File

@ -546,4 +546,14 @@ impl ExternalInterfaceTestProvider {
} }
} }
impl ExternalInterfaceProvider for ExternalInterfaceTestProvider {} impl ExternalInterfaceProvider for ExternalInterfaceTestProvider {
fn call(&self, name: &str) -> Option<()> {
match name {
"ping" => {
log::info!(target: "avm_trace", "[ExternalInterface] ping");
Some(())
}
_ => None,
}
}
}

View File

@ -4,6 +4,16 @@ true
// ExternalInterface.addCallback("dump", object, dump) // ExternalInterface.addCallback("dump", object, dump)
true true
// ExternalInterface.call()
null
// ExternalInterface.call("ping")
[ExternalInterface] ping
null
// ExternalInterface.call("non_existent")
null
/// dump() start /// dump() start
// this // this
[object Object] [object Object]