/// Install a trait from anywyere.
///
/// The value of the trait at the time of installation will be returned
/// here.
Install a trait from anywyere.
The value of the trait at the time of installation will be returned
here.
Install a trait from anywyere . The value of the trait at the time of installation will be returned here .
fn install_foreign_trait(
        &mut self,
        activation: &mut Activation<'_, 'gc, '_>,
        trait_entry: Trait<'gc>,
        scope: Option<GcCell<'gc, Scope<'gc>>>,
        receiver: Object<'gc>,
    ) -> Result<Value<'gc>, Error> {
        let fn_proto = activation.avm2().prototypes().function;
        let trait_name = trait_entry.name().clone();
        avm_debug!(
            activation.avm2(),
            "Installing trait {:?} of kind {:?}",
            trait_name,
            trait_entry.kind()
        );
        match trait_entry.kind() {
            TraitKind::Slot {
                slot_id,
                default_value,
                ..
            } => {
                let value = default_value.clone().unwrap_or(Value::Undefined);
                self.install_slot(
                    activation.context.gc_context,
                    trait_name,
                    *slot_id,
                    value.clone(),
                );
                Ok(value)
            }
            TraitKind::Method {
                disp_id, method, ..
            } => {
                let function = FunctionObject::from_method(
                    activation.context.gc_context,
                    method.clone(),
                    scope,
                    fn_proto,
                    Some(receiver),
                );
                self.install_method(
                    activation.context.gc_context,
                    trait_name,
                    *disp_id,
                    function,
                );
                Ok(function.into())
            }
            TraitKind::Getter {
                disp_id, method, ..
            } => {
                let function = FunctionObject::from_method(
                    activation.context.gc_context,
                    method.clone(),
                    scope,
                    fn_proto,
                    Some(receiver),
                );
                self.install_getter(
                    activation.context.gc_context,
                    trait_name,
                    *disp_id,
                    function,
                )?;
                Ok(function.into())
            }
            TraitKind::Setter {
                disp_id, method, ..
            } => {
                let function = FunctionObject::from_method(
                    activation.context.gc_context,
                    method.clone(),
                    scope,
                    fn_proto,
                    Some(receiver),
                );
                self.install_setter(
                    activation.context.gc_context,
                    trait_name,
                    *disp_id,
                    function,
                )?;
                Ok(function.into())
            }
            TraitKind::Class { slot_id, class } => {
                let class_read = class.read();
                let super_class = if let Some(sc_name) = class_read.super_class_name() {
                    let super_name = self
                        .resolve_multiname(sc_name)?
                        .unwrap_or_else(|| QName::dynamic_name("Object"));
                    let super_class = if let Some(scope) = scope {
                        scope
                            .write(activation.context.gc_context)
                            .resolve(&super_name.clone().into(), activation)?
                    } else {
                        None
                    };
                    Some(
                        super_class
                            .ok_or_else(|| {
                                format!(
                                    "Could not resolve superclass {:?}",
                                    super_name.local_name()
                                )
                            })?
                            .coerce_to_object(activation)?,
                    )
                } else {
                    None
                };
                let (class_object, _cinit) =
                    FunctionObject::from_class(activation, *class, super_class, scope)?;
                self.install_const(
                    activation.context.gc_context,
                    class_read.name().clone(),
                    *slot_id,
                    class_object.into(),
                );
                Ok(class_object.into())
            }
            TraitKind::Function {
                slot_id, function, ..
            } => {
                let mut fobject = FunctionObject::from_method(
                    activation.context.gc_context,
                    function.clone(),
                    scope,
                    fn_proto,
                    None,
                );
                let es3_proto = ScriptObject::object(
                    activation.context.gc_context,
                    activation.avm2().prototypes().object,
                );
                fobject.install_slot(
                    activation.context.gc_context,
                    QName::new(Namespace::public(), "prototype"),
                    0,
                    es3_proto.into(),
                );
                self.install_const(
                    activation.context.gc_context,
                    trait_name,
                    *slot_id,
                    fobject.into(),
                );
                Ok(fobject.into())
            }
            TraitKind::Const {
                slot_id,
                default_value,
                ..
            } => {
                let value = default_value.clone().unwrap_or(Value::Undefined);
                self.install_const(
                    activation.context.gc_context,
                    trait_name,
                    *slot_id,
                    value.clone(),
                );
                Ok(value)
            }
        }
    }
fn install_foreign_trait ( & mut self , activation : & mut Activation < ' _ , ' gc , ' _ > , trait_entry : Trait < ' gc > , scope : Option < GcCell < ' gc , Scope < ' gc > > > , receiver : Object < ' gc > , ) -> Result < Value < ' gc > , Error > { let fn_proto = activation . avm2 ( ) . prototypes ( ) . function ; let trait_name = trait_entry . name ( ) . clone ( ) ; avm_debug ! ( activation avm2 ( ) " " trait_name trait_entry kind ( ) ) ; match trait_entry . kind ( ) { TraitKind :: Slot { slot_id , default_value , .. } => { let value = default_value . clone ( ) . unwrap_or ( Value :: Undefined ) ; self . install_slot ( activation . context . gc_context , trait_name , * slot_id , value . clone ( ) , ) ; Ok ( value ) } TraitKind :: Method { disp_id , method , .. } => { let function = FunctionObject :: from_method ( activation . context . gc_context , method . clone ( ) , scope , fn_proto , Some ( receiver ) , ) ; self . install_method ( activation . context . gc_context , trait_name , * disp_id , function , ) ; Ok ( function . into ( ) ) } TraitKind :: Getter { disp_id , method , .. } => { let function = FunctionObject :: from_method ( activation . context . gc_context , method . clone ( ) , scope , fn_proto , Some ( receiver ) , ) ; self . install_getter ( activation . context . gc_context , trait_name , * disp_id , function , ) ? ; Ok ( function . into ( ) ) } TraitKind :: Setter { disp_id , method , .. } => { let function = FunctionObject :: from_method ( activation . context . gc_context , method . clone ( ) , scope , fn_proto , Some ( receiver ) , ) ; self . install_setter ( activation . context . gc_context , trait_name , * disp_id , function , ) ? ; Ok ( function . into ( ) ) } TraitKind :: Class { slot_id , class } => { let class_read = class . read ( ) ; let super_class = if let Some ( sc_name ) = class_read . super_class_name ( ) { let super_name = self . resolve_multiname ( sc_name ) ? . unwrap_or_else ( | | QName :: dynamic_name ( " " ) ) ; let super_class = if let Some ( scope ) = scope { scope . write ( activation . context . gc_context ) . resolve ( & super_name . clone ( ) . into ( ) , activation ) ? } else { None } ; Some ( super_class . ok_or_else ( | | { format ! ( " " super_name local_name ( ) ) } ) ? . coerce_to_object ( activation ) ? , ) } else { None } ; let ( class_object , _cinit ) = FunctionObject :: from_class ( activation , * class , super_class , scope ) ? ; self . install_const ( activation . context . gc_context , class_read . name ( ) . clone ( ) , * slot_id , class_object . into ( ) , ) ; Ok ( class_object . into ( ) ) } TraitKind :: Function { slot_id , function , .. } => { let mut fobject = FunctionObject :: from_method ( activation . context . gc_context , function . clone ( ) , scope , fn_proto , None , ) ; let es3_proto = ScriptObject :: object ( activation . context . gc_context , activation . avm2 ( ) . prototypes ( ) . object , ) ; fobject . install_slot ( activation . context . gc_context , QName :: new ( Namespace :: public ( ) , " " ) , 0 , es3_proto . into ( ) , ) ; self . install_const ( activation . context . gc_context , trait_name , * slot_id , fobject . into ( ) , ) ; Ok ( fobject . into ( ) ) } TraitKind :: Const { slot_id , default_value , .. } => { let value = default_value . clone ( ) . unwrap_or ( Value :: Undefined ) ; self . install_const ( activation . context . gc_context , trait_name , * slot_id , value . clone ( ) , ) ; Ok ( value ) } } }
Install a trait from anywyere.
Install a trait from anywyere .
&mut self
activation
&mut Activation<'_, 'gc, '_>
trait_entry
Trait<'gc>
scope
Option<GcCell<'gc, Scope<'gc>>>
receiver
Object<'gc>