Execute actions in MovieClip scope

This commit is contained in:
David Wendt 2019-09-18 18:47:21 -06:00 committed by Mike Welsh
parent 215d4f2df4
commit ca1fb713a3
4 changed files with 23 additions and 5 deletions

View File

@ -108,8 +108,16 @@ impl<'gc> Avm1<'gc> {
form_values
}
/// Add a stack frame that executes code directly from a SwfSlice.
pub fn insert_stack_frame_from_action(&mut self, swf_version: u8, code: SwfSlice, gc_context: MutationContext<'gc, '_>) {
/// Add a stack frame that executes code in timeline scope
pub fn insert_stack_frame_for_action(&mut self, swf_version: u8, code: SwfSlice, action_context: &mut ActionContext<'_, 'gc, '_>) {
let global_scope = GcCell::allocate(action_context.gc_context, Scope::from_global_object(self.globals));
let clip_obj = action_context.active_clip.read().object().as_object().unwrap().to_owned();
let child_scope = GcCell::allocate(action_context.gc_context, Scope::from_parent_scope_with_object(global_scope, clip_obj));
self.stack_frames.push(Activation::from_action(swf_version, code, child_scope));
}
/// Add a stack frame that executes code in function scope
pub fn insert_stack_frame_for_function(&mut self, swf_version: u8, code: SwfSlice, gc_context: MutationContext<'gc, '_>) {
let scope = GcCell::allocate(gc_context, Scope::from_global_object(self.globals));
self.stack_frames.push(Activation::from_action(swf_version, code, scope));
}

View File

@ -68,7 +68,7 @@ impl<'gc> Executable<'gc> {
match self {
Executable::Native(nf) => Some(nf(avm, ac, this, args)),
Executable::Action(af) => {
avm.insert_stack_frame_from_action(af.swf_version, af.data.clone(), ac.gc_context);
avm.insert_stack_frame_for_function(af.swf_version, af.data.clone(), ac.gc_context);
for i in 0..args.len() {
avm.push(args.get(i).unwrap().clone());

View File

@ -27,7 +27,7 @@ impl<'gc> Scope<'gc> {
}
}
/// Construct a child scope (one with a parent).
/// Construct a child scope of another scope.
pub fn from_parent_scope(parent: GcCell<'gc, Self>, mc: MutationContext<'gc, '_>) -> Scope<'gc> {
Scope {
parent: Some(parent.clone()),
@ -35,6 +35,16 @@ impl<'gc> Scope<'gc> {
}
}
/// Construct a child scope with a given object
///
/// Rejected titles: `from_oyako_scope`
pub fn from_parent_scope_with_object(parent: GcCell<'gc, Self>, with_object: GcCell<'gc, Object<'gc>>) -> Scope<'gc> {
Scope {
parent: Some(parent),
values: with_object
}
}
/// Returns a reference to the current local scope object.
pub fn locals(&self) -> Ref<Object<'gc>> {
self.values.read()

View File

@ -515,7 +515,7 @@ impl<Audio: AudioBackend, Renderer: RenderBackend, Navigator: NavigatorBackend>
action_context.start_clip = active_clip;
action_context.active_clip = active_clip;
action_context.target_clip = Some(active_clip);
update_context.avm.insert_stack_frame_from_action(update_context.swf_version, action, update_context.gc_context);
update_context.avm.insert_stack_frame_for_action(update_context.swf_version, action, &mut action_context);
let _ = update_context.avm.run_stack_till_empty(&mut action_context);
}
}