@@ -149,19 +149,17 @@ impl<'gc> MovieClipWeak<'gc> {
149149#[ derive( Clone , Collect ) ]
150150#[ collect( no_drop) ]
151151pub struct MovieClipData < ' gc > {
152- base : RefLock < InteractiveObjectBase < ' gc > > ,
152+ cell : RefLock < MovieClipDataMut < ' gc > > ,
153153 shared : Lock < Gc < ' gc , MovieClipShared < ' gc > > > ,
154154 tag_stream_pos : Cell < u64 > ,
155155 current_frame : Cell < FrameNumber > ,
156156 #[ collect( require_static) ]
157157 audio_stream : Cell < Option < SoundInstanceHandle > > ,
158- container : RefLock < ChildContainer < ' gc > > ,
159158 object : Lock < Option < AvmObject < ' gc > > > ,
160159 #[ collect( require_static) ]
161160 clip_event_handlers : OnceCell < Box < [ ClipEventHandler ] > > ,
162161 #[ collect( require_static) ]
163162 clip_event_flags : Cell < ClipEventFlag > ,
164- frame_scripts : RefLock < Vec < Option < Avm2Object < ' gc > > > > ,
165163 flags : Cell < MovieClipFlags > ,
166164 /// This is lazily allocated on demand, to make `MovieClipData` smaller in the common case.
167165 #[ collect( require_static) ]
@@ -184,32 +182,41 @@ pub struct MovieClipData<'gc> {
184182 drop_target : Lock < Option < DisplayObject < ' gc > > > ,
185183
186184 /// List of tags queued up for the current frame.
187- #[ collect( require_static) ]
188185 queued_tags : RefCell < HashMap < Depth , QueuedTagList > > ,
189186
190187 /// Attached audio (AVM1)
191188 attached_audio : Lock < Option < NetStream < ' gc > > > ,
192189
193190 // If this movie was loaded from ImportAssets(2), this will be the parent movie.
194191 importer_movie : Option < Arc < SwfMovie > > ,
192+ }
195193
196- avm1_text_field_bindings : RefLock < Vec < Avm1TextFieldBinding < ' gc > > > ,
194+ #[ derive( Clone , Collect ) ]
195+ #[ collect( no_drop) ]
196+ struct MovieClipDataMut < ' gc > {
197+ base : InteractiveObjectBase < ' gc > ,
198+ container : ChildContainer < ' gc > ,
199+ frame_scripts : Vec < Option < Avm2Object < ' gc > > > ,
200+ avm1_text_field_bindings : Vec < Avm1TextFieldBinding < ' gc > > ,
197201}
198202
199203impl < ' gc > MovieClipData < ' gc > {
200204 fn new ( shared : MovieClipShared < ' gc > , mc : & Mutation < ' gc > ) -> Self {
201205 let movie = shared. movie ( ) ;
202206 Self {
203- base : Default :: default ( ) ,
207+ cell : RefLock :: new ( MovieClipDataMut {
208+ base : Default :: default ( ) ,
209+ container : ChildContainer :: new ( & movie) ,
210+ frame_scripts : Vec :: new ( ) ,
211+ avm1_text_field_bindings : Vec :: new ( ) ,
212+ } ) ,
204213 shared : Lock :: new ( Gc :: new ( mc, shared) ) ,
205214 tag_stream_pos : Cell :: new ( 0 ) ,
206215 current_frame : Cell :: new ( 0 ) ,
207216 audio_stream : Cell :: new ( None ) ,
208- container : RefLock :: new ( ChildContainer :: new ( & movie) ) ,
209217 object : Lock :: new ( None ) ,
210218 clip_event_handlers : OnceCell :: new ( ) ,
211219 clip_event_flags : Cell :: new ( ClipEventFlag :: empty ( ) ) ,
212- frame_scripts : RefLock :: new ( Vec :: new ( ) ) ,
213220 flags : Cell :: new ( MovieClipFlags :: empty ( ) ) ,
214221 drawing : OnceCell :: new ( ) ,
215222 avm2_enabled : Cell :: new ( true ) ,
@@ -220,11 +227,10 @@ impl<'gc> MovieClipData<'gc> {
220227 has_pending_script : Cell :: new ( false ) ,
221228 queued_goto_frame : Cell :: new ( None ) ,
222229 drop_target : Lock :: new ( None ) ,
223- hit_area : Lock :: new ( None ) ,
224230 queued_tags : Default :: default ( ) ,
231+ hit_area : Lock :: new ( None ) ,
225232 attached_audio : Lock :: new ( None ) ,
226233 importer_movie : None ,
227- avm1_text_field_bindings : Default :: default ( ) ,
228234 }
229235 }
230236
@@ -311,9 +317,9 @@ impl<'gc> MovieClip<'gc> {
311317 movie. num_frames ( ) ,
312318 loader_info. map ( |l| l. 0 ) ,
313319 ) ;
314- let data = MovieClipData :: new ( shared, activation. gc ( ) ) ;
320+ let mut data = MovieClipData :: new ( shared, activation. gc ( ) ) ;
315321 data. flags . set ( MovieClipFlags :: PLAYING ) ;
316- data. base . borrow ( ) . base . set_is_root ( true ) ;
322+ data. cell . get_mut ( ) . base . base . set_is_root ( true ) ;
317323
318324 let mc = MovieClip ( Gc :: new ( activation. gc ( ) , data) ) ;
319325 if let Some ( ( _, loader_info) ) = loader_info {
@@ -348,11 +354,11 @@ impl<'gc> MovieClip<'gc> {
348354 ) ;
349355
350356 {
351- let base = write. base . borrow ( ) ;
352- base. base . reset_for_movie_load ( ) ;
353- base. base . set_is_root ( is_root) ;
357+ let mut write = unlock ! ( write, MovieClipData , cell) . borrow_mut ( ) ;
358+ write. base . base . reset_for_movie_load ( ) ;
359+ write. base . base . set_is_root ( is_root) ;
360+ write. container = ChildContainer :: new ( & movie) ;
354361 }
355- unlock ! ( write, MovieClipData , container) . replace ( ChildContainer :: new ( & movie) ) ;
356362 unlock ! ( write, MovieClipData , shared) . set ( Gc :: new (
357363 context. gc ( ) ,
358364 MovieClipShared :: with_data (
@@ -885,12 +891,16 @@ impl<'gc> MovieClip<'gc> {
885891 }
886892
887893 pub fn has_frame_script ( self , frame : FrameNumber ) -> bool {
894+ self . frame_script ( frame) . is_some ( )
895+ }
896+
897+ fn frame_script ( self , frame : FrameNumber ) -> Option < Avm2Object < ' gc > > {
888898 self . 0
889- . frame_scripts
899+ . cell
890900 . borrow ( )
901+ . frame_scripts
891902 . get ( frame as usize )
892- . map ( |v| v. is_some ( ) )
893- . unwrap_or_default ( )
903+ . and_then ( |& v| v)
894904 }
895905
896906 /// This sets the current preload frame of this MovieClipto a given number (resulting
@@ -1425,7 +1435,7 @@ impl<'gc> MovieClip<'gc> {
14251435 // tags. The rest of the goto machinery can handle the side effects of
14261436 // a half-executed loop.
14271437 if self . 0 . loop_queued ( ) {
1428- self . 0 . queued_tags . take ( ) ;
1438+ self . 0 . queued_tags . borrow_mut ( ) . clear ( ) ;
14291439 }
14301440
14311441 if is_implicit {
@@ -1823,7 +1833,10 @@ impl<'gc> MovieClip<'gc> {
18231833 ) {
18241834 let write = Gc :: write ( context. gc ( ) , self . 0 ) ;
18251835 let current_frame = write. current_frame ( ) ;
1826- let mut frame_scripts = unlock ! ( write, MovieClipData , frame_scripts) . borrow_mut ( ) ;
1836+ let mut frame_scripts =
1837+ RefMut :: map ( unlock ! ( write, MovieClipData , cell) . borrow_mut ( ) , |r| {
1838+ & mut r. frame_scripts
1839+ } ) ;
18271840
18281841 let index = frame_id as usize ;
18291842 if let Some ( callable) = callable {
@@ -2143,13 +2156,7 @@ impl<'gc> MovieClip<'gc> {
21432156 let is_fresh_frame = self . 0 . last_queued_script_frame . get ( ) != Some ( frame_id) ;
21442157
21452158 if is_fresh_frame {
2146- if let Some ( Some ( callable) ) = self
2147- . 0
2148- . frame_scripts
2149- . borrow ( )
2150- . get ( frame_id as usize )
2151- . cloned ( )
2152- {
2159+ if let Some ( callable) = self . frame_script ( frame_id) {
21532160 self . 0 . last_queued_script_frame . set ( Some ( frame_id) ) ;
21542161 self . 0 . has_pending_script . set ( false ) ;
21552162 self . 0
@@ -2192,12 +2199,12 @@ impl<'gc> MovieClip<'gc> {
21922199
21932200impl < ' gc > TDisplayObject < ' gc > for MovieClip < ' gc > {
21942201 fn base ( & self ) -> Ref < ' _ , DisplayObjectBase < ' gc > > {
2195- Ref :: map ( self . 0 . base . borrow ( ) , |r| & r. base )
2202+ Ref :: map ( self . 0 . cell . borrow ( ) , |r| & r. base . base )
21962203 }
21972204
21982205 fn base_mut < ' a > ( & ' a self , mc : & Mutation < ' gc > ) -> RefMut < ' a , DisplayObjectBase < ' gc > > {
2199- let base = unlock ! ( Gc :: write( mc, self . 0 ) , MovieClipData , base ) ;
2200- RefMut :: map ( base . borrow_mut ( ) , |r| & mut r. base )
2206+ let write = unlock ! ( Gc :: write( mc, self . 0 ) , MovieClipData , cell ) ;
2207+ RefMut :: map ( write . borrow_mut ( ) , |r| & mut r. base . base )
22012208 }
22022209
22032210 fn instantiate ( self , mc : & Mutation < ' gc > ) -> DisplayObject < ' gc > {
@@ -2312,12 +2319,7 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
23122319
23132320 // Check for frame-scripts before starting the frame-script phase,
23142321 // to differentiate the pre-existing scripts from those introduced during frame-script phase.
2315- let has_pending_script = self
2316- . 0
2317- . frame_scripts
2318- . borrow ( )
2319- . get ( self . 0 . current_frame . get ( ) as usize )
2320- . is_some ( ) ;
2322+ let has_pending_script = self . has_frame_script ( self . 0 . current_frame . get ( ) ) ;
23212323 self . 0 . has_pending_script . set ( has_pending_script) ;
23222324 }
23232325
@@ -2554,8 +2556,8 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
25542556 fn avm1_text_field_bindings ( & self ) -> Option < Ref < ' _ , [ Avm1TextFieldBinding < ' gc > ] > > {
25552557 let obj = self . 0 . object . get ( ) . and_then ( |o| o. as_avm1_object ( ) ) ;
25562558 obj. map ( |_| {
2557- let bindings = self . 0 . avm1_text_field_bindings . borrow ( ) ;
2558- Ref :: map ( bindings , |b| & * * b )
2559+ let read = self . 0 . cell . borrow ( ) ;
2560+ Ref :: map ( read , |r| r . avm1_text_field_bindings . as_slice ( ) )
25592561 } )
25602562 }
25612563
@@ -2565,8 +2567,8 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
25652567 ) -> Option < RefMut < ' _ , Vec < Avm1TextFieldBinding < ' gc > > > > {
25662568 let obj = self . 0 . object . get ( ) . and_then ( |o| o. as_avm1_object ( ) ) ;
25672569 obj. map ( |_| {
2568- let write = Gc :: write ( mc, self . 0 ) ;
2569- unlock ! ( write, MovieClipData , avm1_text_field_bindings ) . borrow_mut ( )
2570+ let write = unlock ! ( Gc :: write( mc, self . 0 ) , MovieClipData , cell ) ;
2571+ RefMut :: map ( write. borrow_mut ( ) , |r| & mut r . avm1_text_field_bindings )
25702572 } )
25712573 }
25722574
@@ -2581,11 +2583,12 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
25812583
25822584impl < ' gc > TDisplayObjectContainer < ' gc > for MovieClip < ' gc > {
25832585 fn raw_container ( & self ) -> Ref < ' _ , ChildContainer < ' gc > > {
2584- self . 0 . container . borrow ( )
2586+ Ref :: map ( self . 0 . cell . borrow ( ) , |r| & r . container )
25852587 }
25862588
25872589 fn raw_container_mut ( & self , mc : & Mutation < ' gc > ) -> RefMut < ' _ , ChildContainer < ' gc > > {
2588- unlock ! ( Gc :: write( mc, self . 0 ) , MovieClipData , container) . borrow_mut ( )
2590+ let write = unlock ! ( Gc :: write( mc, self . 0 ) , MovieClipData , cell) ;
2591+ RefMut :: map ( write. borrow_mut ( ) , |r| & mut r. container )
25892592 }
25902593
25912594 fn is_tab_children_avm1 ( self , context : & mut UpdateContext < ' gc > ) -> bool {
@@ -2595,11 +2598,12 @@ impl<'gc> TDisplayObjectContainer<'gc> for MovieClip<'gc> {
25952598
25962599impl < ' gc > TInteractiveObject < ' gc > for MovieClip < ' gc > {
25972600 fn raw_interactive ( & self ) -> Ref < ' _ , InteractiveObjectBase < ' gc > > {
2598- self . 0 . base . borrow ( )
2601+ Ref :: map ( self . 0 . cell . borrow ( ) , |r| & r . base )
25992602 }
26002603
26012604 fn raw_interactive_mut ( & self , mc : & Mutation < ' gc > ) -> RefMut < ' _ , InteractiveObjectBase < ' gc > > {
2602- unlock ! ( Gc :: write( mc, self . 0 ) , MovieClipData , base) . borrow_mut ( )
2605+ let write = unlock ! ( Gc :: write( mc, self . 0 ) , MovieClipData , cell) ;
2606+ RefMut :: map ( write. borrow_mut ( ) , |r| & mut r. base )
26032607 }
26042608
26052609 fn as_displayobject ( self ) -> DisplayObject < ' gc > {
0 commit comments