156 lines
5.9 KiB
C#
156 lines
5.9 KiB
C#
|
|
// Copyright (c) 2010-2018 SharpDX - Alexandre Mutel
|
|||
|
|
//
|
|||
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|||
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|||
|
|
// in the Software without restriction, including without limitation the rights
|
|||
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|||
|
|
// furnished to do so, subject to the following conditions:
|
|||
|
|
//
|
|||
|
|
// The above copyright notice and this permission notice shall be included in
|
|||
|
|
// all copies or substantial portions of the Software.
|
|||
|
|
//
|
|||
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|||
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|||
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
|
|
// THE SOFTWARE.
|
|||
|
|
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
|
|||
|
|
namespace SharpDX
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// A class to dispose <see cref="IDisposable"/> instances and allocated unmanaged memory.
|
|||
|
|
/// </summary>
|
|||
|
|
public class DisposeCollector : DisposeBase
|
|||
|
|
{
|
|||
|
|
private List<object> disposables;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Gets the number of elements to dispose.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <value>The number of elements to dispose.</value>
|
|||
|
|
public int Count
|
|||
|
|
{
|
|||
|
|
get { return disposables.Count; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Disposes all object collected by this class and clear the list. The collector can still be used for collecting.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="disposeManagedResources">If true, managed resources should be
|
|||
|
|
/// disposed of in addition to unmanaged resources.</param>
|
|||
|
|
/// <remarks>
|
|||
|
|
/// To completely dispose this instance and avoid further dispose, use <see cref="Dispose"/> method instead.
|
|||
|
|
/// </remarks>
|
|||
|
|
public void DisposeAndClear(bool disposeManagedResources = true)
|
|||
|
|
{
|
|||
|
|
if (disposables == null)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
for (int i = disposables.Count - 1; i >= 0; i--)
|
|||
|
|
{
|
|||
|
|
var valueToDispose = disposables[i];
|
|||
|
|
if (valueToDispose is IDisposable disposable)
|
|||
|
|
{
|
|||
|
|
if (disposeManagedResources)
|
|||
|
|
{
|
|||
|
|
disposable.Dispose();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
Utilities.FreeMemory((IntPtr)valueToDispose);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
disposables.RemoveAt(i);
|
|||
|
|
}
|
|||
|
|
disposables.Clear();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Disposes of object resources.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="disposeManagedResources">If true, managed resources should be
|
|||
|
|
/// disposed of in addition to unmanaged resources.</param>
|
|||
|
|
protected override void Dispose(bool disposeManagedResources)
|
|||
|
|
{
|
|||
|
|
DisposeAndClear(disposeManagedResources);
|
|||
|
|
disposables = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Adds a <see cref="IDisposable"/> object or a <see cref="IntPtr"/> allocated using <see cref="Utilities.AllocateMemory"/> to the list of the objects to dispose.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="toDispose">To dispose.</param>
|
|||
|
|
/// <exception cref="ArgumentException">If toDispose argument is not IDisposable or a valid memory pointer allocated by <see cref="Utilities.AllocateMemory"/></exception>
|
|||
|
|
public T Collect<T>(T toDispose)
|
|||
|
|
{
|
|||
|
|
if (!(toDispose is IDisposable || toDispose is IntPtr))
|
|||
|
|
throw new ArgumentException("Argument must be IDisposable or IntPtr");
|
|||
|
|
|
|||
|
|
// Check memory alignment
|
|||
|
|
if (toDispose is IntPtr)
|
|||
|
|
{
|
|||
|
|
var memoryPtr = (IntPtr)(object)toDispose;
|
|||
|
|
if (!Utilities.IsMemoryAligned(memoryPtr))
|
|||
|
|
throw new ArgumentException("Memory pointer is invalid. Memory must have been allocated with Utilties.AllocateMemory");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!Equals(toDispose, default(T)))
|
|||
|
|
{
|
|||
|
|
if (disposables == null)
|
|||
|
|
disposables = new List<object>();
|
|||
|
|
|
|||
|
|
if (!disposables.Contains(toDispose))
|
|||
|
|
{
|
|||
|
|
disposables.Add(toDispose);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return toDispose;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Dispose a disposable object and set the reference to null. Removes this object from this instance..
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="objectToDispose">Object to dispose.</param>
|
|||
|
|
public void RemoveAndDispose<T>(ref T objectToDispose)
|
|||
|
|
{
|
|||
|
|
if (disposables != null)
|
|||
|
|
{
|
|||
|
|
Remove(objectToDispose);
|
|||
|
|
|
|||
|
|
var disposableObject = objectToDispose as IDisposable;
|
|||
|
|
if (disposableObject != null)
|
|||
|
|
{
|
|||
|
|
// Dispose the component
|
|||
|
|
disposableObject.Dispose();
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
var localData = (object)objectToDispose;
|
|||
|
|
var dataPointer = (IntPtr) localData;
|
|||
|
|
Utilities.FreeMemory(dataPointer);
|
|||
|
|
}
|
|||
|
|
objectToDispose = default(T);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Removes a disposable object to the list of the objects to dispose.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <typeparam name="T"></typeparam>
|
|||
|
|
/// <param name="toDisposeArg">To dispose.</param>
|
|||
|
|
public void Remove<T>(T toDisposeArg)
|
|||
|
|
{
|
|||
|
|
if (disposables != null && disposables.Contains(toDisposeArg))
|
|||
|
|
{
|
|||
|
|
disposables.Remove(toDisposeArg);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|