准备更新BP
This commit is contained in:
@@ -1,4 +1,7 @@
|
|||||||
|
using Convention.Collections;
|
||||||
|
using Convention.Collections.Generic;
|
||||||
using Convention.Experimental.PublicType;
|
using Convention.Experimental.PublicType;
|
||||||
|
using Convention.ReferenceManagement;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|||||||
11
Convention/[Architecture]/Modules/ActionManager.cs.meta
Normal file
11
Convention/[Architecture]/Modules/ActionManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d8ac4985ed7261b4eb47642f5a27a1f5
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -7,449 +7,4 @@ using UnityEngine;
|
|||||||
namespace Convention.Experimental.PublicType
|
namespace Convention.Experimental.PublicType
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 附带有缓存机制的链表类。
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">指定链表的元素类型。</typeparam>
|
|
||||||
public sealed class LinkedCacheList<T> : ICollection<T>, IEnumerable<T>, ICollection, IEnumerable
|
|
||||||
{
|
|
||||||
private readonly LinkedList<T> m_LinkedList;
|
|
||||||
/// <summary>
|
|
||||||
/// 之所以需要这套缓存机制,主要有三点好处:
|
|
||||||
/// <list type="bullet">减少 GC 压力:大量频繁的插入/删除会产生很多短生命周期的节点对象,通过复用可以显著降低托管堆的分配与回收次数</list>
|
|
||||||
/// <list type="bullet">提升性能:避免频繁 new 和 GC,能减少停顿时间,提高链表在高频操作场景下的吞吐</list>
|
|
||||||
/// <list type="bullet">便于观察与管理:类中还提供了 CachedNodeCount 方便调试统计缓存规模,必要时可通过 ClearCachedNodes 主动释放</list>
|
|
||||||
/// 适用场景是节点使用模式“高频增删但总量有限”,此时缓存能稳定性能;若链表规模始终在增长且很少释放,缓存收益会较低。
|
|
||||||
/// </summary>
|
|
||||||
private readonly Queue<LinkedListNode<T>> m_CachedNodes;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化游戏框架链表类的新实例。
|
|
||||||
/// </summary>
|
|
||||||
public LinkedCacheList()
|
|
||||||
{
|
|
||||||
m_LinkedList = new LinkedList<T>();
|
|
||||||
m_CachedNodes = new Queue<LinkedListNode<T>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取链表中实际包含的结点数量。
|
|
||||||
/// </summary>
|
|
||||||
public int Count
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_LinkedList.Count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取链表结点缓存数量。
|
|
||||||
/// </summary>
|
|
||||||
public int CachedNodeCount
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_CachedNodes.Count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取链表的第一个结点。
|
|
||||||
/// </summary>
|
|
||||||
public LinkedListNode<T> First
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_LinkedList.First;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取链表的最后一个结点。
|
|
||||||
/// </summary>
|
|
||||||
public LinkedListNode<T> Last
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_LinkedList.Last;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取一个值,该值指示 ICollection`1 是否为只读。
|
|
||||||
/// </summary>
|
|
||||||
public bool IsReadOnly
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return ((ICollection<T>)m_LinkedList).IsReadOnly;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取可用于同步对 ICollection 的访问的对象。
|
|
||||||
/// </summary>
|
|
||||||
public object SyncRoot
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return ((ICollection)m_LinkedList).SyncRoot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取一个值,该值指示是否同步对 ICollection 的访问(线程安全)。
|
|
||||||
/// </summary>
|
|
||||||
public bool IsSynchronized
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return ((ICollection)m_LinkedList).IsSynchronized;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在链表中指定的现有结点后添加包含指定值的新结点。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="node">指定的现有结点。</param>
|
|
||||||
/// <param name="value">指定值。</param>
|
|
||||||
/// <returns>包含指定值的新结点。</returns>
|
|
||||||
public LinkedListNode<T> AddAfter(LinkedListNode<T> node, T value)
|
|
||||||
{
|
|
||||||
LinkedListNode<T> newNode = AcquireNode(value);
|
|
||||||
m_LinkedList.AddAfter(node, newNode);
|
|
||||||
return newNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在链表中指定的现有结点后添加指定的新结点。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="node">指定的现有结点。</param>
|
|
||||||
/// <param name="newNode">指定的新结点。</param>
|
|
||||||
public void AddAfter(LinkedListNode<T> node, LinkedListNode<T> newNode)
|
|
||||||
{
|
|
||||||
m_LinkedList.AddAfter(node, newNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在链表中指定的现有结点前添加包含指定值的新结点。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="node">指定的现有结点。</param>
|
|
||||||
/// <param name="value">指定值。</param>
|
|
||||||
/// <returns>包含指定值的新结点。</returns>
|
|
||||||
public LinkedListNode<T> AddBefore(LinkedListNode<T> node, T value)
|
|
||||||
{
|
|
||||||
LinkedListNode<T> newNode = AcquireNode(value);
|
|
||||||
m_LinkedList.AddBefore(node, newNode);
|
|
||||||
return newNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在链表中指定的现有结点前添加指定的新结点。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="node">指定的现有结点。</param>
|
|
||||||
/// <param name="newNode">指定的新结点。</param>
|
|
||||||
public void AddBefore(LinkedListNode<T> node, LinkedListNode<T> newNode)
|
|
||||||
{
|
|
||||||
m_LinkedList.AddBefore(node, newNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在链表的开头处添加包含指定值的新结点。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">指定值。</param>
|
|
||||||
/// <returns>包含指定值的新结点。</returns>
|
|
||||||
public LinkedListNode<T> AddFirst(T value)
|
|
||||||
{
|
|
||||||
LinkedListNode<T> node = AcquireNode(value);
|
|
||||||
m_LinkedList.AddFirst(node);
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在链表的开头处添加指定的新结点。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="node">指定的新结点。</param>
|
|
||||||
public void AddFirst(LinkedListNode<T> node)
|
|
||||||
{
|
|
||||||
m_LinkedList.AddFirst(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在链表的结尾处添加包含指定值的新结点。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">指定值。</param>
|
|
||||||
/// <returns>包含指定值的新结点。</returns>
|
|
||||||
public LinkedListNode<T> AddLast(T value)
|
|
||||||
{
|
|
||||||
LinkedListNode<T> node = AcquireNode(value);
|
|
||||||
m_LinkedList.AddLast(node);
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在链表的结尾处添加指定的新结点。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="node">指定的新结点。</param>
|
|
||||||
public void AddLast(LinkedListNode<T> node)
|
|
||||||
{
|
|
||||||
m_LinkedList.AddLast(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 从链表中移除所有结点。
|
|
||||||
/// </summary>
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
LinkedListNode<T> current = m_LinkedList.First;
|
|
||||||
while (current != null)
|
|
||||||
{
|
|
||||||
ReleaseNode(current);
|
|
||||||
current = current.Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_LinkedList.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 清除链表结点缓存。
|
|
||||||
/// </summary>
|
|
||||||
public void ClearCachedNodes()
|
|
||||||
{
|
|
||||||
m_CachedNodes.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 确定某值是否在链表中。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">指定值。</param>
|
|
||||||
/// <returns>某值是否在链表中。</returns>
|
|
||||||
public bool Contains(T value)
|
|
||||||
{
|
|
||||||
return m_LinkedList.Contains(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 从目标数组的指定索引处开始将整个链表复制到兼容的一维数组。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="array">一维数组,它是从链表复制的元素的目标。数组必须具有从零开始的索引。</param>
|
|
||||||
/// <param name="index">array 中从零开始的索引,从此处开始复制。</param>
|
|
||||||
public void CopyTo(T[] array, int index)
|
|
||||||
{
|
|
||||||
m_LinkedList.CopyTo(array, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 从特定的 ICollection 索引开始,将数组的元素复制到一个数组中。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="array">一维数组,它是从 ICollection 复制的元素的目标。数组必须具有从零开始的索引。</param>
|
|
||||||
/// <param name="index">array 中从零开始的索引,从此处开始复制。</param>
|
|
||||||
public void CopyTo(Array array, int index)
|
|
||||||
{
|
|
||||||
((ICollection)m_LinkedList).CopyTo(array, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查找包含指定值的第一个结点。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">要查找的指定值。</param>
|
|
||||||
/// <returns>包含指定值的第一个结点。</returns>
|
|
||||||
public LinkedListNode<T> Find(T value)
|
|
||||||
{
|
|
||||||
return m_LinkedList.Find(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查找包含指定值的最后一个结点。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">要查找的指定值。</param>
|
|
||||||
/// <returns>包含指定值的最后一个结点。</returns>
|
|
||||||
public LinkedListNode<T> FindLast(T value)
|
|
||||||
{
|
|
||||||
return m_LinkedList.FindLast(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 从链表中移除指定值的第一个匹配项。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">指定值。</param>
|
|
||||||
/// <returns>是否移除成功。</returns>
|
|
||||||
public bool Remove(T value)
|
|
||||||
{
|
|
||||||
LinkedListNode<T> node = m_LinkedList.Find(value);
|
|
||||||
if (node != null)
|
|
||||||
{
|
|
||||||
m_LinkedList.Remove(node);
|
|
||||||
ReleaseNode(node);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 从链表中移除指定的结点。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="node">指定的结点。</param>
|
|
||||||
public void Remove(LinkedListNode<T> node)
|
|
||||||
{
|
|
||||||
m_LinkedList.Remove(node);
|
|
||||||
ReleaseNode(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 移除位于链表开头处的结点。
|
|
||||||
/// </summary>
|
|
||||||
public void RemoveFirst()
|
|
||||||
{
|
|
||||||
LinkedListNode<T> first = m_LinkedList.First;
|
|
||||||
if (first == null)
|
|
||||||
{
|
|
||||||
throw new GameException("First is invalid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_LinkedList.RemoveFirst();
|
|
||||||
ReleaseNode(first);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 移除位于链表结尾处的结点。
|
|
||||||
/// </summary>
|
|
||||||
public void RemoveLast()
|
|
||||||
{
|
|
||||||
LinkedListNode<T> last = m_LinkedList.Last;
|
|
||||||
if (last == null)
|
|
||||||
{
|
|
||||||
throw new GameException("Last is invalid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_LinkedList.RemoveLast();
|
|
||||||
ReleaseNode(last);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 返回循环访问集合的枚举数。
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>循环访问集合的枚举数。</returns>
|
|
||||||
public Enumerator GetEnumerator()
|
|
||||||
{
|
|
||||||
return new Enumerator(m_LinkedList);
|
|
||||||
}
|
|
||||||
|
|
||||||
private LinkedListNode<T> AcquireNode(T value)
|
|
||||||
{
|
|
||||||
LinkedListNode<T> node = null;
|
|
||||||
if (m_CachedNodes.Count > 0)
|
|
||||||
{
|
|
||||||
node = m_CachedNodes.Dequeue();
|
|
||||||
node.Value = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
node = new LinkedListNode<T>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ReleaseNode(LinkedListNode<T> node)
|
|
||||||
{
|
|
||||||
node.Value = default(T);
|
|
||||||
m_CachedNodes.Enqueue(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 将值添加到 ICollection`1 的结尾处。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">要添加的值。</param>
|
|
||||||
void ICollection<T>.Add(T value)
|
|
||||||
{
|
|
||||||
AddLast(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 返回循环访问集合的枚举数。
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>循环访问集合的枚举数。</returns>
|
|
||||||
IEnumerator<T> IEnumerable<T>.GetEnumerator()
|
|
||||||
{
|
|
||||||
return GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 返回循环访问集合的枚举数。
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>循环访问集合的枚举数。</returns>
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
|
||||||
{
|
|
||||||
return GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 循环访问集合的枚举数。
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Auto)]
|
|
||||||
public struct Enumerator : IEnumerator<T>, IEnumerator
|
|
||||||
{
|
|
||||||
private LinkedList<T>.Enumerator m_Enumerator;
|
|
||||||
|
|
||||||
internal Enumerator(LinkedList<T> linkedList)
|
|
||||||
{
|
|
||||||
if (linkedList == null)
|
|
||||||
{
|
|
||||||
throw new GameException("Linked list is invalid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Enumerator = linkedList.GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取当前结点。
|
|
||||||
/// </summary>
|
|
||||||
public T Current
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_Enumerator.Current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取当前的枚举数。
|
|
||||||
/// </summary>
|
|
||||||
object IEnumerator.Current
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_Enumerator.Current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 清理枚举数。
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
m_Enumerator.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取下一个结点。
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>返回下一个结点。</returns>
|
|
||||||
public bool MoveNext()
|
|
||||||
{
|
|
||||||
return m_Enumerator.MoveNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 重置枚举数。
|
|
||||||
/// </summary>
|
|
||||||
void IEnumerator.Reset()
|
|
||||||
{
|
|
||||||
((IEnumerator<T>)m_Enumerator).Reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,485 +7,4 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace Convention.Experimental.PublicType
|
namespace Convention.Experimental.PublicType
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD>ýӿڡ<D3BF>
|
|
||||||
/// </summary>
|
|
||||||
public interface IReference
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>á<EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
void Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD>ó<EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
public static partial class ReferencePool
|
|
||||||
{
|
|
||||||
private static bool m_EnableStrictCheck = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>Ƽ<EFBFBD><C6BC><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
public static bool EnableStrictCheck
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_EnableStrictCheck;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
m_EnableStrictCheck = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private sealed class ReferenceCollection
|
|
||||||
{
|
|
||||||
private readonly Queue<IReference> m_References;
|
|
||||||
private readonly Type m_ReferenceType;
|
|
||||||
private int m_UsingReferenceCount;
|
|
||||||
private int m_AcquireReferenceCount;
|
|
||||||
private int m_ReleaseReferenceCount;
|
|
||||||
private int m_AddReferenceCount;
|
|
||||||
private int m_RemoveReferenceCount;
|
|
||||||
|
|
||||||
public ReferenceCollection(Type referenceType)
|
|
||||||
{
|
|
||||||
m_References = new Queue<IReference>();
|
|
||||||
m_ReferenceType = referenceType;
|
|
||||||
m_UsingReferenceCount = 0;
|
|
||||||
m_AcquireReferenceCount = 0;
|
|
||||||
m_ReleaseReferenceCount = 0;
|
|
||||||
m_AddReferenceCount = 0;
|
|
||||||
m_RemoveReferenceCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type ReferenceType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_ReferenceType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int UnusedReferenceCount
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_References.Count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int UsingReferenceCount
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_UsingReferenceCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int AcquireReferenceCount
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_AcquireReferenceCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int ReleaseReferenceCount
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_ReleaseReferenceCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int AddReferenceCount
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_AddReferenceCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int RemoveReferenceCount
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_RemoveReferenceCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public T Acquire<T>() where T : class, IReference, new()
|
|
||||||
{
|
|
||||||
if (typeof(T) != m_ReferenceType)
|
|
||||||
{
|
|
||||||
throw new GameException("Type is invalid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_UsingReferenceCount++;
|
|
||||||
m_AcquireReferenceCount++;
|
|
||||||
lock (m_References)
|
|
||||||
{
|
|
||||||
if (m_References.Count > 0)
|
|
||||||
{
|
|
||||||
return (T)m_References.Dequeue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_AddReferenceCount++;
|
|
||||||
return new T();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IReference Acquire()
|
|
||||||
{
|
|
||||||
m_UsingReferenceCount++;
|
|
||||||
m_AcquireReferenceCount++;
|
|
||||||
lock (m_References)
|
|
||||||
{
|
|
||||||
if (m_References.Count > 0)
|
|
||||||
{
|
|
||||||
return m_References.Dequeue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_AddReferenceCount++;
|
|
||||||
return (IReference)Activator.CreateInstance(m_ReferenceType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Release(IReference reference)
|
|
||||||
{
|
|
||||||
reference.Clear();
|
|
||||||
lock (m_References)
|
|
||||||
{
|
|
||||||
if (m_EnableStrictCheck && m_References.Contains(reference))
|
|
||||||
{
|
|
||||||
throw new GameException("The reference has been released.");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_References.Enqueue(reference);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ReleaseReferenceCount++;
|
|
||||||
m_UsingReferenceCount--;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add<T>(int count) where T : class, IReference, new()
|
|
||||||
{
|
|
||||||
if (typeof(T) != m_ReferenceType)
|
|
||||||
{
|
|
||||||
throw new GameException("Type is invalid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (m_References)
|
|
||||||
{
|
|
||||||
m_AddReferenceCount += count;
|
|
||||||
while (count-- > 0)
|
|
||||||
{
|
|
||||||
m_References.Enqueue(new T());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(int count)
|
|
||||||
{
|
|
||||||
lock (m_References)
|
|
||||||
{
|
|
||||||
m_AddReferenceCount += count;
|
|
||||||
while (count-- > 0)
|
|
||||||
{
|
|
||||||
m_References.Enqueue((IReference)Activator.CreateInstance(m_ReferenceType));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Remove(int count)
|
|
||||||
{
|
|
||||||
lock (m_References)
|
|
||||||
{
|
|
||||||
if (count > m_References.Count)
|
|
||||||
{
|
|
||||||
count = m_References.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_RemoveReferenceCount += count;
|
|
||||||
while (count-- > 0)
|
|
||||||
{
|
|
||||||
m_References.Dequeue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAll()
|
|
||||||
{
|
|
||||||
lock (m_References)
|
|
||||||
{
|
|
||||||
m_RemoveReferenceCount += m_References.Count;
|
|
||||||
m_References.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly Dictionary<Type, ReferenceCollection> s_ReferenceCollections = new();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD>óص<C3B3><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
public static int Count
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return s_ReferenceCollections.Count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD>Ϣ
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Auto)]
|
|
||||||
public readonly struct ReferencePoolInfo
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
public readonly Type Type;
|
|
||||||
/// <summary>
|
|
||||||
/// δʹ<CEB4><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
public readonly int UnusedReferenceCount;
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
public readonly int UsingReferenceCount;
|
|
||||||
/// <summary>
|
|
||||||
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
public readonly int AcquireReferenceCount;
|
|
||||||
/// <summary>
|
|
||||||
/// <20>黹<EFBFBD><E9BBB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
public readonly int ReleaseReferenceCount;
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
public readonly int AddReferenceCount;
|
|
||||||
/// <summary>
|
|
||||||
/// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
public readonly int RemoveReferenceCount;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type"><3E><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>͡<EFBFBD></param>
|
|
||||||
/// <param name="unusedReferenceCount">δʹ<CEB4><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
|
||||||
/// <param name="usingReferenceCount"><3E><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
|
||||||
/// <param name="acquireReferenceCount"><3E><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
|
||||||
/// <param name="releaseReferenceCount"><3E>黹<EFBFBD><E9BBB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
|
||||||
/// <param name="addReferenceCount"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
|
||||||
/// <param name="removeReferenceCount"><3E>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
|
||||||
public ReferencePoolInfo(Type type,
|
|
||||||
int unusedReferenceCount,
|
|
||||||
int usingReferenceCount,
|
|
||||||
int acquireReferenceCount,
|
|
||||||
int releaseReferenceCount,
|
|
||||||
int addReferenceCount,
|
|
||||||
int removeReferenceCount)
|
|
||||||
{
|
|
||||||
this.Type = type;
|
|
||||||
this.UnusedReferenceCount = unusedReferenceCount;
|
|
||||||
this.UsingReferenceCount = usingReferenceCount;
|
|
||||||
this.AcquireReferenceCount = acquireReferenceCount;
|
|
||||||
this.ReleaseReferenceCount = releaseReferenceCount;
|
|
||||||
this.AddReferenceCount = addReferenceCount;
|
|
||||||
this.RemoveReferenceCount = removeReferenceCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>óص<C3B3><D8B5><EFBFBD>Ϣ
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>óص<C3B3><D8B5><EFBFBD>Ϣ</returns>
|
|
||||||
public static ReferencePoolInfo[] GetAllReferencePoolInfos()
|
|
||||||
{
|
|
||||||
int index = 0;
|
|
||||||
ReferencePoolInfo[] results = null;
|
|
||||||
|
|
||||||
lock (s_ReferenceCollections)
|
|
||||||
{
|
|
||||||
results = new ReferencePoolInfo[s_ReferenceCollections.Count];
|
|
||||||
foreach (var (key,value) in s_ReferenceCollections)
|
|
||||||
{
|
|
||||||
results[index++] = new ReferencePoolInfo(key,
|
|
||||||
value.UnusedReferenceCount,
|
|
||||||
value.UsingReferenceCount,
|
|
||||||
value.AcquireReferenceCount,
|
|
||||||
value.ReleaseReferenceCount,
|
|
||||||
value.AddReferenceCount,
|
|
||||||
value.RemoveReferenceCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
public static void ClearAll()
|
|
||||||
{
|
|
||||||
lock (s_ReferenceCollections)
|
|
||||||
{
|
|
||||||
foreach (var (_, value) in s_ReferenceCollections)
|
|
||||||
{
|
|
||||||
value.RemoveAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
s_ReferenceCollections.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ReferenceCollection GetReferenceCollection(Type referenceType)
|
|
||||||
{
|
|
||||||
if (referenceType == null)
|
|
||||||
{
|
|
||||||
throw new GameException("ReferenceType is invalid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
ReferenceCollection referenceCollection = null;
|
|
||||||
lock (s_ReferenceCollections)
|
|
||||||
{
|
|
||||||
if (!s_ReferenceCollections.TryGetValue(referenceType, out referenceCollection))
|
|
||||||
{
|
|
||||||
referenceCollection = new ReferenceCollection(referenceType);
|
|
||||||
s_ReferenceCollections.Add(referenceType, referenceCollection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return referenceCollection;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void InternalCheckReferenceType(Type referenceType)
|
|
||||||
{
|
|
||||||
if (!m_EnableStrictCheck)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (referenceType == null)
|
|
||||||
{
|
|
||||||
throw new GameException("Reference type is invalid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!referenceType.IsClass || referenceType.IsAbstract)
|
|
||||||
{
|
|
||||||
throw new GameException("Reference type is not a non-abstract class type.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!typeof(IReference).IsAssignableFrom(referenceType))
|
|
||||||
{
|
|
||||||
throw new GameException($"Reference type '{referenceType.FullName}' is invalid.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD><EFBFBD><EFBFBD>óػ<C3B3>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="referenceType"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
|
||||||
/// <returns><3E><><EFBFBD><EFBFBD></returns>
|
|
||||||
public static IReference Acquire(Type referenceType)
|
|
||||||
{
|
|
||||||
InternalCheckReferenceType(referenceType);
|
|
||||||
return GetReferenceCollection(referenceType).Acquire();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD><EFBFBD><EFBFBD>óػ<C3B3>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
|
|
||||||
/// <returns><3E><><EFBFBD><EFBFBD></returns>
|
|
||||||
public static T Acquire<T>() where T : class, IReference, new()
|
|
||||||
{
|
|
||||||
return GetReferenceCollection(typeof(T)).Acquire<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD><EFBFBD><EFBFBD>ù黹<C3B9><E9BBB9><EFBFBD>ó<EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="reference"><3E><><EFBFBD><EFBFBD></param>
|
|
||||||
public static void Release(IReference reference)
|
|
||||||
{
|
|
||||||
if (reference == null)
|
|
||||||
{
|
|
||||||
throw new GameException("Reference is invalid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Type referenceType = reference.GetType();
|
|
||||||
InternalCheckReferenceType(referenceType);
|
|
||||||
GetReferenceCollection(referenceType).Release(reference);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><D7B7>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
|
|
||||||
/// <param name="count"><><D7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
|
||||||
public static void Add<T>(int count) where T : class, IReference, new()
|
|
||||||
{
|
|
||||||
GetReferenceCollection(typeof(T)).Add<T>(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><D7B7>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="referenceType"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
|
||||||
/// <param name="count"><><D7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
|
||||||
public static void Add(Type referenceType, int count)
|
|
||||||
{
|
|
||||||
InternalCheckReferenceType(referenceType);
|
|
||||||
GetReferenceCollection(referenceType).Add(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>Ƴ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
|
|
||||||
/// <param name="count"><3E>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD></param>
|
|
||||||
public static void Remove<T>(int count) where T : class, IReference
|
|
||||||
{
|
|
||||||
GetReferenceCollection(typeof(T)).Remove(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>Ƴ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="referenceType"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
|
||||||
/// <param name="count"><3E>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD></param>
|
|
||||||
public static void Remove(Type referenceType, int count)
|
|
||||||
{
|
|
||||||
InternalCheckReferenceType(referenceType);
|
|
||||||
GetReferenceCollection(referenceType).Remove(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
|
|
||||||
public static void RemoveAll<T>() where T : class, IReference
|
|
||||||
{
|
|
||||||
GetReferenceCollection(typeof(T)).RemoveAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD>á<EFBFBD>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="referenceType"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͡<EFBFBD></param>
|
|
||||||
public static void RemoveAll(Type referenceType)
|
|
||||||
{
|
|
||||||
InternalCheckReferenceType(referenceType);
|
|
||||||
GetReferenceCollection(referenceType).RemoveAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
using System;
|
using Convention.Experimental.PublicType;
|
||||||
|
using Convention.WindowsUI;
|
||||||
|
using Sirenix.Utilities;
|
||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -7,8 +10,6 @@ using System.Reflection;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Convention.WindowsUI;
|
|
||||||
using Sirenix.Utilities;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
@@ -2528,9 +2529,3 @@ namespace Convention
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Convention.Collections
|
|
||||||
{
|
|
||||||
namespace Generic
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
456
Convention/[Runtime]/Convention.Collections.cs
Normal file
456
Convention/[Runtime]/Convention.Collections.cs
Normal file
@@ -0,0 +1,456 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Convention.Collections
|
||||||
|
{
|
||||||
|
namespace Generic
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
|
||||||
|
public sealed class LinkedCacheList<T> : ICollection<T>, IEnumerable<T>, ICollection, IEnumerable
|
||||||
|
{
|
||||||
|
private readonly LinkedList<T> m_LinkedList;
|
||||||
|
/// <summary>
|
||||||
|
/// ֮<><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><D7BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD>
|
||||||
|
/// <list type="bullet"><3E><><EFBFBD><EFBFBD> GC ѹ<><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD>/ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܶ<EFBFBD><DCB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵĽڵ<C4BD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>йܶѵķ<D1B5><C4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>մ<EFBFBD><D5B4><EFBFBD></list>
|
||||||
|
/// <list type="bullet"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5> new <20><> GC<47><43><EFBFBD>ܼ<EFBFBD><DCBC><EFBFBD>ͣ<EFBFBD><CDA3>ʱ<EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD></list>
|
||||||
|
/// <list type="bullet"><3E><><EFBFBD>ڹ۲<DAB9><DBB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB>ṩ<EFBFBD><E1B9A9> CachedNodeCount <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD>ƻ<EFBFBD><C6BB><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>Ҫʱ<D2AA><CAB1>ͨ<EFBFBD><CDA8> ClearCachedNodes <20><><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD></list>
|
||||||
|
/// <20><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>ǽڵ<C7BD>ʹ<EFBFBD><CAB9>ģʽ<C4A3><CABD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޡ<EFBFBD><DEA1><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȶ<EFBFBD><C8B6><EFBFBD><EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʼ<C4A3><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD><EFBFBD>ͷţ<CDB7><C5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ͡<CFB5>
|
||||||
|
/// </summary>
|
||||||
|
private readonly Queue<LinkedListNode<T>> m_CachedNodes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>
|
||||||
|
/// </summary>
|
||||||
|
public LinkedCacheList()
|
||||||
|
{
|
||||||
|
m_LinkedList = new LinkedList<T>();
|
||||||
|
m_CachedNodes = new Queue<LinkedListNode<T>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ʰ<EFBFBD><CAB0><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_LinkedList.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㻺<EFBFBD><E3BBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public int CachedNodeCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_CachedNodes.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public LinkedListNode<T> First
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_LinkedList.First;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public LinkedListNode<T> Last
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_LinkedList.Last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡһ<C8A1><D2BB>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ֵָʾ <see cref="ICollection{T}"/> <20>Ƿ<EFBFBD>Ϊֻ<CEAA><D6BB>
|
||||||
|
/// </summary>
|
||||||
|
public bool IsReadOnly
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ((ICollection<T>)m_LinkedList).IsReadOnly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD> <see cref="ICollection"/> <20>ķ<EFBFBD><C4B7>ʵĶ<CAB5><C4B6><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public object SyncRoot
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ((ICollection)m_LinkedList).SyncRoot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡһ<C8A1><D2BB>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ֵָʾ<D6B8>Ƿ<EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD> <see cref="ICollection"/> <20>ķ<EFBFBD><C4B7>ʣ<EFBFBD><CAA3>̰߳<DFB3>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public bool IsSynchronized
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ((ICollection)m_LinkedList).IsSynchronized;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0><EFBFBD>ָ<EFBFBD><D6B8>ֵ<EFBFBD><D6B5><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD></param>
|
||||||
|
/// <param name="value">ָ<><D6B8>ֵ</param>
|
||||||
|
/// <returns><3E><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>ֵ<EFBFBD><D6B5><EFBFBD>½<EFBFBD><C2BD><EFBFBD></returns>
|
||||||
|
public LinkedListNode<T> AddAfter(LinkedListNode<T> node, T value)
|
||||||
|
{
|
||||||
|
LinkedListNode<T> newNode = AcquireNode(value);
|
||||||
|
m_LinkedList.AddAfter(node, newNode);
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD></param>
|
||||||
|
/// <param name="newNode">ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD></param>
|
||||||
|
public void AddAfter(LinkedListNode<T> node, LinkedListNode<T> newNode)
|
||||||
|
{
|
||||||
|
m_LinkedList.AddAfter(node, newNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>Ӱ<EFBFBD><D3B0><EFBFBD>ָ<EFBFBD><D6B8>ֵ<EFBFBD><D6B5><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD></param>
|
||||||
|
/// <param name="value">ָ<><D6B8>ֵ</param>
|
||||||
|
/// <returns><3E><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>ֵ<EFBFBD><D6B5><EFBFBD>½<EFBFBD><C2BD><EFBFBD></returns>
|
||||||
|
public LinkedListNode<T> AddBefore(LinkedListNode<T> node, T value)
|
||||||
|
{
|
||||||
|
LinkedListNode<T> newNode = AcquireNode(value);
|
||||||
|
m_LinkedList.AddBefore(node, newNode);
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD></param>
|
||||||
|
/// <param name="newNode">ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD></param>
|
||||||
|
public void AddBefore(LinkedListNode<T> node, LinkedListNode<T> newNode)
|
||||||
|
{
|
||||||
|
m_LinkedList.AddBefore(node, newNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0><EFBFBD>ָ<EFBFBD><D6B8>ֵ<EFBFBD><D6B5><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">ָ<><D6B8>ֵ</param>
|
||||||
|
/// <returns><3E><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>ֵ<EFBFBD><D6B5><EFBFBD>½<EFBFBD><C2BD><EFBFBD></returns>
|
||||||
|
public LinkedListNode<T> AddFirst(T value)
|
||||||
|
{
|
||||||
|
LinkedListNode<T> node = AcquireNode(value);
|
||||||
|
m_LinkedList.AddFirst(node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD></param>
|
||||||
|
public void AddFirst(LinkedListNode<T> node)
|
||||||
|
{
|
||||||
|
m_LinkedList.AddFirst(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0><EFBFBD>ָ<EFBFBD><D6B8>ֵ<EFBFBD><D6B5><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">ָ<><D6B8>ֵ</param>
|
||||||
|
/// <returns><3E><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>ֵ<EFBFBD><D6B5><EFBFBD>½<EFBFBD><C2BD><EFBFBD></returns>
|
||||||
|
public LinkedListNode<T> AddLast(T value)
|
||||||
|
{
|
||||||
|
LinkedListNode<T> node = AcquireNode(value);
|
||||||
|
m_LinkedList.AddLast(node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD></param>
|
||||||
|
public void AddLast(LinkedListNode<T> node)
|
||||||
|
{
|
||||||
|
m_LinkedList.AddLast(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
LinkedListNode<T> current = m_LinkedList.First;
|
||||||
|
while (current != null)
|
||||||
|
{
|
||||||
|
ReleaseNode(current);
|
||||||
|
current = current.Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_LinkedList.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㻺<EFBFBD><E3BBBA>
|
||||||
|
/// </summary>
|
||||||
|
public void ClearCachedNodes()
|
||||||
|
{
|
||||||
|
m_CachedNodes.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ȷ<><C8B7>ijֵ<C4B3>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">ָ<><D6B8>ֵ</param>
|
||||||
|
/// <returns>ijֵ<C4B3>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></returns>
|
||||||
|
public bool Contains(T value)
|
||||||
|
{
|
||||||
|
return m_LinkedList.Contains(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>ݵ<EFBFBD>һά<D2BB><CEAC><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="array">һά<D2BB><CEAC><EFBFBD>飬<EFBFBD><E9A3AC><EFBFBD>Ǵ<EFBFBD><C7B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>Ԫ<EFBFBD>ص<EFBFBD>Ŀ<EFBFBD>ꡣ<EFBFBD><EAA1A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>㿪ʼ<E3BFAA><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
/// <param name="index">array <20>д<EFBFBD><D0B4>㿪ʼ<E3BFAA><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӵ˴<D3B4><CBB4><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD></param>
|
||||||
|
public void CopyTo(T[] array, int index)
|
||||||
|
{
|
||||||
|
m_LinkedList.CopyTo(array, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD>ض<EFBFBD><D8B6><EFBFBD> ICollection <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ظ<EFBFBD><D8B8>Ƶ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="array">һά<D2BB><CEAC><EFBFBD>飬<EFBFBD><E9A3AC><EFBFBD>Ǵ<EFBFBD> ICollection <20><><EFBFBD>Ƶ<EFBFBD>Ԫ<EFBFBD>ص<EFBFBD>Ŀ<EFBFBD>ꡣ<EFBFBD><EAA1A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>㿪ʼ<E3BFAA><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
/// <param name="index">array <20>д<EFBFBD><D0B4>㿪ʼ<E3BFAA><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӵ˴<D3B4><CBB4><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD></param>
|
||||||
|
public void CopyTo(Array array, int index)
|
||||||
|
{
|
||||||
|
((ICollection)m_LinkedList).CopyTo(array, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD>Ұ<EFBFBD><D2B0><EFBFBD>ָ<EFBFBD><D6B8>ֵ<EFBFBD>ĵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Ҫ<><D2AA><EFBFBD>ҵ<EFBFBD>ָ<EFBFBD><D6B8>ֵ</param>
|
||||||
|
/// <returns><3E><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>ֵ<EFBFBD>ĵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD></returns>
|
||||||
|
public LinkedListNode<T> Find(T value)
|
||||||
|
{
|
||||||
|
return m_LinkedList.Find(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD>Ұ<EFBFBD><D2B0><EFBFBD>ָ<EFBFBD><D6B8>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Ҫ<><D2AA><EFBFBD>ҵ<EFBFBD>ָ<EFBFBD><D6B8>ֵ</param>
|
||||||
|
/// <returns><3E><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD></returns>
|
||||||
|
public LinkedListNode<T> FindLast(T value)
|
||||||
|
{
|
||||||
|
return m_LinkedList.FindLast(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>ָ<EFBFBD><D6B8>ֵ<EFBFBD>ĵ<EFBFBD>һ<EFBFBD><D2BB>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">ָ<><D6B8>ֵ</param>
|
||||||
|
/// <returns><3E>Ƿ<EFBFBD><C7B7>Ƴ<EFBFBD><C6B3>ɹ<EFBFBD></returns>
|
||||||
|
public bool Remove(T value)
|
||||||
|
{
|
||||||
|
LinkedListNode<T> node = m_LinkedList.Find(value);
|
||||||
|
if (node != null)
|
||||||
|
{
|
||||||
|
m_LinkedList.Remove(node);
|
||||||
|
ReleaseNode(node);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">ָ<><D6B8><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD></param>
|
||||||
|
public void Remove(LinkedListNode<T> node)
|
||||||
|
{
|
||||||
|
m_LinkedList.Remove(node);
|
||||||
|
ReleaseNode(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20>Ƴ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public void RemoveFirst()
|
||||||
|
{
|
||||||
|
LinkedListNode<T> first = m_LinkedList.First;
|
||||||
|
if (first == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Rmove first is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_LinkedList.RemoveFirst();
|
||||||
|
ReleaseNode(first);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20>Ƴ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2><EFBFBD>Ľ<EFBFBD><C4BD>㡣
|
||||||
|
/// </summary>
|
||||||
|
public void RemoveLast()
|
||||||
|
{
|
||||||
|
LinkedListNode<T> last = m_LinkedList.Last;
|
||||||
|
if (last == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Remove last is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_LinkedList.RemoveLast();
|
||||||
|
ReleaseNode(last);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ϵ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ϵ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD></returns>
|
||||||
|
public Enumerator GetEnumerator()
|
||||||
|
{
|
||||||
|
return new Enumerator(m_LinkedList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LinkedListNode<T> AcquireNode(T value)
|
||||||
|
{
|
||||||
|
LinkedListNode<T> node = null;
|
||||||
|
if (m_CachedNodes.Count > 0)
|
||||||
|
{
|
||||||
|
node = m_CachedNodes.Dequeue();
|
||||||
|
node.Value = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node = new LinkedListNode<T>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReleaseNode(LinkedListNode<T> node)
|
||||||
|
{
|
||||||
|
node.Value = default(T);
|
||||||
|
m_CachedNodes.Enqueue(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ֵ<EFBFBD><D6B5><EFBFBD>ӵ<EFBFBD> ICollection`1 <20>Ľ<EFBFBD>β<EFBFBD><CEB2>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Ҫ<><D2AA><EFBFBD>ӵ<EFBFBD>ֵ</param>
|
||||||
|
void ICollection<T>.Add(T value)
|
||||||
|
{
|
||||||
|
AddLast(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ϵ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ϵ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD></returns>
|
||||||
|
IEnumerator<T> IEnumerable<T>.GetEnumerator()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ϵ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ϵ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD></returns>
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ϵ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Auto)]
|
||||||
|
public struct Enumerator : IEnumerator<T>, IEnumerator
|
||||||
|
{
|
||||||
|
private LinkedList<T>.Enumerator m_Enumerator;
|
||||||
|
|
||||||
|
internal Enumerator(LinkedList<T> linkedList)
|
||||||
|
{
|
||||||
|
if (linkedList == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Linked list is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Enumerator = linkedList.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public T Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_Enumerator.Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0>ö<EFBFBD><C3B6><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
object IEnumerator.Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_Enumerator.Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
m_Enumerator.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD></returns>
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
return m_Enumerator.MoveNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
void IEnumerator.Reset()
|
||||||
|
{
|
||||||
|
((IEnumerator<T>)m_Enumerator).Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Convention/[Runtime]/Convention.Collections.cs.meta
Normal file
11
Convention/[Runtime]/Convention.Collections.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a40a6ad3561c922478840f163ea43790
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
490
Convention/[Runtime]/Convention.ReferencePool.cs
Normal file
490
Convention/[Runtime]/Convention.ReferencePool.cs
Normal file
@@ -0,0 +1,490 @@
|
|||||||
|
|
||||||
|
using Convention.Experimental.PublicType;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Convention.ReferenceManagement
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD>ýӿ<C3BD>
|
||||||
|
/// </summary>
|
||||||
|
public interface IReference
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
void Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD>ó<EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public static partial class ReferencePool
|
||||||
|
{
|
||||||
|
private static bool m_EnableStrictCheck = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>Ƽ<EFBFBD><C6BC><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public static bool EnableStrictCheck
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_EnableStrictCheck;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_EnableStrictCheck = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private sealed class ReferenceCollection
|
||||||
|
{
|
||||||
|
private readonly Queue<IReference> m_References;
|
||||||
|
private readonly Type m_ReferenceType;
|
||||||
|
private int m_UsingReferenceCount;
|
||||||
|
private int m_AcquireReferenceCount;
|
||||||
|
private int m_ReleaseReferenceCount;
|
||||||
|
private int m_AddReferenceCount;
|
||||||
|
private int m_RemoveReferenceCount;
|
||||||
|
|
||||||
|
public ReferenceCollection(Type referenceType)
|
||||||
|
{
|
||||||
|
m_References = new Queue<IReference>();
|
||||||
|
m_ReferenceType = referenceType;
|
||||||
|
m_UsingReferenceCount = 0;
|
||||||
|
m_AcquireReferenceCount = 0;
|
||||||
|
m_ReleaseReferenceCount = 0;
|
||||||
|
m_AddReferenceCount = 0;
|
||||||
|
m_RemoveReferenceCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type ReferenceType
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_ReferenceType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int UnusedReferenceCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_References.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int UsingReferenceCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_UsingReferenceCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int AcquireReferenceCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_AcquireReferenceCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ReleaseReferenceCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_ReleaseReferenceCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int AddReferenceCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_AddReferenceCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int RemoveReferenceCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_RemoveReferenceCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Acquire<T>() where T : class, IReference, new()
|
||||||
|
{
|
||||||
|
if (typeof(T) != m_ReferenceType)
|
||||||
|
{
|
||||||
|
throw new GameException("Type is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_UsingReferenceCount++;
|
||||||
|
m_AcquireReferenceCount++;
|
||||||
|
lock (m_References)
|
||||||
|
{
|
||||||
|
if (m_References.Count > 0)
|
||||||
|
{
|
||||||
|
return (T)m_References.Dequeue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_AddReferenceCount++;
|
||||||
|
return new T();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IReference Acquire()
|
||||||
|
{
|
||||||
|
m_UsingReferenceCount++;
|
||||||
|
m_AcquireReferenceCount++;
|
||||||
|
lock (m_References)
|
||||||
|
{
|
||||||
|
if (m_References.Count > 0)
|
||||||
|
{
|
||||||
|
return m_References.Dequeue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_AddReferenceCount++;
|
||||||
|
return (IReference)Activator.CreateInstance(m_ReferenceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Release(IReference reference)
|
||||||
|
{
|
||||||
|
reference.Clear();
|
||||||
|
lock (m_References)
|
||||||
|
{
|
||||||
|
if (m_EnableStrictCheck && m_References.Contains(reference))
|
||||||
|
{
|
||||||
|
throw new GameException("The reference has been released.");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_References.Enqueue(reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ReleaseReferenceCount++;
|
||||||
|
m_UsingReferenceCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add<T>(int count) where T : class, IReference, new()
|
||||||
|
{
|
||||||
|
if (typeof(T) != m_ReferenceType)
|
||||||
|
{
|
||||||
|
throw new GameException("Type is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (m_References)
|
||||||
|
{
|
||||||
|
m_AddReferenceCount += count;
|
||||||
|
while (count-- > 0)
|
||||||
|
{
|
||||||
|
m_References.Enqueue(new T());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(int count)
|
||||||
|
{
|
||||||
|
lock (m_References)
|
||||||
|
{
|
||||||
|
m_AddReferenceCount += count;
|
||||||
|
while (count-- > 0)
|
||||||
|
{
|
||||||
|
m_References.Enqueue((IReference)Activator.CreateInstance(m_ReferenceType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(int count)
|
||||||
|
{
|
||||||
|
lock (m_References)
|
||||||
|
{
|
||||||
|
if (count > m_References.Count)
|
||||||
|
{
|
||||||
|
count = m_References.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_RemoveReferenceCount += count;
|
||||||
|
while (count-- > 0)
|
||||||
|
{
|
||||||
|
m_References.Dequeue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveAll()
|
||||||
|
{
|
||||||
|
lock (m_References)
|
||||||
|
{
|
||||||
|
m_RemoveReferenceCount += m_References.Count;
|
||||||
|
m_References.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Dictionary<Type, ReferenceCollection> s_ReferenceCollections = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD>óص<C3B3><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public static int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return s_ReferenceCollections.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD>Ϣ
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Auto)]
|
||||||
|
public readonly struct ReferencePoolInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public readonly Type Type;
|
||||||
|
/// <summary>
|
||||||
|
/// δʹ<CEB4><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public readonly int UnusedReferenceCount;
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public readonly int UsingReferenceCount;
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public readonly int AcquireReferenceCount;
|
||||||
|
/// <summary>
|
||||||
|
/// <20>黹<EFBFBD><E9BBB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public readonly int ReleaseReferenceCount;
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public readonly int AddReferenceCount;
|
||||||
|
/// <summary>
|
||||||
|
/// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public readonly int RemoveReferenceCount;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type"><3E><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>͡<EFBFBD></param>
|
||||||
|
/// <param name="unusedReferenceCount">δʹ<CEB4><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
/// <param name="usingReferenceCount"><3E><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
/// <param name="acquireReferenceCount"><3E><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
/// <param name="releaseReferenceCount"><3E>黹<EFBFBD><E9BBB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
/// <param name="addReferenceCount"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
/// <param name="removeReferenceCount"><3E>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
public ReferencePoolInfo(Type type,
|
||||||
|
int unusedReferenceCount,
|
||||||
|
int usingReferenceCount,
|
||||||
|
int acquireReferenceCount,
|
||||||
|
int releaseReferenceCount,
|
||||||
|
int addReferenceCount,
|
||||||
|
int removeReferenceCount)
|
||||||
|
{
|
||||||
|
this.Type = type;
|
||||||
|
this.UnusedReferenceCount = unusedReferenceCount;
|
||||||
|
this.UsingReferenceCount = usingReferenceCount;
|
||||||
|
this.AcquireReferenceCount = acquireReferenceCount;
|
||||||
|
this.ReleaseReferenceCount = releaseReferenceCount;
|
||||||
|
this.AddReferenceCount = addReferenceCount;
|
||||||
|
this.RemoveReferenceCount = removeReferenceCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>óص<C3B3><D8B5><EFBFBD>Ϣ
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>óص<C3B3><D8B5><EFBFBD>Ϣ</returns>
|
||||||
|
public static ReferencePoolInfo[] GetAllReferencePoolInfos()
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
ReferencePoolInfo[] results = null;
|
||||||
|
|
||||||
|
lock (s_ReferenceCollections)
|
||||||
|
{
|
||||||
|
results = new ReferencePoolInfo[s_ReferenceCollections.Count];
|
||||||
|
foreach (var (key, value) in s_ReferenceCollections)
|
||||||
|
{
|
||||||
|
results[index++] = new ReferencePoolInfo(key,
|
||||||
|
value.UnusedReferenceCount,
|
||||||
|
value.UsingReferenceCount,
|
||||||
|
value.AcquireReferenceCount,
|
||||||
|
value.ReleaseReferenceCount,
|
||||||
|
value.AddReferenceCount,
|
||||||
|
value.RemoveReferenceCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public static void ClearAll()
|
||||||
|
{
|
||||||
|
lock (s_ReferenceCollections)
|
||||||
|
{
|
||||||
|
foreach (var (_, value) in s_ReferenceCollections)
|
||||||
|
{
|
||||||
|
value.RemoveAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
s_ReferenceCollections.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReferenceCollection GetReferenceCollection(Type referenceType)
|
||||||
|
{
|
||||||
|
if (referenceType == null)
|
||||||
|
{
|
||||||
|
throw new GameException("ReferenceType is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
ReferenceCollection referenceCollection = null;
|
||||||
|
lock (s_ReferenceCollections)
|
||||||
|
{
|
||||||
|
if (!s_ReferenceCollections.TryGetValue(referenceType, out referenceCollection))
|
||||||
|
{
|
||||||
|
referenceCollection = new ReferenceCollection(referenceType);
|
||||||
|
s_ReferenceCollections.Add(referenceType, referenceCollection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return referenceCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void InternalCheckReferenceType(Type referenceType)
|
||||||
|
{
|
||||||
|
if (!m_EnableStrictCheck)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (referenceType == null)
|
||||||
|
{
|
||||||
|
throw new GameException("Reference type is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!referenceType.IsClass || referenceType.IsAbstract)
|
||||||
|
{
|
||||||
|
throw new GameException("Reference type is not a non-abstract class type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!typeof(IReference).IsAssignableFrom(referenceType))
|
||||||
|
{
|
||||||
|
throw new GameException($"Reference type '{referenceType.FullName}' is invalid.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD>óػ<C3B3>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="referenceType"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
/// <returns><3E><><EFBFBD><EFBFBD></returns>
|
||||||
|
public static IReference Acquire(Type referenceType)
|
||||||
|
{
|
||||||
|
InternalCheckReferenceType(referenceType);
|
||||||
|
return GetReferenceCollection(referenceType).Acquire();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD>óػ<C3B3>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
|
||||||
|
/// <returns><3E><><EFBFBD><EFBFBD></returns>
|
||||||
|
public static T Acquire<T>() where T : class, IReference, new()
|
||||||
|
{
|
||||||
|
return GetReferenceCollection(typeof(T)).Acquire<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD>ù黹<C3B9><E9BBB9><EFBFBD>ó<EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reference"><3E><><EFBFBD><EFBFBD></param>
|
||||||
|
public static void Release(IReference reference)
|
||||||
|
{
|
||||||
|
if (reference == null)
|
||||||
|
{
|
||||||
|
throw new GameException("Reference is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Type referenceType = reference.GetType();
|
||||||
|
InternalCheckReferenceType(referenceType);
|
||||||
|
GetReferenceCollection(referenceType).Release(reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><D7B7>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
|
||||||
|
/// <param name="count"><><D7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
public static void Add<T>(int count) where T : class, IReference, new()
|
||||||
|
{
|
||||||
|
GetReferenceCollection(typeof(T)).Add<T>(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><D7B7>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="referenceType"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
/// <param name="count"><><D7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
public static void Add(Type referenceType, int count)
|
||||||
|
{
|
||||||
|
InternalCheckReferenceType(referenceType);
|
||||||
|
GetReferenceCollection(referenceType).Add(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>Ƴ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
|
||||||
|
/// <param name="count"><3E>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
public static void Remove<T>(int count) where T : class, IReference
|
||||||
|
{
|
||||||
|
GetReferenceCollection(typeof(T)).Remove(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>Ƴ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="referenceType"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
/// <param name="count"><3E>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
public static void Remove(Type referenceType, int count)
|
||||||
|
{
|
||||||
|
InternalCheckReferenceType(referenceType);
|
||||||
|
GetReferenceCollection(referenceType).Remove(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
|
||||||
|
public static void RemoveAll<T>() where T : class, IReference
|
||||||
|
{
|
||||||
|
GetReferenceCollection(typeof(T)).RemoveAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD>á<EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="referenceType"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͡<EFBFBD></param>
|
||||||
|
public static void RemoveAll(Type referenceType)
|
||||||
|
{
|
||||||
|
InternalCheckReferenceType(referenceType);
|
||||||
|
GetReferenceCollection(referenceType).RemoveAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Convention/[Runtime]/Convention.ReferencePool.cs.meta
Normal file
11
Convention/[Runtime]/Convention.ReferencePool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 84ff342f46113f140afa7a506fb879d4
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
803
Convention/[Runtime]/Convention.TaskPool.cs
Normal file
803
Convention/[Runtime]/Convention.TaskPool.cs
Normal file
@@ -0,0 +1,803 @@
|
|||||||
|
using Convention.Collections;
|
||||||
|
using Convention.Collections.Generic;
|
||||||
|
using Convention.ReferenceManagement;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Convention.TaskManagement
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public abstract class TaskBase: IReference
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public const int DefaultPriority = 0;
|
||||||
|
|
||||||
|
private int m_SerialId;
|
||||||
|
private string m_Tag;
|
||||||
|
private int m_Priority;
|
||||||
|
private object m_UserData;
|
||||||
|
|
||||||
|
private bool m_Done;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>
|
||||||
|
/// </summary>
|
||||||
|
public TaskBase()
|
||||||
|
{
|
||||||
|
m_SerialId = 0;
|
||||||
|
m_Tag = null;
|
||||||
|
m_Priority = DefaultPriority;
|
||||||
|
m_Done = false;
|
||||||
|
m_UserData = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public int SerialId
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_SerialId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ
|
||||||
|
/// </summary>
|
||||||
|
public string Tag
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_Tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public int Priority
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_Priority;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public object UserData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_UserData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public bool Done
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_Done;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_Done = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public virtual string Description
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="serialId"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD></param>
|
||||||
|
/// <param name="tag"><3E><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ</param>
|
||||||
|
/// <param name="priority"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD></param>
|
||||||
|
/// <param name="userData"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
internal void Initialize(int serialId, string tag, int priority, object userData)
|
||||||
|
{
|
||||||
|
m_SerialId = serialId;
|
||||||
|
m_Tag = tag;
|
||||||
|
m_Priority = priority;
|
||||||
|
m_UserData = userData;
|
||||||
|
m_Done = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Clear()
|
||||||
|
{
|
||||||
|
m_SerialId = 0;
|
||||||
|
m_Tag = null;
|
||||||
|
m_Priority = DefaultPriority;
|
||||||
|
m_UserData = null;
|
||||||
|
m_Done = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
|
||||||
|
/// </summary>
|
||||||
|
public enum StartTaskStatus : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD><CCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɴ<EFBFBD><C9B4><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
Done = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
CanResume,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD>ܼ<EFBFBD><DCBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
HasToWait,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD>ܼ<EFBFBD><DCBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F1A3ACB3><EFBFBD>δ֪<CEB4><D6AA><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
UnknownError
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
|
||||||
|
public interface ITaskAgent<T> where T : TaskBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
T Task
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
void Initialize();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="elapseSeconds"><3E><EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ</param>
|
||||||
|
/// <param name="realElapseSeconds"><3E><>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>ʱ<EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ</param>
|
||||||
|
void Update(float elapseSeconds, float realElapseSeconds);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20>رղ<D8B1><D5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="task">Ҫ<><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
/// <returns><3E><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬</returns>
|
||||||
|
StartTaskStatus Start(T task);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ֹͣ<CDA3><D6B9><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
void Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD>״̬
|
||||||
|
/// </summary>
|
||||||
|
public enum TaskStatus : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// δ<><CEB4>ʼ
|
||||||
|
/// </summary>
|
||||||
|
Todo = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ִ<><D6B4><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
Doing,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
Done
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Auto)]
|
||||||
|
public readonly struct TaskInfo
|
||||||
|
{
|
||||||
|
private readonly bool m_IsValid;
|
||||||
|
private readonly int m_SerialId;
|
||||||
|
private readonly string m_Tag;
|
||||||
|
private readonly int m_Priority;
|
||||||
|
private readonly object m_UserData;
|
||||||
|
private readonly TaskStatus m_Status;
|
||||||
|
private readonly string m_Description;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="serialId"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD></param>
|
||||||
|
/// <param name="tag"><3E><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ</param>
|
||||||
|
/// <param name="priority"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD></param>
|
||||||
|
/// <param name="userData"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
/// <param name="status"><3E><><EFBFBD><EFBFBD>״̬</param>
|
||||||
|
/// <param name="description"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
public TaskInfo(int serialId, string tag, int priority, object userData, TaskStatus status, string description)
|
||||||
|
{
|
||||||
|
m_IsValid = true;
|
||||||
|
m_SerialId = serialId;
|
||||||
|
m_Tag = tag;
|
||||||
|
m_Priority = priority;
|
||||||
|
m_UserData = userData;
|
||||||
|
m_Status = status;
|
||||||
|
m_Description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ч
|
||||||
|
/// </summary>
|
||||||
|
public bool IsValid
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_IsValid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public int SerialId
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!m_IsValid)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Data is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_SerialId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ
|
||||||
|
/// </summary>
|
||||||
|
public string Tag
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!m_IsValid)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Data is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_Tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public int Priority
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!m_IsValid)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Data is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_Priority;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public object UserData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!m_IsValid)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Data is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_UserData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>״̬
|
||||||
|
/// </summary>
|
||||||
|
public TaskStatus Status
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!m_IsValid)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Data is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public string Description
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!m_IsValid)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Data is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_Description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
|
||||||
|
public class TaskPool<T> where T : TaskBase
|
||||||
|
{
|
||||||
|
private readonly Stack<ITaskAgent<T>> m_FreeAgents;
|
||||||
|
private readonly LinkedCacheList<ITaskAgent<T>> m_WorkingAgents;
|
||||||
|
private readonly LinkedCacheList<T> m_WaitingTasks;
|
||||||
|
private bool m_Paused;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public TaskPool()
|
||||||
|
{
|
||||||
|
m_FreeAgents = new Stack<ITaskAgent<T>>();
|
||||||
|
m_WorkingAgents = new LinkedCacheList<ITaskAgent<T>>();
|
||||||
|
m_WaitingTasks = new LinkedCacheList<T>();
|
||||||
|
m_Paused = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3>
|
||||||
|
/// </summary>
|
||||||
|
public bool Paused
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_Paused;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_Paused = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public int TotalAgentCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return FreeAgentCount + WorkingAgentCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public int FreeAgentCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_FreeAgents.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public int WorkingAgentCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_WorkingAgents.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public int WaitingTaskCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_WaitingTasks.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="elapseSeconds"><3E><EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ<EFBFBD><CEBB></param>
|
||||||
|
/// <param name="realElapseSeconds"><3E><>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>ʱ<EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ<EFBFBD><CEBB></param>
|
||||||
|
public void Update(float elapseSeconds, float realElapseSeconds)
|
||||||
|
{
|
||||||
|
if (m_Paused)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessRunningTasks(elapseSeconds, realElapseSeconds);
|
||||||
|
ProcessWaitingTasks(elapseSeconds, realElapseSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20>رղ<D8B1><D5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ء<EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
public void Shutdown()
|
||||||
|
{
|
||||||
|
RemoveAllTasks();
|
||||||
|
|
||||||
|
while (FreeAgentCount > 0)
|
||||||
|
{
|
||||||
|
m_FreeAgents.Pop().Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="agent">Ҫ<><D2AA><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
public void AddAgent(ITaskAgent<T> agent)
|
||||||
|
{
|
||||||
|
if (agent == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Task agent is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
agent.Initialize();
|
||||||
|
m_FreeAgents.Push(agent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>Ż<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="serialId">Ҫ<><D2AA>ȡ<EFBFBD><C8A1>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>š<EFBFBD></param>
|
||||||
|
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2></returns>
|
||||||
|
public TaskInfo GetTaskInfo(int serialId)
|
||||||
|
{
|
||||||
|
foreach (ITaskAgent<T> workingAgent in m_WorkingAgents)
|
||||||
|
{
|
||||||
|
T workingTask = workingAgent.Task;
|
||||||
|
if (workingTask.SerialId == serialId)
|
||||||
|
{
|
||||||
|
return new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (T waitingTask in m_WaitingTasks)
|
||||||
|
{
|
||||||
|
if (waitingTask.SerialId == serialId)
|
||||||
|
{
|
||||||
|
return new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return default(TaskInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ<EFBFBD><C7A9>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tag">Ҫ<><D2AA>ȡ<EFBFBD><C8A1>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ<EFBFBD><C7A9></param>
|
||||||
|
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2></returns>
|
||||||
|
public TaskInfo[] GetTaskInfos(string tag)
|
||||||
|
{
|
||||||
|
List<TaskInfo> results = new List<TaskInfo>();
|
||||||
|
GetTaskInfos(tag, results);
|
||||||
|
return results.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ<EFBFBD><C7A9>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tag">Ҫ<><D2AA>ȡ<EFBFBD><C8A1>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ<EFBFBD><C7A9></param>
|
||||||
|
/// <param name="results"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2></param>
|
||||||
|
public void GetTaskInfos(string tag, List<TaskInfo> results)
|
||||||
|
{
|
||||||
|
if (results == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Results is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
results.Clear();
|
||||||
|
foreach (ITaskAgent<T> workingAgent in m_WorkingAgents)
|
||||||
|
{
|
||||||
|
T workingTask = workingAgent.Task;
|
||||||
|
if (workingTask.Tag == tag)
|
||||||
|
{
|
||||||
|
results.Add(new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (T waitingTask in m_WaitingTasks)
|
||||||
|
{
|
||||||
|
if (waitingTask.Tag == tag)
|
||||||
|
{
|
||||||
|
results.Add(new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2></returns>
|
||||||
|
public TaskInfo[] GetAllTaskInfos()
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
TaskInfo[] results = new TaskInfo[m_WorkingAgents.Count + m_WaitingTasks.Count];
|
||||||
|
foreach (ITaskAgent<T> workingAgent in m_WorkingAgents)
|
||||||
|
{
|
||||||
|
T workingTask = workingAgent.Task;
|
||||||
|
results[index++] = new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (T waitingTask in m_WaitingTasks)
|
||||||
|
{
|
||||||
|
results[index++] = new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description);
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="results"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2></param>
|
||||||
|
public void GetAllTaskInfos(List<TaskInfo> results)
|
||||||
|
{
|
||||||
|
if (results == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Results is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
results.Clear();
|
||||||
|
foreach (ITaskAgent<T> workingAgent in m_WorkingAgents)
|
||||||
|
{
|
||||||
|
T workingTask = workingAgent.Task;
|
||||||
|
results.Add(new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (T waitingTask in m_WaitingTasks)
|
||||||
|
{
|
||||||
|
results.Add(new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="task">Ҫ<><D2AA><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||||
|
public void AddTask(T task)
|
||||||
|
{
|
||||||
|
LinkedListNode<T> current = m_WaitingTasks.Last;
|
||||||
|
while (current != null)
|
||||||
|
{
|
||||||
|
if (task.Priority <= current.Value.Priority)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = current.Previous;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current != null)
|
||||||
|
{
|
||||||
|
m_WaitingTasks.AddAfter(current, task);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_WaitingTasks.AddFirst(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="serialId">Ҫ<>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>š<EFBFBD></param>
|
||||||
|
/// <returns><3E>Ƿ<EFBFBD><C7B7>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD></returns>
|
||||||
|
public bool RemoveTask(int serialId)
|
||||||
|
{
|
||||||
|
foreach (T task in m_WaitingTasks)
|
||||||
|
{
|
||||||
|
if (task.SerialId == serialId)
|
||||||
|
{
|
||||||
|
m_WaitingTasks.Remove(task);
|
||||||
|
ReferencePool.Release(task);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedListNode<ITaskAgent<T>> currentWorkingAgent = m_WorkingAgents.First;
|
||||||
|
while (currentWorkingAgent != null)
|
||||||
|
{
|
||||||
|
LinkedListNode<ITaskAgent<T>> next = currentWorkingAgent.Next;
|
||||||
|
ITaskAgent<T> workingAgent = currentWorkingAgent.Value;
|
||||||
|
T task = workingAgent.Task;
|
||||||
|
if (task.SerialId == serialId)
|
||||||
|
{
|
||||||
|
workingAgent.Reset();
|
||||||
|
m_FreeAgents.Push(workingAgent);
|
||||||
|
m_WorkingAgents.Remove(currentWorkingAgent);
|
||||||
|
ReferencePool.Release(task);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentWorkingAgent = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ<EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tag">Ҫ<>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ<EFBFBD><C7A9></param>
|
||||||
|
/// <returns><3E>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></returns>
|
||||||
|
public int RemoveTasks(string tag)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
LinkedListNode<T> currentWaitingTask = m_WaitingTasks.First;
|
||||||
|
while (currentWaitingTask != null)
|
||||||
|
{
|
||||||
|
LinkedListNode<T> next = currentWaitingTask.Next;
|
||||||
|
T task = currentWaitingTask.Value;
|
||||||
|
if (task.Tag == tag)
|
||||||
|
{
|
||||||
|
m_WaitingTasks.Remove(currentWaitingTask);
|
||||||
|
ReferencePool.Release(task);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentWaitingTask = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedListNode<ITaskAgent<T>> currentWorkingAgent = m_WorkingAgents.First;
|
||||||
|
while (currentWorkingAgent != null)
|
||||||
|
{
|
||||||
|
LinkedListNode<ITaskAgent<T>> next = currentWorkingAgent.Next;
|
||||||
|
ITaskAgent<T> workingAgent = currentWorkingAgent.Value;
|
||||||
|
T task = workingAgent.Task;
|
||||||
|
if (task.Tag == tag)
|
||||||
|
{
|
||||||
|
workingAgent.Reset();
|
||||||
|
m_FreeAgents.Push(workingAgent);
|
||||||
|
m_WorkingAgents.Remove(currentWorkingAgent);
|
||||||
|
ReferencePool.Release(task);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentWorkingAgent = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><3E>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></returns>
|
||||||
|
public int RemoveAllTasks()
|
||||||
|
{
|
||||||
|
int count = m_WaitingTasks.Count + m_WorkingAgents.Count;
|
||||||
|
|
||||||
|
foreach (T task in m_WaitingTasks)
|
||||||
|
{
|
||||||
|
ReferencePool.Release(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_WaitingTasks.Clear();
|
||||||
|
|
||||||
|
foreach (ITaskAgent<T> workingAgent in m_WorkingAgents)
|
||||||
|
{
|
||||||
|
T task = workingAgent.Task;
|
||||||
|
workingAgent.Reset();
|
||||||
|
m_FreeAgents.Push(workingAgent);
|
||||||
|
ReferencePool.Release(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_WorkingAgents.Clear();
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessRunningTasks(float elapseSeconds, float realElapseSeconds)
|
||||||
|
{
|
||||||
|
LinkedListNode<ITaskAgent<T>> current = m_WorkingAgents.First;
|
||||||
|
while (current != null)
|
||||||
|
{
|
||||||
|
T task = current.Value.Task;
|
||||||
|
if (!task.Done)
|
||||||
|
{
|
||||||
|
current.Value.Update(elapseSeconds, realElapseSeconds);
|
||||||
|
current = current.Next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedListNode<ITaskAgent<T>> next = current.Next;
|
||||||
|
current.Value.Reset();
|
||||||
|
m_FreeAgents.Push(current.Value);
|
||||||
|
m_WorkingAgents.Remove(current);
|
||||||
|
ReferencePool.Release(task);
|
||||||
|
current = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessWaitingTasks(float elapseSeconds, float realElapseSeconds)
|
||||||
|
{
|
||||||
|
LinkedListNode<T> current = m_WaitingTasks.First;
|
||||||
|
while (current != null && FreeAgentCount > 0)
|
||||||
|
{
|
||||||
|
ITaskAgent<T> agent = m_FreeAgents.Pop();
|
||||||
|
LinkedListNode<ITaskAgent<T>> agentNode = m_WorkingAgents.AddLast(agent);
|
||||||
|
T task = current.Value;
|
||||||
|
LinkedListNode<T> next = current.Next;
|
||||||
|
StartTaskStatus status = agent.Start(task);
|
||||||
|
if (status == StartTaskStatus.Done || status == StartTaskStatus.HasToWait || status == StartTaskStatus.UnknownError)
|
||||||
|
{
|
||||||
|
agent.Reset();
|
||||||
|
m_FreeAgents.Push(agent);
|
||||||
|
m_WorkingAgents.Remove(agentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == StartTaskStatus.Done || status == StartTaskStatus.CanResume || status == StartTaskStatus.UnknownError)
|
||||||
|
{
|
||||||
|
m_WaitingTasks.Remove(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == StartTaskStatus.Done || status == StartTaskStatus.UnknownError)
|
||||||
|
{
|
||||||
|
ReferencePool.Release(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
current = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Convention/[Runtime]/Convention.TaskPool.cs.meta
Normal file
11
Convention/[Runtime]/Convention.TaskPool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4f8c7df8532754c46b224b0cd4d0e171
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -36,7 +36,7 @@ namespace Convention
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public sealed class ToolFile
|
public class ToolFile
|
||||||
{
|
{
|
||||||
public static string[] TextFileExtensions = new string[] { "txt", "ini", "manifest" };
|
public static string[] TextFileExtensions = new string[] { "txt", "ini", "manifest" };
|
||||||
public static string[] AudioFileExtension = new string[] { "ogg", "mp2", "mp3", "mod", "wav", "it" };
|
public static string[] AudioFileExtension = new string[] { "ogg", "mp2", "mp3", "mod", "wav", "it" };
|
||||||
@@ -1264,4 +1264,23 @@ namespace Convention
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class MustExistFile : ToolFile
|
||||||
|
{
|
||||||
|
public MustExistFile(string path) : base(path)
|
||||||
|
{
|
||||||
|
MustExistsPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class DependentFile : ToolFile
|
||||||
|
{
|
||||||
|
public DependentFile(string path) : base(path)
|
||||||
|
{
|
||||||
|
if (Exists() == false)
|
||||||
|
throw new FileNotFoundException($"Dependent file not found: {path}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user