122 lines
3 KiB
C#
122 lines
3 KiB
C#
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine.ResourceManagement.Util;
|
||
|
|
||
|
internal class DelegateList<T>
|
||
|
{
|
||
|
Func<Action<T>, LinkedListNode<Action<T>>> m_acquireFunc;
|
||
|
Action<LinkedListNode<Action<T>>> m_releaseFunc;
|
||
|
LinkedList<Action<T>> m_callbacks;
|
||
|
bool m_invoking = false;
|
||
|
|
||
|
public DelegateList(Func<Action<T>, LinkedListNode<Action<T>>> acquireFunc, Action<LinkedListNode<Action<T>>> releaseFunc)
|
||
|
{
|
||
|
if (acquireFunc == null)
|
||
|
throw new ArgumentNullException("acquireFunc");
|
||
|
if (releaseFunc == null)
|
||
|
throw new ArgumentNullException("releaseFunc");
|
||
|
m_acquireFunc = acquireFunc;
|
||
|
m_releaseFunc = releaseFunc;
|
||
|
}
|
||
|
|
||
|
public int Count
|
||
|
{
|
||
|
get { return m_callbacks == null ? 0 : m_callbacks.Count; }
|
||
|
}
|
||
|
|
||
|
public void Add(Action<T> action)
|
||
|
{
|
||
|
var node = m_acquireFunc(action);
|
||
|
if (m_callbacks == null)
|
||
|
m_callbacks = new LinkedList<Action<T>>();
|
||
|
m_callbacks.AddLast(node);
|
||
|
}
|
||
|
|
||
|
public void Remove(Action<T> action)
|
||
|
{
|
||
|
if (m_callbacks == null)
|
||
|
return;
|
||
|
|
||
|
var node = m_callbacks.First;
|
||
|
while (node != null)
|
||
|
{
|
||
|
if (node.Value == action)
|
||
|
{
|
||
|
if (m_invoking)
|
||
|
{
|
||
|
node.Value = null;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_callbacks.Remove(node);
|
||
|
m_releaseFunc(node);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
node = node.Next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void Invoke(T res)
|
||
|
{
|
||
|
if (m_callbacks == null)
|
||
|
return;
|
||
|
|
||
|
m_invoking = true;
|
||
|
var node = m_callbacks.First;
|
||
|
while (node != null)
|
||
|
{
|
||
|
if (node.Value != null)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
node.Value(res);
|
||
|
}
|
||
|
catch (Exception ex)
|
||
|
{
|
||
|
UnityEngine.Debug.LogException(ex);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
node = node.Next;
|
||
|
}
|
||
|
|
||
|
m_invoking = false;
|
||
|
var r = m_callbacks.First;
|
||
|
while (r != null)
|
||
|
{
|
||
|
var next = r.Next;
|
||
|
if (r.Value == null)
|
||
|
{
|
||
|
m_callbacks.Remove(r);
|
||
|
m_releaseFunc(r);
|
||
|
}
|
||
|
|
||
|
r = next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void Clear()
|
||
|
{
|
||
|
if (m_callbacks == null)
|
||
|
return;
|
||
|
var node = m_callbacks.First;
|
||
|
while (node != null)
|
||
|
{
|
||
|
var next = node.Next;
|
||
|
m_callbacks.Remove(node);
|
||
|
m_releaseFunc(node);
|
||
|
node = next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static DelegateList<T> CreateWithGlobalCache()
|
||
|
{
|
||
|
if (!GlobalLinkedListNodeCache<Action<T>>.CacheExists)
|
||
|
GlobalLinkedListNodeCache<Action<T>>.SetCacheSize(32);
|
||
|
return new DelegateList<T>(GlobalLinkedListNodeCache<Action<T>>.Acquire, GlobalLinkedListNodeCache<Action<T>>.Release);
|
||
|
}
|
||
|
}
|