core: Implement _target property

Add DisplayObject::slash_path to get the Flash 4-style slash path
to the clip. This fixes the tellTarget regression test and removes
the superfluous `target_path` from `UpdateContext`.
This commit is contained in:
Mike Welsh 2019-12-14 23:12:32 -08:00
parent d5f7521061
commit 8c27097240
7 changed files with 20 additions and 18 deletions

View File

@ -1707,13 +1707,11 @@ impl<'gc> Avm1<'gc> {
if target.is_empty() {
context.active_clip = context.start_clip;
context.target_clip = Some(context.start_clip);
context.target_path = target.into();
} else if let Some(clip) =
Avm1::resolve_slash_path(context.start_clip, context.root, target)
{
context.target_clip = Some(clip);
context.active_clip = clip;
context.target_path = target.into();
} else {
log::warn!("SetTarget failed: {} not found", target);
// TODO: Emulate AVM1 trace error message.
@ -1724,7 +1722,6 @@ impl<'gc> Avm1<'gc> {
// fail silenty.
context.target_clip = None;
context.active_clip = context.root;
context.target_path = Value::Undefined;
}
let scope = self.current_stack_frame().unwrap().read().scope_cell();

View File

@ -436,7 +436,6 @@ mod tests {
start_clip: root,
active_clip: root,
target_clip: Some(root),
target_path: Value::Undefined,
rng: &mut SmallRng::from_seed([0u8; 16]),
action_queue: &mut crate::context::ActionQueue::new(),
audio: &mut NullAudioBackend::new(),

View File

@ -575,10 +575,9 @@ fn set_rotation<'gc>(
fn target<'gc>(
_avm: &mut Avm1<'gc>,
_context: &mut UpdateContext<'_, 'gc, '_>,
_this: DisplayObject<'gc>,
this: DisplayObject<'gc>,
) -> Result<Value<'gc>, Error> {
log::warn!("Unimplemented property _target");
Ok("".into())
Ok(this.slash_path().into())
}
fn frames_loaded<'gc>(

View File

@ -1,5 +1,5 @@
use crate::avm1::activation::Activation;
use crate::avm1::{Avm1, Object, UpdateContext, Value};
use crate::avm1::{Avm1, Object, UpdateContext};
use crate::backend::audio::NullAudioBackend;
use crate::backend::navigator::NullNavigatorBackend;
use crate::backend::render::NullRenderer;
@ -32,7 +32,6 @@ where
start_clip: root,
active_clip: root,
target_clip: Some(root),
target_path: Value::Undefined,
rng: &mut SmallRng::from_seed([0u8; 16]),
audio: &mut NullAudioBackend::new(),
action_queue: &mut ActionQueue::new(),

View File

@ -77,13 +77,6 @@ pub struct UpdateContext<'a, 'gc, 'gc_context> {
/// `target_clip` will reset to this value with `SetTarget ""` action.
pub start_clip: DisplayObject<'gc>,
/// The last path string used by `tellTarget`.
/// Returned by `GetProperty`.
/// TODO: This should actually be built dynamically upon
/// request, but this requires us to implement auto-generated
/// _names ("instanceN" etc. for unnamed clips).
pub target_path: avm1::Value<'gc>,
/// The current set of system-specified prototypes to use when constructing
/// new built-in objects.
pub system_prototypes: avm1::SystemPrototypes<'gc>,

View File

@ -521,6 +521,7 @@ pub trait TDisplayObject<'gc>: 'gc + Collect + Debug {
fn set_alpha(&self, gc_context: MutationContext<'gc, '_>, value: f64);
fn name(&self) -> Ref<str>;
fn set_name(&mut self, context: MutationContext<'gc, '_>, name: &str);
/// Returns the dot-syntax path to this display object, e.g. `_level0.foo.clip`
fn path(&self) -> String {
if let Some(parent) = self.parent() {
@ -532,6 +533,21 @@ pub trait TDisplayObject<'gc>: 'gc + Collect + Debug {
self.name().to_string()
}
}
/// Returns the Flash 4 slash-syntax path to this display object, e.g. `/foo/clip`.
/// Returned by the `_target` property in AVM1.
fn slash_path(&self) -> String {
if let Some(parent) = self.parent() {
let mut path = parent.slash_path();
path.push_str("/");
path.push_str(&*self.name());
path
} else {
// The stage/root levels do not append their name in slash syntax.
"".to_string()
}
}
fn clip_depth(&self) -> Depth;
fn set_clip_depth(&mut self, context: MutationContext<'gc, '_>, depth: Depth);
fn parent(&self) -> Option<DisplayObject<'gc>>;

View File

@ -1,4 +1,4 @@
use crate::avm1::{Avm1, Value};
use crate::avm1::Avm1;
use crate::backend::{
audio::AudioBackend, navigator::NavigatorBackend, render::Letterbox, render::RenderBackend,
};
@ -594,7 +594,6 @@ impl<Audio: AudioBackend, Renderer: RenderBackend, Navigator: NavigatorBackend>
start_clip: root,
target_clip: Some(root),
root,
target_path: Value::Undefined,
system_prototypes: avm.prototypes().clone(),
mouse_hovered_object,
};