using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace Urho
{
///
///
internal class RefCountedCache
{
Dictionary> knownObjects = new Dictionary>(256); //based on samples (average)
public int Count => knownObjects.Count;
public void Add(RefCounted refCounted)
{
lock (knownObjects)
{
ReferenceHolder knownObject;
if (knownObjects.TryGetValue(refCounted.Handle, out knownObject))
{
knownObject?.Reference?.Dispose();
}
knownObjects[refCounted.Handle] = new ReferenceHolder(refCounted, weak: refCounted.Refs() < 1 && !StrongRefByDefault(refCounted));
}
}
public bool Remove(IntPtr ptr)
{
lock (knownObjects)
{
return knownObjects.Remove(ptr);
}
}
public ReferenceHolder Get(IntPtr ptr)
{
lock (knownObjects)
{
ReferenceHolder refCounted;
knownObjects.TryGetValue(ptr, out refCounted);
return refCounted;
}
}
public void Clean()
{
IntPtr[] handles;
lock (knownObjects)
handles = knownObjects.OrderBy(t => GetDisposePriority(t.Value)).Select(t => t.Key).ToArray();
foreach (var handle in handles)
{
ReferenceHolder refHolder;
lock (knownObjects)
knownObjects.TryGetValue(handle, out refHolder);
refHolder?.Reference?.Dispose();
}
LogSharp.Warn($"RefCountedCache objects alive: {knownObjects.Count}");
//knownObjects.Clear();
}
int GetDisposePriority(ReferenceHolder refHolder)
{
const int defaulPriority = 1000;
var obj = refHolder?.Reference;
if (obj == null)
return defaulPriority;
if (obj is Scene)
return 1;
//TODO:
return defaulPriority;
}
bool StrongRefByDefault(RefCounted refCounted)
{
if (refCounted is Scene)
return true;
return false;
}
}
}