`DisplayObject`s all have a AVM1 `Value`. Added `toString()` default method for Objects (but not functions)
This commit is contained in:
parent
bd63a82e9e
commit
7a18ece455
|
@ -369,7 +369,7 @@ impl<'gc> Avm1<'gc> {
|
|||
|
||||
fn action_call_method(
|
||||
&mut self,
|
||||
_context: &mut ActionContext<'_, 'gc, '_>,
|
||||
context: &mut ActionContext<'_, 'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
let method_name = self.pop()?;
|
||||
let object = self.pop()?;
|
||||
|
@ -383,13 +383,13 @@ impl<'gc> Avm1<'gc> {
|
|||
Value::Undefined | Value::Null => {
|
||||
self.stack.push(
|
||||
object.call(
|
||||
_context.gc_context,
|
||||
_context
|
||||
context.gc_context,
|
||||
context
|
||||
.active_clip
|
||||
.read()
|
||||
.as_movie_clip()
|
||||
.unwrap()
|
||||
.object(),
|
||||
.object()
|
||||
.as_object()?
|
||||
.to_owned(),
|
||||
&args,
|
||||
)?,
|
||||
);
|
||||
|
@ -397,13 +397,13 @@ impl<'gc> Avm1<'gc> {
|
|||
Value::String(name) => {
|
||||
if name.is_empty() {
|
||||
self.stack.push(object.call(
|
||||
_context.gc_context,
|
||||
context.gc_context,
|
||||
object.as_object()?.to_owned(),
|
||||
&args,
|
||||
)?);
|
||||
} else {
|
||||
self.stack.push(object.as_object()?.read().get(&name).call(
|
||||
_context.gc_context,
|
||||
context.gc_context,
|
||||
object.as_object()?.to_owned(),
|
||||
&args,
|
||||
)?);
|
||||
|
@ -588,8 +588,7 @@ impl<'gc> Avm1<'gc> {
|
|||
context
|
||||
.start_clip
|
||||
.read()
|
||||
.as_movie_clip()
|
||||
.map_or(Value::Undefined, |clip| Value::Object(clip.object())),
|
||||
.object()
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -601,7 +600,7 @@ impl<'gc> Avm1<'gc> {
|
|||
Self::resolve_slash_path_variable(context.active_clip, context.root, path)
|
||||
{
|
||||
if let Some(clip) = node.read().as_movie_clip() {
|
||||
let object = clip.object();
|
||||
let object = clip.object().as_object()?;
|
||||
if object.read().has_property(var_name) {
|
||||
result = Some(object.read().get(var_name));
|
||||
}
|
||||
|
@ -1004,7 +1003,7 @@ impl<'gc> Avm1<'gc> {
|
|||
Self::resolve_slash_path_variable(context.active_clip, context.root, var_path)
|
||||
{
|
||||
if let Some(clip) = node.write(context.gc_context).as_movie_clip_mut() {
|
||||
clip.object().write(context.gc_context).set(var_name, value);
|
||||
clip.object().as_object()?.write(context.gc_context).set(var_name, value);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -20,7 +20,7 @@ fn round<'gc>(
|
|||
}
|
||||
|
||||
pub fn create<'gc>(gc_context: MutationContext<'gc, '_>) -> Value<'gc> {
|
||||
let mut math = Object::object();
|
||||
let mut math = Object::object(gc_context);
|
||||
|
||||
math.set_function("abs", abs, gc_context);
|
||||
math.set_function("round", round, gc_context);
|
||||
|
|
|
@ -42,7 +42,7 @@ macro_rules! with_movie_clip_mut {
|
|||
}
|
||||
|
||||
pub fn create_movie_object<'gc>(gc_context: MutationContext<'gc, '_>) -> Object<'gc> {
|
||||
let mut object = Object::object();
|
||||
let mut object = Object::object(gc_context);
|
||||
|
||||
with_movie_clip_mut!(
|
||||
gc_context,
|
||||
|
|
|
@ -11,6 +11,10 @@ pub const TYPE_OF_OBJECT: &str = "object";
|
|||
pub const TYPE_OF_FUNCTION: &str = "function";
|
||||
pub const TYPE_OF_MOVIE_CLIP: &str = "movieclip";
|
||||
|
||||
fn default_to_string<'gc>(_: MutationContext<'gc, '_>, _: GcCell<'gc, Object<'gc>>, _: &[Value<'gc>]) -> Value<'gc> {
|
||||
Value::String("[Object object]".to_string())
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Object<'gc> {
|
||||
display_node: Option<DisplayNode<'gc>>,
|
||||
|
@ -37,13 +41,17 @@ impl fmt::Debug for Object<'_> {
|
|||
}
|
||||
|
||||
impl<'gc> Object<'gc> {
|
||||
pub fn object() -> Self {
|
||||
Self {
|
||||
pub fn object(gc_context: MutationContext<'gc, '_>) -> Self {
|
||||
let mut result = Self {
|
||||
type_of: TYPE_OF_OBJECT,
|
||||
display_node: None,
|
||||
values: HashMap::new(),
|
||||
function: None,
|
||||
}
|
||||
};
|
||||
|
||||
result.set_function("toString", default_to_string, gc_context);
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub fn function(function: NativeFunction<'gc>) -> Self {
|
||||
|
|
|
@ -119,9 +119,9 @@ impl<'gc> Value<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn as_object(&self) -> Result<&GcCell<'gc, Object<'gc>>, Error> {
|
||||
pub fn as_object(&self) -> Result<GcCell<'gc, Object<'gc>>, Error> {
|
||||
if let Value::Object(object) = self {
|
||||
Ok(object)
|
||||
Ok(object.to_owned())
|
||||
} else {
|
||||
Err(format!("Expected Object, found {:?}", self).into())
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use crate::avm1::object::Object;
|
||||
|
||||
use crate::player::{RenderContext, UpdateContext};
|
||||
use crate::prelude::*;
|
||||
use crate::transform::Transform;
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::fmt::Debug;
|
||||
use crate::avm1::Value;
|
||||
|
||||
#[derive(Clone, Collect, Debug)]
|
||||
#[collect(empty_drop)]
|
||||
|
@ -118,8 +117,8 @@ pub trait DisplayObject<'gc>: 'gc + Collect + Debug {
|
|||
}
|
||||
fn box_clone(&self) -> Box<dyn DisplayObject<'gc>>;
|
||||
|
||||
fn object(&self) -> Object<'gc> {
|
||||
Object::object() // todo: impl for every type and delete this fallback
|
||||
fn object(&self) -> Value<'gc> {
|
||||
Value::Undefined // todo: impl for every type and delete this fallback
|
||||
}
|
||||
|
||||
fn hit_test(&self, _: (Twips, Twips)) -> bool {
|
||||
|
|
|
@ -15,6 +15,7 @@ use crate::text::Text;
|
|||
use gc_arena::{Gc, GcCell, MutationContext};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use swf::read::SwfRead;
|
||||
use crate::avm1::Value;
|
||||
|
||||
type Depth = i16;
|
||||
type FrameNumber = u16;
|
||||
|
@ -34,7 +35,6 @@ pub struct MovieClip<'gc> {
|
|||
|
||||
impl<'gc> MovieClip<'gc> {
|
||||
pub fn new(gc_context: MutationContext<'gc, '_>) -> Self {
|
||||
let object = GcCell::allocate(gc_context, create_movie_object(gc_context));
|
||||
Self {
|
||||
base: Default::default(),
|
||||
static_data: Gc::allocate(gc_context, MovieClipStatic::default()),
|
||||
|
@ -44,7 +44,7 @@ impl<'gc> MovieClip<'gc> {
|
|||
current_frame: 0,
|
||||
audio_stream: None,
|
||||
children: BTreeMap::new(),
|
||||
object,
|
||||
object: GcCell::allocate(gc_context, create_movie_object(gc_context)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,6 @@ impl<'gc> MovieClip<'gc> {
|
|||
tag_stream_len: usize,
|
||||
num_frames: u16,
|
||||
) -> Self {
|
||||
let object = GcCell::allocate(gc_context, create_movie_object(gc_context));
|
||||
Self {
|
||||
base: Default::default(),
|
||||
static_data: Gc::allocate(
|
||||
|
@ -75,7 +74,7 @@ impl<'gc> MovieClip<'gc> {
|
|||
current_frame: 0,
|
||||
audio_stream: None,
|
||||
children: BTreeMap::new(),
|
||||
object,
|
||||
object: GcCell::allocate(gc_context, create_movie_object(gc_context)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,10 +231,6 @@ impl<'gc> MovieClip<'gc> {
|
|||
self.static_data.id
|
||||
}
|
||||
|
||||
pub fn object(&self) -> GcCell<'gc, Object<'gc>> {
|
||||
self.object
|
||||
}
|
||||
|
||||
fn tag_stream_start(&self) -> u64 {
|
||||
self.static_data.tag_stream_start
|
||||
}
|
||||
|
@ -442,6 +437,10 @@ impl<'gc> DisplayObject<'gc> for MovieClip<'gc> {
|
|||
object.set_display_node(display_object);
|
||||
object.set_type_of(TYPE_OF_MOVIE_CLIP);
|
||||
}
|
||||
|
||||
fn object(&self) -> Value<'gc> {
|
||||
Value::Object(self.object)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<'gc> gc_arena::Collect for MovieClip<'gc> {
|
||||
|
|
Loading…
Reference in New Issue