diff --git a/src/Audio/AudioDevice.cs b/src/Audio/AudioDevice.cs index c7371955..35036760 100644 --- a/src/Audio/AudioDevice.cs +++ b/src/Audio/AudioDevice.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading; namespace MoonWorks.Audio @@ -24,7 +25,7 @@ namespace MoonWorks.Audio public float DopplerScale = 1f; public float SpeedOfSound = 343.5f; - private readonly HashSet resources = new HashSet(); + private readonly HashSet resources = new HashSet(); private readonly HashSet activeSourceVoices = new HashSet(); private AudioTweenManager AudioTweenManager; @@ -251,24 +252,24 @@ namespace MoonWorks.Audio WakeSignal.Set(); } - internal void AddResourceReference(AudioResource resource) + internal void AddResourceReference(GCHandle resourceReference) { lock (StateLock) { - resources.Add(resource.weakReference); + resources.Add(resourceReference); - if (resource is SourceVoice voice) + if (resourceReference.Target is SourceVoice voice) { activeSourceVoices.Add(voice); } } } - internal void RemoveResourceReference(AudioResource resource) + internal void RemoveResourceReference(GCHandle resourceReference) { lock (StateLock) { - resources.Remove(resource.weakReference); + resources.Remove(resourceReference); } } @@ -282,24 +283,20 @@ namespace MoonWorks.Audio if (disposing) { // stop all source voices - foreach (var weakReference in resources) + foreach (var resource in resources) { - var target = weakReference.Target; - - if (target != null && target is SourceVoice voice) + if (resource.Target is SourceVoice voice) { voice.Stop(); } } // destroy all audio resources - foreach (var weakReference in resources) + foreach (var resource in resources) { - var target = weakReference.Target; - - if (target != null) + if (resource.Target is IDisposable disposable) { - (target as IDisposable).Dispose(); + disposable.Dispose(); } } diff --git a/src/Audio/AudioResource.cs b/src/Audio/AudioResource.cs index c8a1360c..4c8d4e92 100644 --- a/src/Audio/AudioResource.cs +++ b/src/Audio/AudioResource.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.InteropServices; namespace MoonWorks.Audio { @@ -8,30 +9,26 @@ namespace MoonWorks.Audio public bool IsDisposed { get; private set; } - internal WeakReference weakReference; + private GCHandle SelfReference; - public AudioResource(AudioDevice device) + protected AudioResource(AudioDevice device) { Device = device; - weakReference = new WeakReference(this); - Device.AddResourceReference(this); + SelfReference = GCHandle.Alloc(this, GCHandleType.Weak); + Device.AddResourceReference(SelfReference); } protected abstract void Destroy(); - protected virtual void Dispose(bool disposing) + protected void Dispose(bool disposing) { if (!IsDisposed) { Destroy(); - if (weakReference != null) - { - Device.RemoveResourceReference(this); - weakReference.Target = null; - weakReference = null; - } + Device.RemoveResourceReference(SelfReference); + SelfReference.Free(); IsDisposed = true; }