diff --git a/core/src/avm1.rs b/core/src/avm1.rs index 571916476..10d95baac 100644 --- a/core/src/avm1.rs +++ b/core/src/avm1.rs @@ -3,13 +3,12 @@ use crate::avm1::globals::create_globals; use crate::avm1::object::stage_object; use crate::avm1::property_map::PropertyMap; use crate::context::UpdateContext; -use crate::prelude::*; -use gc_arena::{Collect, GcCell, MutationContext}; - -use swf::avm1::read::Reader; - use crate::display_object::DisplayObject; +use crate::frame_lifecycle::FramePhase; +use crate::prelude::*; use crate::tag_utils::SwfSlice; +use gc_arena::{Collect, GcCell, MutationContext}; +use swf::avm1::read::Reader; #[cfg(test)] #[macro_use] @@ -424,12 +423,39 @@ impl<'gc> Avm1<'gc> { } /// Returns an iterator over all movie clips in execution order. - pub fn clip_exec_iter(&self) -> DisplayObjectIter<'gc> { + fn clip_exec_iter(&self) -> DisplayObjectIter<'gc> { DisplayObjectIter { clip: self.clip_exec_list, } } + // Run a single frame. + pub fn run_frame(context: &mut UpdateContext<'_, 'gc, '_>) { + // In AVM1, we only ever execute the update phase, and all the work that + // would ordinarily be phased is instead run all at once in whatever order + // the SWF requests it. + *context.frame_phase = FramePhase::Update; + + // AVM1 execution order is determined by the global execution list, based on instantiation order. + for clip in context.avm1.clip_exec_iter() { + if clip.removed() { + // Clean up removed objects from this frame or a previous frame. + // Can be safely removed while iterating here, because the iterator advances + // to the next node before returning the current node. + context.avm1.remove_from_exec_list(context.gc_context, clip); + } else { + clip.run_frame(context); + } + } + + // Fire "onLoadInit" events. + context + .load_manager + .movie_clip_on_load(context.action_queue); + + *context.frame_phase = FramePhase::Idle; + } + /// Adds a movie clip to the execution list. /// /// This should be called whenever a movie clip is created, and controls the order of @@ -450,7 +476,7 @@ impl<'gc> Avm1<'gc> { } /// Removes a display object from the execution list. - pub fn remove_from_exec_list( + fn remove_from_exec_list( &mut self, gc_context: MutationContext<'gc, '_>, clip: DisplayObject<'gc>, @@ -642,7 +668,7 @@ pub fn start_drag<'gc>( *activation.context.drag_object = Some(drag_object); } -pub struct DisplayObjectIter<'gc> { +struct DisplayObjectIter<'gc> { clip: Option>, } diff --git a/core/src/frame_lifecycle.rs b/core/src/frame_lifecycle.rs index 544eeb50c..a4228b393 100644 --- a/core/src/frame_lifecycle.rs +++ b/core/src/frame_lifecycle.rs @@ -75,33 +75,6 @@ impl Default for FramePhase { } } -/// Run one frame according to AVM1 frame order. -pub fn run_all_phases_avm1<'gc>(context: &mut UpdateContext<'_, 'gc, '_>) { - // In AVM1, we only ever execute the update phase, and all the work that - // would ordinarily be phased is instead run all at once in whatever order - // the SWF requests it. - *context.frame_phase = FramePhase::Update; - - // AVM1 execution order is determined by the global execution list, based on instantiation order. - for clip in context.avm1.clip_exec_iter() { - if clip.removed() { - // Clean up removed objects from this frame or a previous frame. - // Can be safely removed while iterating here, because the iterator advances - // to the next node before returning the current node. - context.avm1.remove_from_exec_list(context.gc_context, clip); - } else { - clip.run_frame(context); - } - } - - // Fire "onLoadInit" events. - context - .load_manager - .movie_clip_on_load(context.action_queue); - - *context.frame_phase = FramePhase::Idle; -} - /// Run one frame according to AVM2 frame order. pub fn run_all_phases_avm2<'gc>(context: &mut UpdateContext<'_, 'gc, '_>) { let stage = context.stage; diff --git a/core/src/player.rs b/core/src/player.rs index 668602432..8c3e580e5 100644 --- a/core/src/player.rs +++ b/core/src/player.rs @@ -30,7 +30,7 @@ use crate::external::Value as ExternalValue; use crate::external::{ExternalInterface, ExternalInterfaceProvider}; use crate::focus_tracker::FocusTracker; use crate::font::Font; -use crate::frame_lifecycle::{run_all_phases_avm1, run_all_phases_avm2, FramePhase}; +use crate::frame_lifecycle::{run_all_phases_avm2, FramePhase}; use crate::library::Library; use crate::loader::LoadManager; use crate::locale::get_current_date_time; @@ -1340,7 +1340,7 @@ impl Player { if context.is_action_script_3() { run_all_phases_avm2(context); } else { - run_all_phases_avm1(context); + Avm1::run_frame(context); } context.update_sounds(); });