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:
parent
d5f7521061
commit
8c27097240
|
@ -1707,13 +1707,11 @@ impl<'gc> Avm1<'gc> {
|
||||||
if target.is_empty() {
|
if target.is_empty() {
|
||||||
context.active_clip = context.start_clip;
|
context.active_clip = context.start_clip;
|
||||||
context.target_clip = Some(context.start_clip);
|
context.target_clip = Some(context.start_clip);
|
||||||
context.target_path = target.into();
|
|
||||||
} else if let Some(clip) =
|
} else if let Some(clip) =
|
||||||
Avm1::resolve_slash_path(context.start_clip, context.root, target)
|
Avm1::resolve_slash_path(context.start_clip, context.root, target)
|
||||||
{
|
{
|
||||||
context.target_clip = Some(clip);
|
context.target_clip = Some(clip);
|
||||||
context.active_clip = clip;
|
context.active_clip = clip;
|
||||||
context.target_path = target.into();
|
|
||||||
} else {
|
} else {
|
||||||
log::warn!("SetTarget failed: {} not found", target);
|
log::warn!("SetTarget failed: {} not found", target);
|
||||||
// TODO: Emulate AVM1 trace error message.
|
// TODO: Emulate AVM1 trace error message.
|
||||||
|
@ -1724,7 +1722,6 @@ impl<'gc> Avm1<'gc> {
|
||||||
// fail silenty.
|
// fail silenty.
|
||||||
context.target_clip = None;
|
context.target_clip = None;
|
||||||
context.active_clip = context.root;
|
context.active_clip = context.root;
|
||||||
context.target_path = Value::Undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let scope = self.current_stack_frame().unwrap().read().scope_cell();
|
let scope = self.current_stack_frame().unwrap().read().scope_cell();
|
||||||
|
|
|
@ -436,7 +436,6 @@ mod tests {
|
||||||
start_clip: root,
|
start_clip: root,
|
||||||
active_clip: root,
|
active_clip: root,
|
||||||
target_clip: Some(root),
|
target_clip: Some(root),
|
||||||
target_path: Value::Undefined,
|
|
||||||
rng: &mut SmallRng::from_seed([0u8; 16]),
|
rng: &mut SmallRng::from_seed([0u8; 16]),
|
||||||
action_queue: &mut crate::context::ActionQueue::new(),
|
action_queue: &mut crate::context::ActionQueue::new(),
|
||||||
audio: &mut NullAudioBackend::new(),
|
audio: &mut NullAudioBackend::new(),
|
||||||
|
|
|
@ -575,10 +575,9 @@ fn set_rotation<'gc>(
|
||||||
fn target<'gc>(
|
fn target<'gc>(
|
||||||
_avm: &mut Avm1<'gc>,
|
_avm: &mut Avm1<'gc>,
|
||||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
_context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
_this: DisplayObject<'gc>,
|
this: DisplayObject<'gc>,
|
||||||
) -> Result<Value<'gc>, Error> {
|
) -> Result<Value<'gc>, Error> {
|
||||||
log::warn!("Unimplemented property _target");
|
Ok(this.slash_path().into())
|
||||||
Ok("".into())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn frames_loaded<'gc>(
|
fn frames_loaded<'gc>(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::avm1::activation::Activation;
|
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::audio::NullAudioBackend;
|
||||||
use crate::backend::navigator::NullNavigatorBackend;
|
use crate::backend::navigator::NullNavigatorBackend;
|
||||||
use crate::backend::render::NullRenderer;
|
use crate::backend::render::NullRenderer;
|
||||||
|
@ -32,7 +32,6 @@ where
|
||||||
start_clip: root,
|
start_clip: root,
|
||||||
active_clip: root,
|
active_clip: root,
|
||||||
target_clip: Some(root),
|
target_clip: Some(root),
|
||||||
target_path: Value::Undefined,
|
|
||||||
rng: &mut SmallRng::from_seed([0u8; 16]),
|
rng: &mut SmallRng::from_seed([0u8; 16]),
|
||||||
audio: &mut NullAudioBackend::new(),
|
audio: &mut NullAudioBackend::new(),
|
||||||
action_queue: &mut ActionQueue::new(),
|
action_queue: &mut ActionQueue::new(),
|
||||||
|
|
|
@ -77,13 +77,6 @@ pub struct UpdateContext<'a, 'gc, 'gc_context> {
|
||||||
/// `target_clip` will reset to this value with `SetTarget ""` action.
|
/// `target_clip` will reset to this value with `SetTarget ""` action.
|
||||||
pub start_clip: DisplayObject<'gc>,
|
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
|
/// The current set of system-specified prototypes to use when constructing
|
||||||
/// new built-in objects.
|
/// new built-in objects.
|
||||||
pub system_prototypes: avm1::SystemPrototypes<'gc>,
|
pub system_prototypes: avm1::SystemPrototypes<'gc>,
|
||||||
|
|
|
@ -521,6 +521,7 @@ pub trait TDisplayObject<'gc>: 'gc + Collect + Debug {
|
||||||
fn set_alpha(&self, gc_context: MutationContext<'gc, '_>, value: f64);
|
fn set_alpha(&self, gc_context: MutationContext<'gc, '_>, value: f64);
|
||||||
fn name(&self) -> Ref<str>;
|
fn name(&self) -> Ref<str>;
|
||||||
fn set_name(&mut self, context: MutationContext<'gc, '_>, name: &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`
|
/// Returns the dot-syntax path to this display object, e.g. `_level0.foo.clip`
|
||||||
fn path(&self) -> String {
|
fn path(&self) -> String {
|
||||||
if let Some(parent) = self.parent() {
|
if let Some(parent) = self.parent() {
|
||||||
|
@ -532,6 +533,21 @@ pub trait TDisplayObject<'gc>: 'gc + Collect + Debug {
|
||||||
self.name().to_string()
|
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 clip_depth(&self) -> Depth;
|
||||||
fn set_clip_depth(&mut self, context: MutationContext<'gc, '_>, depth: Depth);
|
fn set_clip_depth(&mut self, context: MutationContext<'gc, '_>, depth: Depth);
|
||||||
fn parent(&self) -> Option<DisplayObject<'gc>>;
|
fn parent(&self) -> Option<DisplayObject<'gc>>;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::avm1::{Avm1, Value};
|
use crate::avm1::Avm1;
|
||||||
use crate::backend::{
|
use crate::backend::{
|
||||||
audio::AudioBackend, navigator::NavigatorBackend, render::Letterbox, render::RenderBackend,
|
audio::AudioBackend, navigator::NavigatorBackend, render::Letterbox, render::RenderBackend,
|
||||||
};
|
};
|
||||||
|
@ -594,7 +594,6 @@ impl<Audio: AudioBackend, Renderer: RenderBackend, Navigator: NavigatorBackend>
|
||||||
start_clip: root,
|
start_clip: root,
|
||||||
target_clip: Some(root),
|
target_clip: Some(root),
|
||||||
root,
|
root,
|
||||||
target_path: Value::Undefined,
|
|
||||||
system_prototypes: avm.prototypes().clone(),
|
system_prototypes: avm.prototypes().clone(),
|
||||||
mouse_hovered_object,
|
mouse_hovered_object,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue