Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ObjectCollector.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 
6 namespace SiliconStudio.Core
7 {
8  /// <summary>
9  /// A struct to dispose <see cref="IDisposable"/>, <see cref="IReferencable"/> instances and allocated unmanaged memory.
10  /// </summary>
11  public struct ObjectCollector : IDisposable
12  {
13  private List<object> disposables;
14 
15  /// <summary>
16  /// Gets the number of elements to dispose.
17  /// </summary>
18  /// <value>The number of elements to dispose.</value>
19  public int Count
20  {
21  get { return disposables.Count; }
22  }
23 
24  /// <summary>
25  /// Disposes all object collected by this class and clear the list. The collector can still be used for collecting.
26  /// </summary>
27  /// <remarks>
28  /// To completely dispose this instance and avoid further dispose, use <see cref="Dispose"/> method instead.
29  /// </remarks>
30  public void Dispose()
31  {
32  if (disposables == null)
33  {
34  return;
35  }
36 
37  for (int i = disposables.Count - 1; i >= 0; i--)
38  {
39  var objectToDispose = disposables[i];
40  DisposeObject(objectToDispose);
41  disposables.RemoveAt(i);
42  }
43  disposables.Clear();
44  }
45 
46  public void EnsureValid()
47  {
48  if (disposables == null)
49  disposables = new List<object>();
50  }
51 
52  /// <summary>
53  /// 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.
54  /// </summary>
55  /// <param name="objectToDispose">To dispose.</param>
56  /// <exception cref="ArgumentException">If objectToDispose argument is not IDisposable or a valid memory pointer allocated by <see cref="Utilities.AllocateMemory"/></exception>
57  public T Add<T>(T objectToDispose)
58  {
59  if (!(objectToDispose is IDisposable || objectToDispose is IntPtr || objectToDispose is IReferencable))
60  throw new ArgumentException("Argument must be IDisposable, IReferenceable or IntPtr");
61 
62  // Check memory alignment
63  if (objectToDispose is IntPtr)
64  {
65  var memoryPtr = (IntPtr)(object)objectToDispose;
66  if (!Utilities.IsMemoryAligned(memoryPtr))
67  throw new ArgumentException("Memory pointer is invalid. Memory must have been allocated with Utilties.AllocateMemory");
68  }
69 
70  EnsureValid();
71 
72  if (!disposables.Contains(objectToDispose))
73  {
74  disposables.Add(objectToDispose);
75 
76  var referenceableObject = objectToDispose as IReferencable;
77  if (referenceableObject != null)
78  {
79  referenceableObject.AddReference();
80  }
81  }
82  return objectToDispose;
83  }
84 
85  /// <summary>
86  /// Dispose a disposable object and set the reference to null. Removes this object from this instance..
87  /// </summary>
88  /// <param name="objectToDispose">Object to dispose.</param>
89  public void RemoveAndDispose<T>(ref T objectToDispose)
90  {
91  if (disposables != null)
92  {
93  Remove(objectToDispose);
94  DisposeObject(objectToDispose);
95  objectToDispose = default(T);
96  }
97  }
98 
99  /// <summary>
100  /// Removes a disposable object to the list of the objects to dispose.
101  /// </summary>
102  /// <typeparam name="T"></typeparam>
103  /// <param name="objectToDispose">To dispose.</param>
104  public void Remove<T>(T objectToDispose)
105  {
106  if (disposables != null && disposables.Contains(objectToDispose))
107  {
108  disposables.Remove(objectToDispose);
109 
110  var referenceableObject = objectToDispose as IReferencable;
111  if (referenceableObject != null)
112  {
113  referenceableObject.Release();
114  }
115  }
116  }
117 
118  private void DisposeObject(object objectToDispose)
119  {
120  if (objectToDispose == null || objectToDispose is IReferencable)
121  {
122  return;
123  }
124 
125  var disposableObject = objectToDispose as IDisposable;
126  if (disposableObject != null)
127  {
128  disposableObject.Dispose();
129  }
130  else
131  {
132  var localData = (object)objectToDispose;
133  var dataPointer = (IntPtr)localData;
134  Utilities.FreeMemory(dataPointer);
135  }
136  }
137  }
138 }
Base interface for all referencable objects.
Definition: IReferencable.cs:8
static bool IsMemoryAligned(IntPtr memoryPtr, int align=16)
Determines whether the specified memory pointer is aligned in memory.
Definition: Utilities.cs:386
A struct to dispose IDisposable, IReferencable instances and allocated unmanaged memory.
void Dispose()
Disposes all object collected by this class and clear the list. The collector can still be used for c...