agrobot_base/Exemplos/SharpDX-master/Source/SharpDX/DisposeCollector.cs

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);
}
}
}
}