Skip to content

Commit

Permalink
Implements standard IDispose pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
AristurtleDev committed May 30, 2024
1 parent 1119f82 commit 32653e7
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 30 deletions.
53 changes: 29 additions & 24 deletions source/MonoGame.Extended.Particles/ParticleBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public class ParticleBuffer : IDisposable
// points to the first memory pos after the buffer
protected readonly unsafe Particle* BufferEnd;

private bool _disposed;
// points to the particle after the last active particle.
protected unsafe Particle* Tail;

Expand Down Expand Up @@ -44,16 +43,28 @@ public unsafe ParticleBuffer(int size)
// total size of active particles
public int ActiveSizeInBytes => Particle.SizeInBytes*Count;

/// <summary>
/// Gets a value that indicates whether this instance of the <see cref="ParticleBuffer"/> class has been
/// disposed.
/// </summary>
public bool IsDisposed { get; set; }

public void Dispose()
{
if (!_disposed)
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if(IsDisposed)
{
Marshal.FreeHGlobal(_nativePointer);
_disposed = true;
GC.RemoveMemoryPressure(SizeInBytes);
return;
}

GC.SuppressFinalize(this);
Marshal.FreeHGlobal(_nativePointer);
GC.RemoveMemoryPressure(SizeInBytes);
IsDisposed = true;
}

/// <summary>
Expand All @@ -62,6 +73,8 @@ public void Dispose()
/// </summary>
public unsafe ParticleIterator Release(int releaseQuantity)
{
ThrowIfDisposed();

var numToRelease = Math.Min(releaseQuantity, Available);

var prevCount = Count;
Expand All @@ -75,34 +88,26 @@ public unsafe ParticleIterator Release(int releaseQuantity)

public unsafe void Reclaim(int number)
{
ThrowIfDisposed();

Count -= number;

Head += number;
if (Head >= BufferEnd)
Head -= Size + 1;
}

//public void CopyTo(IntPtr destination)
//{
// memcpy(destination, _nativePointer, ActiveSizeInBytes);
//}

//public void CopyToReverse(IntPtr destination)
//{
// var offset = 0;
// for (var i = ActiveSizeInBytes - Particle.SizeInBytes; i >= 0; i -= Particle.SizeInBytes)
// {
// memcpy(IntPtr.Add(destination, offset), IntPtr.Add(_nativePointer, i), Particle.SizeInBytes);
// offset += Particle.SizeInBytes;
// }
//}

//[DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
//public static extern void memcpy(IntPtr dest, IntPtr src, int count);
private void ThrowIfDisposed()
{
if(IsDisposed)
{
throw new ObjectDisposedException(nameof(ParticleBuffer));
}
}

~ParticleBuffer()
{
Dispose();
Dispose(false);
}

public class ParticleIterator
Expand Down
44 changes: 42 additions & 2 deletions source/MonoGame.Extended.Particles/ParticleEffect.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json;
using Microsoft.Xna.Framework;
using MonoGame.Extended.Particles.Serialization;
Expand All @@ -17,16 +19,42 @@ public ParticleEffect(string name = null)
Emitters = new List<ParticleEmitter>();
}

~ParticleEffect() => Dispose(false);

public void Dispose()
{
foreach (var emitter in Emitters)
emitter.Dispose();
Dispose(true);
GC.SuppressFinalize(this);
}

private void Dispose(bool disposing)
{
if(IsDisposed)
{
return;
}

if(disposing)
{
foreach(var emitter in Emitters)
{
emitter.Dispose();
}
}

IsDisposed = true;
}

public string Name { get; set; }
public List<ParticleEmitter> Emitters { get; set; }
public int ActiveParticles => Emitters.Sum(t => t.ActiveParticles);

/// <summary>
/// Gets a value that indicates whether this instance of the <see cref="ParticleEffect"/> class has been
/// disposed.
/// </summary>
public bool IsDisposed { get; private set; }

public void FastForward(Vector2 position, float seconds, float triggerPeriod)
{
var time = 0f;
Expand Down Expand Up @@ -54,6 +82,8 @@ public static ParticleEffect FromStream(ITextureRegionService textureRegionServi

public void Update(float elapsedSeconds)
{
ThrowIfDisposed();

for (var i = 0; i < Emitters.Count; i++)
Emitters[i].Update(elapsedSeconds, Position);
}
Expand All @@ -65,16 +95,26 @@ public void Trigger()

public void Trigger(Vector2 position, float layerDepth = 0)
{
ThrowIfDisposed();
for (var i = 0; i < Emitters.Count; i++)
Emitters[i].Trigger(position, layerDepth);
}

public void Trigger(LineSegment line, float layerDepth = 0)
{
ThrowIfDisposed();
for (var i = 0; i < Emitters.Count; i++)
Emitters[i].Trigger(line, layerDepth);
}

private void ThrowIfDisposed()
{
if(IsDisposed)
{
throw new ObjectDisposedException(nameof(ParticleBuffer));
}
}

public override string ToString()
{
return Name;
Expand Down
42 changes: 39 additions & 3 deletions source/MonoGame.Extended.Particles/ParticleEmitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,25 @@ public ParticleEmitter(TextureRegion2D textureRegion, int capacity, TimeSpan lif

public void Dispose()
{
Buffer.Dispose();
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if(IsDisposed)
{
return;
}

Buffer.Dispose();
Buffer = null;
IsDisposed = true;
}

~ParticleEmitter()
{
Dispose();
Dispose(false);
}

public string Name { get; set; }
Expand All @@ -57,16 +69,28 @@ public void Dispose()
public ParticleReleaseParameters Parameters { get; set; }
public TextureRegion2D TextureRegion { get; set; }

/// <summary>
/// Gets a value that indicates whether this instance of the <see cref="ParticleEmitter"/> class has been
/// disposed.
/// </summary>
public bool IsDisposed { get; private set;}

[EditorBrowsable(EditorBrowsableState.Never)]
public ParticleModifierExecutionStrategy ModifierExecutionStrategy { get; set; }

internal ParticleBuffer Buffer;

public int Capacity
{
get { return Buffer.Size; }
get
{
ThrowIfDisposed();
return Buffer.Size;
}
set
{
ThrowIfDisposed();

var oldBuffer = Buffer;
oldBuffer.Dispose();
Buffer = new ParticleBuffer(value);
Expand Down Expand Up @@ -125,6 +149,8 @@ private void ReclaimExpiredParticles()

public bool Update(float elapsedSeconds, Vector2 position = default(Vector2))
{
ThrowIfDisposed();

_totalSeconds += elapsedSeconds;

if (_autoTrigger)
Expand Down Expand Up @@ -176,6 +202,8 @@ public void Trigger(LineSegment line, float layerDepth = 0)

private void Release(Vector2 position, int numToRelease, float layerDepth)
{
ThrowIfDisposed();

var iterator = Buffer.Release(numToRelease);

while (iterator.HasNext)
Expand Down Expand Up @@ -214,6 +242,14 @@ private void Release(Vector2 position, int numToRelease, float layerDepth)
}
}

private void ThrowIfDisposed()
{
if(IsDisposed)
{
throw new ObjectDisposedException(nameof(ParticleBuffer));
}
}

public override string ToString()
{
return Name;
Expand Down
12 changes: 11 additions & 1 deletion source/MonoGame.Extended.Particles/ParticleExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,22 @@ public static class ParticleExtensions
{
public static void Draw(this SpriteBatch spriteBatch, ParticleEffect effect)
{
if(effect.IsDisposed)
{
return;
}

for (var i = 0; i < effect.Emitters.Count; i++)
UnsafeDraw(spriteBatch, effect.Emitters[i]);
}

public static void Draw(this SpriteBatch spriteBatch, ParticleEmitter emitter)
{
if(emitter.IsDisposed)
{
return;
}

UnsafeDraw(spriteBatch, emitter);
}

Expand Down Expand Up @@ -46,4 +56,4 @@ private static unsafe void UnsafeDraw(SpriteBatch spriteBatch, ParticleEmitter e
}
}
}
}
}

0 comments on commit 32653e7

Please sign in to comment.