@@ -158,7 +158,7 @@ pub struct MovieClipData<'gc> {
158158 container : RefLock < ChildContainer < ' gc > > ,
159159 object : Lock < Option < AvmObject < ' gc > > > ,
160160 #[ collect( require_static) ]
161- clip_event_handlers : RefCell < Box < [ ClipEventHandler ] > > ,
161+ clip_event_handlers : OnceCell < Box < [ ClipEventHandler ] > > ,
162162 #[ collect( require_static) ]
163163 clip_event_flags : Cell < ClipEventFlag > ,
164164 frame_scripts : RefLock < Vec < Option < Avm2Object < ' gc > > > > ,
@@ -207,7 +207,7 @@ impl<'gc> MovieClipData<'gc> {
207207 audio_stream : Cell :: new ( None ) ,
208208 container : RefLock :: new ( ChildContainer :: new ( & movie) ) ,
209209 object : Lock :: new ( None ) ,
210- clip_event_handlers : Default :: default ( ) ,
210+ clip_event_handlers : OnceCell :: new ( ) ,
211211 clip_event_flags : Cell :: new ( ClipEventFlag :: empty ( ) ) ,
212212 frame_scripts : RefLock :: new ( Vec :: new ( ) ) ,
213213 flags : Cell :: new ( MovieClipFlags :: empty ( ) ) ,
@@ -677,9 +677,7 @@ impl<'gc> MovieClip<'gc> {
677677
678678 /// Does this clip have a unload handler
679679 pub fn has_unload_handler ( & self ) -> bool {
680- self . 0
681- . clip_event_handlers
682- . borrow ( )
680+ self . clip_actions ( )
683681 . iter ( )
684682 . any ( |handler| handler. events . contains ( ClipEventFlag :: UNLOAD ) )
685683 }
@@ -1042,20 +1040,27 @@ impl<'gc> MovieClip<'gc> {
10421040 }
10431041
10441042 /// Gets the clip events for this MovieClip.
1045- pub fn clip_actions ( & self ) -> Ref < ' _ , [ ClipEventHandler ] > {
1046- Ref :: map ( self . 0 . clip_event_handlers . borrow ( ) , |r| & * * r)
1043+ pub fn clip_actions ( self ) -> & ' gc [ ClipEventHandler ] {
1044+ match Gc :: as_ref ( self . 0 ) . clip_event_handlers . get ( ) {
1045+ Some ( handlers) => handlers,
1046+ None => & [ ] ,
1047+ }
10471048 }
10481049
10491050 /// Sets the clip actions (a.k.a. clip events) for this MovieClip.
10501051 /// Clip actions are created in the Flash IDE by using the `onEnterFrame`
10511052 /// tag on a MovieClip instance.
1052- pub fn set_clip_event_handlers ( self , event_handlers : Box < [ ClipEventHandler ] > ) {
1053+ pub fn init_clip_event_handlers ( self , event_handlers : Box < [ ClipEventHandler ] > ) {
1054+ if self . 0 . clip_event_handlers . get ( ) . is_some ( ) {
1055+ panic ! ( "Clip event handlers already initialized" ) ;
1056+ }
1057+
10531058 let mut all_event_flags = ClipEventFlag :: empty ( ) ;
1054- for handler in & event_handlers {
1059+ for handler in self . 0 . clip_event_handlers . get_or_init ( || event_handlers) {
10551060 all_event_flags |= handler. events ;
10561061 }
1062+
10571063 self . 0 . clip_event_flags . set ( all_event_flags) ;
1058- self . 0 . clip_event_handlers . replace ( event_handlers) ;
10591064 }
10601065
10611066 /// Returns an iterator of AVM1 `DoAction` blocks on the given frame number.
@@ -1277,7 +1282,7 @@ impl<'gc> MovieClip<'gc> {
12771282 ( & place_object. clip_actions , child. as_movie_clip ( ) )
12781283 {
12791284 // Convert from `swf::ClipAction` to Ruffle's `ClipEventHandler`.
1280- clip. set_clip_event_handlers (
1285+ clip. init_clip_event_handlers (
12811286 clip_actions
12821287 . iter ( )
12831288 . cloned ( )
@@ -1712,7 +1717,7 @@ impl<'gc> MovieClip<'gc> {
17121717
17131718 let mut events = Vec :: new ( ) ;
17141719
1715- for event_handler in self . 0 . clip_event_handlers . borrow ( ) . iter ( ) {
1720+ for event_handler in self . clip_actions ( ) . iter ( ) {
17161721 if event_handler. events . contains ( ClipEventFlag :: INITIALIZE ) {
17171722 context. action_queue . queue_action (
17181723 self . into ( ) ,
@@ -2649,9 +2654,7 @@ impl<'gc> TInteractiveObject<'gc> for MovieClip<'gc> {
26492654 if swf_version >= 5 {
26502655 if let Some ( flag) = event. flag ( ) {
26512656 for event_handler in self
2652- . 0
2653- . clip_event_handlers
2654- . borrow ( )
2657+ . clip_actions ( )
26552658 . iter ( )
26562659 . filter ( |handler| handler. events . contains ( flag) )
26572660 {
0 commit comments