Implement slot traits.
This commit is contained in:
parent
200c10b4a2
commit
af70024f62
|
@ -8,7 +8,7 @@ use crate::avm2::property::Attribute;
|
||||||
use crate::avm2::return_value::ReturnValue;
|
use crate::avm2::return_value::ReturnValue;
|
||||||
use crate::avm2::scope::Scope;
|
use crate::avm2::scope::Scope;
|
||||||
use crate::avm2::script_object::ScriptObject;
|
use crate::avm2::script_object::ScriptObject;
|
||||||
use crate::avm2::value::Value;
|
use crate::avm2::value::{abc_default_value, Value};
|
||||||
use crate::avm2::{Avm2, Error};
|
use crate::avm2::{Avm2, Error};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
|
@ -173,6 +173,14 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
||||||
);
|
);
|
||||||
|
|
||||||
match &trait_entry.kind {
|
match &trait_entry.kind {
|
||||||
|
AbcTraitKind::Slot { slot_id, value, .. } => {
|
||||||
|
let value = if let Some(value) = value {
|
||||||
|
abc_default_value(&abc, value)?
|
||||||
|
} else {
|
||||||
|
Value::Undefined
|
||||||
|
};
|
||||||
|
self.install_slot(context.gc_context, trait_name, *slot_id, value);
|
||||||
|
}
|
||||||
AbcTraitKind::Method { method, .. } => {
|
AbcTraitKind::Method { method, .. } => {
|
||||||
let method = Avm2MethodEntry::from_method_index(abc, method.clone()).unwrap();
|
let method = Avm2MethodEntry::from_method_index(abc, method.clone()).unwrap();
|
||||||
let function =
|
let function =
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::avm2::object::Object;
|
||||||
use crate::avm2::Error;
|
use crate::avm2::Error;
|
||||||
use gc_arena::Collect;
|
use gc_arena::Collect;
|
||||||
use std::f64::NAN;
|
use std::f64::NAN;
|
||||||
use swf::avm2::types::{AbcFile, Index};
|
use swf::avm2::types::{AbcFile, DefaultValue as AbcDefaultValue, Index};
|
||||||
|
|
||||||
/// An AVM2 value.
|
/// An AVM2 value.
|
||||||
///
|
///
|
||||||
|
@ -210,6 +210,32 @@ pub fn abc_string_option(file: &AbcFile, index: Index<String>) -> Result<Option<
|
||||||
.ok_or_else(|| format!("Unknown string constant {}", index.0).into())
|
.ok_or_else(|| format!("Unknown string constant {}", index.0).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieve a default value as an AVM2 `Value`.
|
||||||
|
pub fn abc_default_value<'gc>(
|
||||||
|
file: &AbcFile,
|
||||||
|
default: &AbcDefaultValue,
|
||||||
|
) -> Result<Value<'gc>, Error> {
|
||||||
|
match default {
|
||||||
|
AbcDefaultValue::Int(i) => abc_int(file, *i).map(|v| v.into()),
|
||||||
|
AbcDefaultValue::Uint(u) => abc_uint(file, *u).map(|v| v.into()),
|
||||||
|
AbcDefaultValue::Double(d) => abc_double(file, *d).map(|v| v.into()),
|
||||||
|
AbcDefaultValue::String(s) => abc_string(file, s.clone()).map(|v| v.into()),
|
||||||
|
AbcDefaultValue::True => Ok(true.into()),
|
||||||
|
AbcDefaultValue::False => Ok(false.into()),
|
||||||
|
AbcDefaultValue::Null => Ok(Value::Null),
|
||||||
|
AbcDefaultValue::Undefined => Ok(Value::Undefined),
|
||||||
|
AbcDefaultValue::Namespace(ns)
|
||||||
|
| AbcDefaultValue::Package(ns)
|
||||||
|
| AbcDefaultValue::PackageInternal(ns)
|
||||||
|
| AbcDefaultValue::Protected(ns)
|
||||||
|
| AbcDefaultValue::Explicit(ns)
|
||||||
|
| AbcDefaultValue::StaticProtected(ns)
|
||||||
|
| AbcDefaultValue::Private(ns) => {
|
||||||
|
Namespace::from_abc_namespace(file, ns.clone()).map(|v| v.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'gc> Value<'gc> {
|
impl<'gc> Value<'gc> {
|
||||||
pub fn as_object(&self) -> Result<Object<'gc>, Error> {
|
pub fn as_object(&self) -> Result<Object<'gc>, Error> {
|
||||||
if let Value::Object(object) = self {
|
if let Value::Object(object) = self {
|
||||||
|
|
Loading…
Reference in New Issue