diff --git a/core/src/avm2/object.rs b/core/src/avm2/object.rs index 3c309fb1b..736877cd2 100644 --- a/core/src/avm2/object.rs +++ b/core/src/avm2/object.rs @@ -1392,7 +1392,7 @@ impl<'gc> Object<'gc> { Self::LoaderInfoObject(o) => WeakObject::LoaderInfoObject(LoaderInfoObjectWeak(GcCell::downgrade(o.0))), Self::ClassObject(o) => WeakObject::ClassObject(ClassObjectWeak(Gc::downgrade(o.0))), Self::VectorObject(o) => WeakObject::VectorObject(VectorObjectWeak(Gc::downgrade(o.0))), - Self::SoundObject(o) => WeakObject::SoundObject(SoundObjectWeak(GcCell::downgrade(o.0))), + Self::SoundObject(o) => WeakObject::SoundObject(SoundObjectWeak(Gc::downgrade(o.0))), Self::SoundChannelObject(o) => WeakObject::SoundChannelObject(SoundChannelObjectWeak(GcCell::downgrade(o.0))), Self::BitmapDataObject(o) => WeakObject::BitmapDataObject(BitmapDataObjectWeak(Gc::downgrade(o.0))), Self::DateObject(o) => WeakObject::DateObject(DateObjectWeak(Gc::downgrade(o.0))), diff --git a/core/src/avm2/object/sound_object.rs b/core/src/avm2/object/sound_object.rs index 102e05c85..ca5355775 100644 --- a/core/src/avm2/object/sound_object.rs +++ b/core/src/avm2/object/sound_object.rs @@ -12,7 +12,11 @@ use crate::context::UpdateContext; use crate::display_object::SoundTransform; use crate::string::AvmString; use core::fmt; -use gc_arena::{Collect, GcCell, GcWeakCell, Mutation}; +use gc_arena::barrier::unlock; +use gc_arena::{ + lock::{Lock, RefLock}, + Collect, Gc, GcWeak, Mutation, +}; use id3::{Tag, TagLike}; use std::cell::{Ref, RefMut}; use std::io::Cursor; @@ -25,16 +29,16 @@ pub fn sound_allocator<'gc>( class: ClassObject<'gc>, activation: &mut Activation<'_, 'gc>, ) -> Result, Error<'gc>> { - let base = ScriptObjectData::new(class); + let base = ScriptObjectData::new(class).into(); - Ok(SoundObject(GcCell::new( + Ok(SoundObject(Gc::new( activation.context.gc_context, SoundObjectData { base, - sound_data: SoundData::NotLoaded { + sound_data: RefLock::new(SoundData::NotLoaded { queued_plays: Vec::new(), - }, - id3: None, + }), + id3: Lock::new(None), }, )) .into()) @@ -42,16 +46,16 @@ pub fn sound_allocator<'gc>( #[derive(Clone, Collect, Copy)] #[collect(no_drop)] -pub struct SoundObject<'gc>(pub GcCell<'gc, SoundObjectData<'gc>>); +pub struct SoundObject<'gc>(pub Gc<'gc, SoundObjectData<'gc>>); #[derive(Clone, Collect, Copy, Debug)] #[collect(no_drop)] -pub struct SoundObjectWeak<'gc>(pub GcWeakCell<'gc, SoundObjectData<'gc>>); +pub struct SoundObjectWeak<'gc>(pub GcWeak<'gc, SoundObjectData<'gc>>); impl fmt::Debug for SoundObject<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("SoundObject") - .field("ptr", &self.0.as_ptr()) + .field("ptr", &Gc::as_ptr(self.0)) .finish() } } @@ -60,13 +64,13 @@ impl fmt::Debug for SoundObject<'_> { #[collect(no_drop)] pub struct SoundObjectData<'gc> { /// Base script object - base: ScriptObjectData<'gc>, + base: RefLock>, /// The sound this object holds. - sound_data: SoundData<'gc>, + sound_data: RefLock>, /// ID3Info Object - id3: Option>, + id3: Lock>>, } #[derive(Collect)] @@ -94,10 +98,10 @@ pub struct QueuedPlay<'gc> { impl<'gc> SoundObject<'gc> { pub fn sound_handle(self) -> Option { - let this = self.0.read(); - match this.sound_data { + let sound_data = self.0.sound_data.borrow(); + match &*sound_data { SoundData::NotLoaded { .. } => None, - SoundData::Loaded { sound } => Some(sound), + SoundData::Loaded { sound } => Some(*sound), } } @@ -107,8 +111,13 @@ impl<'gc> SoundObject<'gc> { queued: QueuedPlay<'gc>, activation: &mut Activation<'_, 'gc>, ) -> Result> { - let mut this = self.0.write(activation.context.gc_context); - match &mut this.sound_data { + let mut sound_data = unlock!( + Gc::write(activation.context.gc_context, self.0), + SoundObjectData, + sound_data + ) + .borrow_mut(); + match &mut *sound_data { SoundData::NotLoaded { queued_plays } => { queued_plays.push(queued); // We don't know the length yet, so return the `SoundChannel` @@ -123,14 +132,19 @@ impl<'gc> SoundObject<'gc> { context: &mut UpdateContext<'_, 'gc>, sound: SoundHandle, ) -> Result<(), Error<'gc>> { - let mut this = self.0.write(context.gc_context); + let mut sound_data = unlock!( + Gc::write(context.gc_context, self.0), + SoundObjectData, + sound_data + ) + .borrow_mut(); let mut activation = Activation::from_nothing(context.reborrow()); - match &mut this.sound_data { + match &mut *sound_data { SoundData::NotLoaded { queued_plays } => { for queued in std::mem::take(queued_plays) { play_queued(queued, sound, &mut activation)?; } - this.sound_data = SoundData::Loaded { sound }; + *sound_data = SoundData::Loaded { sound }; } SoundData::Loaded { sound: old_sound } => { panic!("Tried to replace sound {old_sound:?} with {sound:?}") @@ -140,13 +154,11 @@ impl<'gc> SoundObject<'gc> { } pub fn id3(self) -> Option> { - let this = self.0.read(); - this.id3 + self.0.id3.get() } pub fn set_id3(self, mc: &Mutation<'gc>, id3: Option>) { - let mut this = self.0.write(mc); - this.id3 = id3; + unlock!(Gc::write(mc, self.0), SoundObjectData, id3).set(id3); } pub fn read_and_call_id3_event(self, activation: &mut Activation<'_, 'gc>, bytes: &[u8]) { @@ -265,15 +277,15 @@ fn play_queued<'gc>( impl<'gc> TObject<'gc> for SoundObject<'gc> { fn base(&self) -> Ref> { - Ref::map(self.0.read(), |read| &read.base) + self.0.base.borrow() } fn base_mut(&self, mc: &Mutation<'gc>) -> RefMut> { - RefMut::map(self.0.write(mc), |write| &mut write.base) + unlock!(Gc::write(mc, self.0), SoundObjectData, base).borrow_mut() } fn as_ptr(&self) -> *const ObjectPtr { - self.0.as_ptr() as *const ObjectPtr + Gc::as_ptr(self.0) as *const ObjectPtr } fn value_of(&self, _mc: &Mutation<'gc>) -> Result, Error<'gc>> {