WuhuIslandTesting/Library/PackageCache/com.unity.addressables@1.21.12/Runtime/ResourceManager/Util/DelegateList.cs
2025-01-07 02:06:59 +01:00

121 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);
}
}