soundvision/UnityProject/Assets/ThridParty/KinectScript/NativeObjectCache.cs
2019-07-06 14:50:40 +02:00

136 lines
No EOL
4.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Linq;
namespace Helper
{
public static class NativeObjectCache
{
private static object _lock = new object();
private static Dictionary<Type, Dictionary<IntPtr, WeakReference>> _objectCache = new Dictionary<Type, Dictionary<IntPtr, WeakReference>>();
public static void AddObject<T>(IntPtr nativePtr, T obj) where T : class
{
lock (_lock)
{
Dictionary<IntPtr, WeakReference> objCache = null;
if (!_objectCache.TryGetValue(typeof(T), out objCache) || objCache == null)
{
objCache = new Dictionary<IntPtr, WeakReference>();
_objectCache[typeof(T)] = objCache;
}
objCache[nativePtr] = new WeakReference(obj);
}
}
public static void Flush()
{
lock(_lock)
{
foreach (var byType in _objectCache.ToArray())
{
foreach(var kvp in byType.Value.ToArray())
{
IDisposable disp = kvp.Value.Target as IDisposable;
if(disp != null)
{
disp.Dispose();
}
}
}
}
}
public static void RemoveObject<T>(IntPtr nativePtr)
{
lock (_lock)
{
Dictionary<IntPtr, WeakReference> objCache = null;
if (!_objectCache.TryGetValue(typeof(T), out objCache) || objCache == null)
{
objCache = new Dictionary<IntPtr, WeakReference>();
_objectCache[typeof(T)] = objCache;
}
if (objCache.ContainsKey(nativePtr))
{
objCache.Remove(nativePtr);
}
}
}
public static T GetObject<T>(IntPtr nativePtr) where T : class
{
lock (_lock)
{
Dictionary<IntPtr, WeakReference> objCache = null;
if (!_objectCache.TryGetValue(typeof(T), out objCache) || objCache == null)
{
objCache = new Dictionary<IntPtr, WeakReference>();
_objectCache[typeof(T)] = objCache;
}
WeakReference reference = null;
if (objCache.TryGetValue(nativePtr, out reference))
{
if (reference != null)
{
T obj = reference.Target as T;
if (obj != null)
{
return (T)obj;
}
}
}
return null;
}
}
public static T CreateOrGetObject<T>(IntPtr nativePtr, Func<System.IntPtr,T> create) where T : class
{
T outputValue = null;
lock (_lock)
{
Dictionary<IntPtr, WeakReference> objCache = null;
if (!_objectCache.TryGetValue(typeof(T), out objCache) || objCache == null)
{
objCache = new Dictionary<IntPtr, WeakReference>();
_objectCache[typeof(T)] = objCache;
}
WeakReference reference = null;
if (objCache.TryGetValue(nativePtr, out reference))
{
if ((reference != null) && reference.IsAlive)
{
outputValue = reference.Target as T;
}
}
if (outputValue == null)
{
if (create != null)
{
outputValue = create(nativePtr);
objCache[nativePtr] = new WeakReference(outputValue);
}
else if(typeof(T) == typeof(System.Object))
{
//T is an object, so lets just pass back our IntPtr, which is an object.
outputValue = (T)(System.Object)nativePtr;
}
}
}
return outputValue;
}
}
}