change AudioResource WeakRef to GCHandle

cosmonaut 2023-11-20 17:52:44 -08:00
parent a736ed031d
commit 40fb313d12
2 changed files with 20 additions and 26 deletions

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
namespace MoonWorks.Audio namespace MoonWorks.Audio
@ -24,7 +25,7 @@ namespace MoonWorks.Audio
public float DopplerScale = 1f; public float DopplerScale = 1f;
public float SpeedOfSound = 343.5f; public float SpeedOfSound = 343.5f;
private readonly HashSet<WeakReference> resources = new HashSet<WeakReference>(); private readonly HashSet<GCHandle> resources = new HashSet<GCHandle>();
private readonly HashSet<SourceVoice> activeSourceVoices = new HashSet<SourceVoice>(); private readonly HashSet<SourceVoice> activeSourceVoices = new HashSet<SourceVoice>();
private AudioTweenManager AudioTweenManager; private AudioTweenManager AudioTweenManager;
@ -251,24 +252,24 @@ namespace MoonWorks.Audio
WakeSignal.Set(); WakeSignal.Set();
} }
internal void AddResourceReference(AudioResource resource) internal void AddResourceReference(GCHandle resourceReference)
{ {
lock (StateLock) lock (StateLock)
{ {
resources.Add(resource.weakReference); resources.Add(resourceReference);
if (resource is SourceVoice voice) if (resourceReference.Target is SourceVoice voice)
{ {
activeSourceVoices.Add(voice); activeSourceVoices.Add(voice);
} }
} }
} }
internal void RemoveResourceReference(AudioResource resource) internal void RemoveResourceReference(GCHandle resourceReference)
{ {
lock (StateLock) lock (StateLock)
{ {
resources.Remove(resource.weakReference); resources.Remove(resourceReference);
} }
} }
@ -282,24 +283,20 @@ namespace MoonWorks.Audio
if (disposing) if (disposing)
{ {
// stop all source voices // stop all source voices
foreach (var weakReference in resources) foreach (var resource in resources)
{ {
var target = weakReference.Target; if (resource.Target is SourceVoice voice)
if (target != null && target is SourceVoice voice)
{ {
voice.Stop(); voice.Stop();
} }
} }
// destroy all audio resources // destroy all audio resources
foreach (var weakReference in resources) foreach (var resource in resources)
{ {
var target = weakReference.Target; if (resource.Target is IDisposable disposable)
if (target != null)
{ {
(target as IDisposable).Dispose(); disposable.Dispose();
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Runtime.InteropServices;
namespace MoonWorks.Audio namespace MoonWorks.Audio
{ {
@ -8,30 +9,26 @@ namespace MoonWorks.Audio
public bool IsDisposed { get; private set; } public bool IsDisposed { get; private set; }
internal WeakReference weakReference; private GCHandle SelfReference;
public AudioResource(AudioDevice device) protected AudioResource(AudioDevice device)
{ {
Device = device; Device = device;
weakReference = new WeakReference(this); SelfReference = GCHandle.Alloc(this, GCHandleType.Weak);
Device.AddResourceReference(this); Device.AddResourceReference(SelfReference);
} }
protected abstract void Destroy(); protected abstract void Destroy();
protected virtual void Dispose(bool disposing) protected void Dispose(bool disposing)
{ {
if (!IsDisposed) if (!IsDisposed)
{ {
Destroy(); Destroy();
if (weakReference != null) Device.RemoveResourceReference(SelfReference);
{ SelfReference.Free();
Device.RemoveResourceReference(this);
weakReference.Target = null;
weakReference = null;
}
IsDisposed = true; IsDisposed = true;
} }