update coffee.internal
parent
626e24b04b
commit
8f1013085a
|
@ -13,13 +13,15 @@ namespace Coffee.UIParticleInternal
|
||||||
{
|
{
|
||||||
public abstract class PreloadedProjectSettings : ScriptableObject
|
public abstract class PreloadedProjectSettings : ScriptableObject
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
, IPreprocessBuildWithReport
|
|
||||||
{
|
{
|
||||||
int IOrderedCallback.callbackOrder => 0;
|
private class PreprocessBuildWithReport : IPreprocessBuildWithReport
|
||||||
|
|
||||||
void IPreprocessBuildWithReport.OnPreprocessBuild(BuildReport report)
|
|
||||||
{
|
{
|
||||||
Initialize();
|
int IOrderedCallback.callbackOrder => 0;
|
||||||
|
|
||||||
|
void IPreprocessBuildWithReport.OnPreprocessBuild(BuildReport report)
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[InitializeOnLoadMethod]
|
[InitializeOnLoadMethod]
|
||||||
|
|
|
@ -5,6 +5,7 @@ using Object = UnityEngine.Object;
|
||||||
#if ENABLE_COFFEE_LOGGER
|
#if ENABLE_COFFEE_LOGGER
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
using Conditional = System.Diagnostics.ConditionalAttribute;
|
using Conditional = System.Diagnostics.ConditionalAttribute;
|
||||||
#endif
|
#endif
|
||||||
|
@ -140,6 +141,9 @@ namespace Coffee.UIParticleInternal
|
||||||
|
|
||||||
switch (tag)
|
switch (tag)
|
||||||
{
|
{
|
||||||
|
case string name:
|
||||||
|
sb.Append(name);
|
||||||
|
break;
|
||||||
case Type type:
|
case Type type:
|
||||||
AppendType(sb, type);
|
AppendType(sb, type);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -8,10 +8,11 @@ namespace Coffee.UIParticleInternal
|
||||||
{
|
{
|
||||||
internal class ObjectRepository<T> where T : Object
|
internal class ObjectRepository<T> where T : Object
|
||||||
{
|
{
|
||||||
private readonly List<Entry> _cache = new List<Entry>();
|
private readonly Dictionary<Hash128, Entry> _cache = new Dictionary<Hash128, Entry>(8);
|
||||||
|
private readonly Dictionary<int, Hash128> _objectKey = new Dictionary<int, Hash128>(8);
|
||||||
private readonly string _name;
|
private readonly string _name;
|
||||||
private readonly Action<T> _onRelease;
|
private readonly Action<T> _onRelease;
|
||||||
private readonly Stack<Entry> _pool = new Stack<Entry>();
|
private readonly Stack<Entry> _pool = new Stack<Entry>(8);
|
||||||
|
|
||||||
public ObjectRepository(Action<T> onRelease = null)
|
public ObjectRepository(Action<T> onRelease = null)
|
||||||
{
|
{
|
||||||
|
@ -36,40 +37,33 @@ namespace Coffee.UIParticleInternal
|
||||||
{
|
{
|
||||||
_onRelease = onRelease;
|
_onRelease = onRelease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
_pool.Push(new Entry());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int count => _cache.Count;
|
public int count => _cache.Count;
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
for (var i = 0; i < _cache.Count; i++)
|
foreach (var kv in _cache)
|
||||||
{
|
{
|
||||||
var entry = _cache[i];
|
var entry = kv.Value;
|
||||||
if (entry == null) continue;
|
if (entry == null) continue;
|
||||||
|
|
||||||
entry.Release(_onRelease);
|
entry.Release(_onRelease);
|
||||||
|
_pool.Push(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
_cache.Clear();
|
_cache.Clear();
|
||||||
|
_objectKey.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Valid(Hash128 hash, T obj)
|
public bool Valid(Hash128 hash, T obj)
|
||||||
{
|
{
|
||||||
// Find existing entry.
|
return _cache.TryGetValue(hash, out var entry) && entry.storedObject == obj;
|
||||||
Profiler.BeginSample("(COF)[ObjectRepository] Valid > Find existing entry");
|
|
||||||
for (var i = 0; i < _cache.Count; ++i)
|
|
||||||
{
|
|
||||||
var entry = _cache[i];
|
|
||||||
if (entry.hash != hash) continue;
|
|
||||||
Profiler.EndSample();
|
|
||||||
|
|
||||||
// Existing entry found.
|
|
||||||
return entry.storedObject == obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
Profiler.EndSample();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -77,41 +71,8 @@ namespace Coffee.UIParticleInternal
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Get(Hash128 hash, ref T obj, Func<T> onCreate)
|
public void Get(Hash128 hash, ref T obj, Func<T> onCreate)
|
||||||
{
|
{
|
||||||
// Find existing entry.
|
if (GetFromCache(hash, ref obj)) return;
|
||||||
Profiler.BeginSample("(COF)[ObjectRepository] Get > Find existing entry");
|
Add(hash, ref obj, onCreate());
|
||||||
for (var i = 0; i < _cache.Count; ++i)
|
|
||||||
{
|
|
||||||
var entry = _cache[i];
|
|
||||||
if (entry.hash != hash) continue;
|
|
||||||
|
|
||||||
// Existing entry found.
|
|
||||||
if (entry.storedObject != obj)
|
|
||||||
{
|
|
||||||
// if the object is different, release the old one.
|
|
||||||
Release(ref obj);
|
|
||||||
++entry.reference;
|
|
||||||
obj = entry.storedObject;
|
|
||||||
Logging.Log(_name, $"Get(#{count}): {entry}");
|
|
||||||
}
|
|
||||||
|
|
||||||
Profiler.EndSample();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Profiler.EndSample();
|
|
||||||
|
|
||||||
// Create new entry.
|
|
||||||
Profiler.BeginSample("(COF)[ObjectRepository] Get > Create new entry");
|
|
||||||
var newEntry = 0 < _pool.Count ? _pool.Pop() : new Entry();
|
|
||||||
newEntry.storedObject = onCreate();
|
|
||||||
newEntry.hash = hash;
|
|
||||||
newEntry.reference = 1;
|
|
||||||
_cache.Add(newEntry);
|
|
||||||
Logging.Log(_name, $"Get(#{count}): {newEntry}");
|
|
||||||
|
|
||||||
Release(ref obj);
|
|
||||||
obj = newEntry.storedObject;
|
|
||||||
Profiler.EndSample();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -119,40 +80,60 @@ namespace Coffee.UIParticleInternal
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Get<TS>(Hash128 hash, ref T obj, Func<TS, T> onCreate, TS source)
|
public void Get<TS>(Hash128 hash, ref T obj, Func<TS, T> onCreate, TS source)
|
||||||
{
|
{
|
||||||
// Find existing entry.
|
if (GetFromCache(hash, ref obj)) return;
|
||||||
Profiler.BeginSample("(COF)[ObjectRepository] Get > Find existing entry");
|
Add(hash, ref obj, onCreate(source));
|
||||||
for (var i = 0; i < _cache.Count; ++i)
|
}
|
||||||
{
|
|
||||||
var entry = _cache[i];
|
private bool GetFromCache(Hash128 hash, ref T obj)
|
||||||
if (entry.hash != hash) continue;
|
{
|
||||||
|
// Find existing entry.
|
||||||
|
Profiler.BeginSample("(COF)[ObjectRepository] GetFromCache");
|
||||||
|
if (_cache.TryGetValue(hash, out var entry))
|
||||||
|
{
|
||||||
|
if (!entry.storedObject)
|
||||||
|
{
|
||||||
|
Release(ref entry.storedObject);
|
||||||
|
Profiler.EndSample();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Existing entry found.
|
|
||||||
if (entry.storedObject != obj)
|
if (entry.storedObject != obj)
|
||||||
{
|
{
|
||||||
// if the object is different, release the old one.
|
// if the object is different, release the old one.
|
||||||
Release(ref obj);
|
Release(ref obj);
|
||||||
++entry.reference;
|
++entry.reference;
|
||||||
obj = entry.storedObject;
|
obj = entry.storedObject;
|
||||||
Logging.Log(_name, $"Get(#{count}): {entry}");
|
Logging.Log(_name, $"Get(total#{count}): {entry}");
|
||||||
}
|
}
|
||||||
|
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Create new entry.
|
private void Add(Hash128 hash, ref T obj, T newObject)
|
||||||
Profiler.BeginSample("(COF)[ObjectRepository] Get > Create new entry");
|
{
|
||||||
|
if (!newObject)
|
||||||
|
{
|
||||||
|
Release(ref obj);
|
||||||
|
obj = newObject;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and add a new entry.
|
||||||
|
Profiler.BeginSample("(COF)[ObjectRepository] Add");
|
||||||
var newEntry = 0 < _pool.Count ? _pool.Pop() : new Entry();
|
var newEntry = 0 < _pool.Count ? _pool.Pop() : new Entry();
|
||||||
newEntry.storedObject = onCreate(source);
|
newEntry.storedObject = newObject;
|
||||||
newEntry.hash = hash;
|
newEntry.hash = hash;
|
||||||
newEntry.reference = 1;
|
newEntry.reference = 1;
|
||||||
_cache.Add(newEntry);
|
_cache[hash] = newEntry;
|
||||||
Logging.Log(_name, $"Get(#{count}): {newEntry}");
|
_objectKey[newObject.GetInstanceID()] = hash;
|
||||||
|
Logging.Log(_name, $"<color=#03c700>Add</color>(total#{count}): {newEntry}");
|
||||||
Release(ref obj);
|
Release(ref obj);
|
||||||
obj = newEntry.storedObject;
|
obj = newObject;
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,35 +144,45 @@ namespace Coffee.UIParticleInternal
|
||||||
{
|
{
|
||||||
if (ReferenceEquals(obj, null)) return;
|
if (ReferenceEquals(obj, null)) return;
|
||||||
|
|
||||||
|
// Find and release the entry.
|
||||||
Profiler.BeginSample("(COF)[ObjectRepository] Release");
|
Profiler.BeginSample("(COF)[ObjectRepository] Release");
|
||||||
for (var i = 0; i < _cache.Count; i++)
|
var id = obj.GetInstanceID();
|
||||||
|
if (_objectKey.TryGetValue(id, out var hash)
|
||||||
|
&& _cache.TryGetValue(hash, out var entry))
|
||||||
{
|
{
|
||||||
var entry = _cache[i];
|
entry.reference--;
|
||||||
|
if (entry.reference <= 0 || !entry.storedObject)
|
||||||
if (entry.storedObject != obj)
|
|
||||||
{
|
{
|
||||||
continue;
|
Remove(entry);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (--entry.reference <= 0)
|
|
||||||
{
|
{
|
||||||
Profiler.BeginSample("(COF)[ObjectRepository] Release > RemoveAt");
|
Logging.Log(_name, $"Release(total#{_cache.Count}): {entry}");
|
||||||
_cache.RemoveAtFast(i);
|
|
||||||
Logging.Log(_name, $"Release(#{_cache.Count}): {entry}");
|
|
||||||
entry.Release(_onRelease);
|
|
||||||
_pool.Push(entry);
|
|
||||||
Profiler.EndSample();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Logging.Log(_name, $"Release(#{count}): {entry}");
|
else
|
||||||
break;
|
{
|
||||||
|
Logging.Log(_name, $"Release(total#{_cache.Count}): <color=red>Already released: {obj}</color>");
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = null;
|
obj = null;
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Remove(Entry entry)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(entry, null)) return;
|
||||||
|
|
||||||
|
Profiler.BeginSample("(COF)[ObjectRepository] Remove");
|
||||||
|
_cache.Remove(entry.hash);
|
||||||
|
_objectKey.Remove(entry.storedObject.GetInstanceID());
|
||||||
|
_pool.Push(entry);
|
||||||
|
entry.reference = 0;
|
||||||
|
Logging.Log(_name, $"<color=#f29e03>Remove</color>(total#{_cache.Count}): {entry}");
|
||||||
|
entry.Release(_onRelease);
|
||||||
|
Profiler.EndSample();
|
||||||
|
}
|
||||||
|
|
||||||
private class Entry
|
private class Entry
|
||||||
{
|
{
|
||||||
public Hash128 hash;
|
public Hash128 hash;
|
||||||
|
@ -211,7 +202,7 @@ namespace Coffee.UIParticleInternal
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"h{(uint)hash.GetHashCode()} (#{reference}), {storedObject}";
|
return $"h{(uint)hash.GetHashCode()} (refs#{reference}), {storedObject}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue