GameFrameworkBase

GameFrameworkBase
This commit is contained in:
ALEXTANG
2023-04-01 16:24:25 +08:00
parent d2e940248a
commit 2213588713
52 changed files with 1153 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 29e774698f38311488a7c2a40eb56f7b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1f66b41634e398e41a3c030782a0cc17
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,392 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace TEngine
{
/// <summary>
/// 游戏框架链表类。
/// </summary>
/// <typeparam name="T">指定链表的元素类型。</typeparam>
public sealed class GameFrameworkLinkedList<T> : ICollection<T>, IEnumerable<T>, ICollection, IEnumerable
{
private readonly LinkedList<T> m_LinkedList;
private readonly Queue<LinkedListNode<T>> m_CachedNodes;
/// <summary>
/// 初始化游戏框架链表类的新实例。
/// </summary>
public GameFrameworkLinkedList()
{
m_LinkedList = new LinkedList<T>();
m_CachedNodes = new Queue<LinkedListNode<T>>();
}
/// <summary>
/// 获取链表中实际包含的结点数量。
/// </summary>
public int Count => m_LinkedList.Count;
/// <summary>
/// 获取链表结点缓存数量。
/// </summary>
public int CachedNodeCount => m_CachedNodes.Count;
/// <summary>
/// 获取链表的第一个结点。
/// </summary>
public LinkedListNode<T> First => m_LinkedList.First;
/// <summary>
/// 获取链表的最后一个结点。
/// </summary>
public LinkedListNode<T> Last => m_LinkedList.Last;
/// <summary>
/// 获取一个值,该值指示 ICollection`1 是否为只读。
/// </summary>
public bool IsReadOnly => ((ICollection<T>)m_LinkedList).IsReadOnly;
/// <summary>
/// 获取可用于同步对 ICollection 的访问的对象。
/// </summary>
public object SyncRoot => ((ICollection)m_LinkedList).SyncRoot;
/// <summary>
/// 获取一个值,该值指示是否同步对 ICollection 的访问(线程安全)。
/// </summary>
public bool IsSynchronized => ((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 GameFrameworkException("First is invalid.");
}
m_LinkedList.RemoveFirst();
ReleaseNode(first);
}
/// <summary>
/// 移除位于链表结尾处的结点。
/// </summary>
public void RemoveLast()
{
LinkedListNode<T> last = m_LinkedList.Last;
if (last == null)
{
throw new GameFrameworkException("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 GameFrameworkException("Linked list is invalid.");
}
m_Enumerator = linkedList.GetEnumerator();
}
/// <summary>
/// 获取当前结点。
/// </summary>
public T Current => m_Enumerator.Current;
/// <summary>
/// 获取当前的枚举数。
/// </summary>
object IEnumerator.Current => 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();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 91989cb9547740bfaa7b7ed8dbd4646a
timeCreated: 1680336403

View File

@@ -0,0 +1,180 @@
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace TEngine
{
/// <summary>
/// 游戏框架链表范围。
/// </summary>
/// <typeparam name="T">指定链表范围的元素类型。</typeparam>
[StructLayout(LayoutKind.Auto)]
public struct GameFrameworkLinkedListRange<T> : IEnumerable<T>, IEnumerable
{
private readonly LinkedListNode<T> m_First;
private readonly LinkedListNode<T> m_Terminal;
/// <summary>
/// 初始化游戏框架链表范围的新实例。
/// </summary>
/// <param name="first">链表范围的开始结点。</param>
/// <param name="terminal">链表范围的终结标记结点。</param>
public GameFrameworkLinkedListRange(LinkedListNode<T> first, LinkedListNode<T> terminal)
{
if (first == null || terminal == null || first == terminal)
{
throw new GameFrameworkException("Range is invalid.");
}
m_First = first;
m_Terminal = terminal;
}
/// <summary>
/// 获取链表范围是否有效。
/// </summary>
public bool IsValid => m_First != null && m_Terminal != null && m_First != m_Terminal;
/// <summary>
/// 获取链表范围的开始结点。
/// </summary>
public LinkedListNode<T> First => m_First;
/// <summary>
/// 获取链表范围的终结标记结点。
/// </summary>
public LinkedListNode<T> Terminal => m_Terminal;
/// <summary>
/// 获取链表范围的结点数量。
/// </summary>
public int Count
{
get
{
if (!IsValid)
{
return 0;
}
int count = 0;
for (LinkedListNode<T> current = m_First; current != null && current != m_Terminal; current = current.Next)
{
count++;
}
return count;
}
}
/// <summary>
/// 检查是否包含指定值。
/// </summary>
/// <param name="value">要检查的值。</param>
/// <returns>是否包含指定值。</returns>
public bool Contains(T value)
{
for (LinkedListNode<T> current = m_First; current != null && current != m_Terminal; current = current.Next)
{
if (current.Value.Equals(value))
{
return true;
}
}
return false;
}
/// <summary>
/// 返回循环访问集合的枚举数。
/// </summary>
/// <returns>循环访问集合的枚举数。</returns>
public Enumerator GetEnumerator()
{
return new Enumerator(this);
}
/// <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 readonly GameFrameworkLinkedListRange<T> m_GameFrameworkLinkedListRange;
private LinkedListNode<T> m_Current;
private T m_CurrentValue;
internal Enumerator(GameFrameworkLinkedListRange<T> range)
{
if (!range.IsValid)
{
throw new GameFrameworkException("Range is invalid.");
}
m_GameFrameworkLinkedListRange = range;
m_Current = m_GameFrameworkLinkedListRange.m_First;
m_CurrentValue = default(T);
}
/// <summary>
/// 获取当前结点。
/// </summary>
public T Current => m_CurrentValue;
/// <summary>
/// 获取当前的枚举数。
/// </summary>
object IEnumerator.Current => m_CurrentValue;
/// <summary>
/// 清理枚举数。
/// </summary>
public void Dispose()
{
}
/// <summary>
/// 获取下一个结点。
/// </summary>
/// <returns>返回下一个结点。</returns>
public bool MoveNext()
{
if (m_Current == null || m_Current == m_GameFrameworkLinkedListRange.m_Terminal)
{
return false;
}
m_CurrentValue = m_Current.Value;
m_Current = m_Current.Next;
return true;
}
/// <summary>
/// 重置枚举数。
/// </summary>
void IEnumerator.Reset()
{
m_Current = m_GameFrameworkLinkedListRange.m_First;
m_CurrentValue = default(T);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3c15a1f4b89d404b8ff77419386ff26a
timeCreated: 1680337062

View File

@@ -0,0 +1,258 @@
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace TEngine
{
/// <summary>
/// 游戏框架多值字典类。
/// </summary>
/// <typeparam name="TKey">指定多值字典的主键类型。</typeparam>
/// <typeparam name="TValue">指定多值字典的值类型。</typeparam>
public sealed class GameFrameworkMultiDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, GameFrameworkLinkedListRange<TValue>>>, IEnumerable
{
private readonly GameFrameworkLinkedList<TValue> m_LinkedList;
private readonly Dictionary<TKey, GameFrameworkLinkedListRange<TValue>> m_Dictionary;
/// <summary>
/// 初始化游戏框架多值字典类的新实例。
/// </summary>
public GameFrameworkMultiDictionary()
{
m_LinkedList = new GameFrameworkLinkedList<TValue>();
m_Dictionary = new Dictionary<TKey, GameFrameworkLinkedListRange<TValue>>();
}
/// <summary>
/// 获取多值字典中实际包含的主键数量。
/// </summary>
public int Count => m_Dictionary.Count;
/// <summary>
/// 获取多值字典中指定主键的范围。
/// </summary>
/// <param name="key">指定的主键。</param>
/// <returns>指定主键的范围。</returns>
public GameFrameworkLinkedListRange<TValue> this[TKey key]
{
get
{
GameFrameworkLinkedListRange<TValue> range = default(GameFrameworkLinkedListRange<TValue>);
m_Dictionary.TryGetValue(key, out range);
return range;
}
}
/// <summary>
/// 清理多值字典。
/// </summary>
public void Clear()
{
m_Dictionary.Clear();
m_LinkedList.Clear();
}
/// <summary>
/// 检查多值字典中是否包含指定主键。
/// </summary>
/// <param name="key">要检查的主键。</param>
/// <returns>多值字典中是否包含指定主键。</returns>
public bool Contains(TKey key)
{
return m_Dictionary.ContainsKey(key);
}
/// <summary>
/// 检查多值字典中是否包含指定值。
/// </summary>
/// <param name="key">要检查的主键。</param>
/// <param name="value">要检查的值。</param>
/// <returns>多值字典中是否包含指定值。</returns>
public bool Contains(TKey key, TValue value)
{
GameFrameworkLinkedListRange<TValue> range = default(GameFrameworkLinkedListRange<TValue>);
if (m_Dictionary.TryGetValue(key, out range))
{
return range.Contains(value);
}
return false;
}
/// <summary>
/// 尝试获取多值字典中指定主键的范围。
/// </summary>
/// <param name="key">指定的主键。</param>
/// <param name="range">指定主键的范围。</param>
/// <returns>是否获取成功。</returns>
public bool TryGetValue(TKey key, out GameFrameworkLinkedListRange<TValue> range)
{
return m_Dictionary.TryGetValue(key, out range);
}
/// <summary>
/// 向指定的主键增加指定的值。
/// </summary>
/// <param name="key">指定的主键。</param>
/// <param name="value">指定的值。</param>
public void Add(TKey key, TValue value)
{
GameFrameworkLinkedListRange<TValue> range = default(GameFrameworkLinkedListRange<TValue>);
if (m_Dictionary.TryGetValue(key, out range))
{
m_LinkedList.AddBefore(range.Terminal, value);
}
else
{
LinkedListNode<TValue> first = m_LinkedList.AddLast(value);
LinkedListNode<TValue> terminal = m_LinkedList.AddLast(default(TValue));
m_Dictionary.Add(key, new GameFrameworkLinkedListRange<TValue>(first, terminal));
}
}
/// <summary>
/// 从指定的主键中移除指定的值。
/// </summary>
/// <param name="key">指定的主键。</param>
/// <param name="value">指定的值。</param>
/// <returns>是否移除成功。</returns>
public bool Remove(TKey key, TValue value)
{
GameFrameworkLinkedListRange<TValue> range = default(GameFrameworkLinkedListRange<TValue>);
if (m_Dictionary.TryGetValue(key, out range))
{
for (LinkedListNode<TValue> current = range.First; current != null && current != range.Terminal; current = current.Next)
{
if (current.Value.Equals(value))
{
if (current == range.First)
{
LinkedListNode<TValue> next = current.Next;
if (next == range.Terminal)
{
m_LinkedList.Remove(next);
m_Dictionary.Remove(key);
}
else
{
m_Dictionary[key] = new GameFrameworkLinkedListRange<TValue>(next, range.Terminal);
}
}
m_LinkedList.Remove(current);
return true;
}
}
}
return false;
}
/// <summary>
/// 从指定的主键中移除所有的值。
/// </summary>
/// <param name="key">指定的主键。</param>
/// <returns>是否移除成功。</returns>
public bool RemoveAll(TKey key)
{
GameFrameworkLinkedListRange<TValue> range = default(GameFrameworkLinkedListRange<TValue>);
if (m_Dictionary.TryGetValue(key, out range))
{
m_Dictionary.Remove(key);
LinkedListNode<TValue> current = range.First;
while (current != null)
{
LinkedListNode<TValue> next = current != range.Terminal ? current.Next : null;
m_LinkedList.Remove(current);
current = next;
}
return true;
}
return false;
}
/// <summary>
/// 返回循环访问集合的枚举数。
/// </summary>
/// <returns>循环访问集合的枚举数。</returns>
public Enumerator GetEnumerator()
{
return new Enumerator(m_Dictionary);
}
/// <summary>
/// 返回循环访问集合的枚举数。
/// </summary>
/// <returns>循环访问集合的枚举数。</returns>
IEnumerator<KeyValuePair<TKey, GameFrameworkLinkedListRange<TValue>>> IEnumerable<KeyValuePair<TKey, GameFrameworkLinkedListRange<TValue>>>.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// 返回循环访问集合的枚举数。
/// </summary>
/// <returns>循环访问集合的枚举数。</returns>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// 循环访问集合的枚举数。
/// </summary>
[StructLayout(LayoutKind.Auto)]
public struct Enumerator : IEnumerator<KeyValuePair<TKey, GameFrameworkLinkedListRange<TValue>>>, IEnumerator
{
private Dictionary<TKey, GameFrameworkLinkedListRange<TValue>>.Enumerator m_Enumerator;
internal Enumerator(Dictionary<TKey, GameFrameworkLinkedListRange<TValue>> dictionary)
{
if (dictionary == null)
{
throw new GameFrameworkException("Dictionary is invalid.");
}
m_Enumerator = dictionary.GetEnumerator();
}
/// <summary>
/// 获取当前结点。
/// </summary>
public KeyValuePair<TKey, GameFrameworkLinkedListRange<TValue>> Current => m_Enumerator.Current;
/// <summary>
/// 获取当前的枚举数。
/// </summary>
object IEnumerator.Current => 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<KeyValuePair<TKey, GameFrameworkLinkedListRange<TValue>>>)m_Enumerator).Reset();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4f09e27ffe754d8894a4ced69a0f90b6
timeCreated: 1680337042

View File

@@ -0,0 +1,116 @@
using System;
using System.Runtime.InteropServices;
namespace TEngine
{
/// <summary>
/// 类型和名称的组合值。
/// </summary>
[StructLayout(LayoutKind.Auto)]
internal struct TypeNamePair : IEquatable<TypeNamePair>
{
private readonly Type m_Type;
private readonly string m_Name;
/// <summary>
/// 初始化类型和名称的组合值的新实例。
/// </summary>
/// <param name="type">类型。</param>
public TypeNamePair(Type type)
: this(type, string.Empty)
{
}
/// <summary>
/// 初始化类型和名称的组合值的新实例。
/// </summary>
/// <param name="type">类型。</param>
/// <param name="name">名称。</param>
public TypeNamePair(Type type, string name)
{
if (type == null)
{
throw new GameFrameworkException("Type is invalid.");
}
m_Type = type;
m_Name = name ?? string.Empty;
}
/// <summary>
/// 获取类型。
/// </summary>
public Type Type => m_Type;
/// <summary>
/// 获取名称。
/// </summary>
public string Name => m_Name;
/// <summary>
/// 获取类型和名称的组合值字符串。
/// </summary>
/// <returns>类型和名称的组合值字符串。</returns>
public override string ToString()
{
if (m_Type == null)
{
throw new GameFrameworkException("Type is invalid.");
}
string typeName = m_Type.FullName;
return string.IsNullOrEmpty(m_Name) ? typeName : Utility.Text.Format("{0}.{1}", typeName, m_Name);
}
/// <summary>
/// 获取对象的哈希值。
/// </summary>
/// <returns>对象的哈希值。</returns>
public override int GetHashCode()
{
return m_Type.GetHashCode() ^ m_Name.GetHashCode();
}
/// <summary>
/// 比较对象是否与自身相等。
/// </summary>
/// <param name="obj">要比较的对象。</param>
/// <returns>被比较的对象是否与自身相等。</returns>
public override bool Equals(object obj)
{
return obj is TypeNamePair && Equals((TypeNamePair)obj);
}
/// <summary>
/// 比较对象是否与自身相等。
/// </summary>
/// <param name="value">要比较的对象。</param>
/// <returns>被比较的对象是否与自身相等。</returns>
public bool Equals(TypeNamePair value)
{
return m_Type == value.m_Type && m_Name == value.m_Name;
}
/// <summary>
/// 判断两个对象是否相等。
/// </summary>
/// <param name="a">值 a。</param>
/// <param name="b">值 b。</param>
/// <returns>两个对象是否相等。</returns>
public static bool operator ==(TypeNamePair a, TypeNamePair b)
{
return a.Equals(b);
}
/// <summary>
/// 判断两个对象是否不相等。
/// </summary>
/// <param name="a">值 a。</param>
/// <param name="b">值 b。</param>
/// <returns>两个对象是否不相等。</returns>
public static bool operator !=(TypeNamePair a, TypeNamePair b)
{
return !(a == b);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7f6fa0da056e31b4bb6d9a31b5da6af8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
namespace TEngine
{
/// <summary>
/// 游戏框架入口。
/// </summary>
public static class GameFrameworkEntry
{
private static readonly GameFrameworkLinkedList<GameFrameworkModule> GameFrameworkModules = new GameFrameworkLinkedList<GameFrameworkModule>();
/// <summary>
/// 所有游戏框架模块轮询。
/// </summary>
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
public static void Update(float elapseSeconds, float realElapseSeconds)
{
foreach (GameFrameworkModule module in GameFrameworkModules)
{
module.Update(elapseSeconds, realElapseSeconds);
}
}
/// <summary>
/// 关闭并清理所有游戏框架模块。
/// </summary>
public static void Shutdown()
{
for (LinkedListNode<GameFrameworkModule> current = GameFrameworkModules.Last; current != null; current = current.Previous)
{
current.Value.Shutdown();
}
GameFrameworkModules.Clear();
MemoryPool.ClearAll();
Utility.Marshal.FreeCachedHGlobal();
GameFrameworkLog.SetLogHelper(null);
}
/// <summary>
/// 获取游戏框架模块。
/// </summary>
/// <typeparam name="T">要获取的游戏框架模块类型。</typeparam>
/// <returns>要获取的游戏框架模块。</returns>
/// <remarks>如果要获取的游戏框架模块不存在,则自动创建该游戏框架模块。</remarks>
public static T GetModule<T>() where T : class
{
Type interfaceType = typeof(T);
// if (!interfaceType.IsInterface)
// {
// throw new GameFrameworkException(Utility.Text.Format("You must get module by interface, but '{0}' is not.", interfaceType.FullName));
// }
if (!interfaceType.FullName.StartsWith("GameFramework.", StringComparison.Ordinal))
{
throw new GameFrameworkException(Utility.Text.Format("You must get a Game Framework module, but '{0}' is not.", interfaceType.FullName));
}
string moduleName = Utility.Text.Format("{0}.{1}", interfaceType.Namespace, interfaceType.Name.Substring(1));
Type moduleType = Type.GetType(moduleName);
if (moduleType == null)
{
moduleName = Utility.Text.Format("{0}.{1}", interfaceType.Namespace, interfaceType.Name);
moduleType = Type.GetType(moduleName);
if (moduleType == null)
{
throw new GameFrameworkException(Utility.Text.Format("Can not find Game Framework module type '{0}'.", moduleName));
}
}
return GetModule(moduleType) as T;
}
/// <summary>
/// 获取游戏框架模块。
/// </summary>
/// <param name="moduleType">要获取的游戏框架模块类型。</param>
/// <returns>要获取的游戏框架模块。</returns>
/// <remarks>如果要获取的游戏框架模块不存在,则自动创建该游戏框架模块。</remarks>
private static GameFrameworkModule GetModule(Type moduleType)
{
foreach (GameFrameworkModule module in GameFrameworkModules)
{
if (module.GetType() == moduleType)
{
return module;
}
}
return CreateModule(moduleType);
}
/// <summary>
/// 创建游戏框架模块。
/// </summary>
/// <param name="moduleType">要创建的游戏框架模块类型。</param>
/// <returns>要创建的游戏框架模块。</returns>
private static GameFrameworkModule CreateModule(Type moduleType)
{
GameFrameworkModule module = (GameFrameworkModule)Activator.CreateInstance(moduleType);
if (module == null)
{
throw new GameFrameworkException(Utility.Text.Format("Can not create module '{0}'.", moduleType.FullName));
}
LinkedListNode<GameFrameworkModule> current = GameFrameworkModules.First;
while (current != null)
{
if (module.Priority > current.Value.Priority)
{
break;
}
current = current.Next;
}
if (current != null)
{
GameFrameworkModules.AddBefore(current, module);
}
else
{
GameFrameworkModules.AddLast(module);
}
return module;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 31ef1cbcd71f47629a509e5171661a52
timeCreated: 1680336346

View File

@@ -0,0 +1,26 @@
namespace TEngine
{
/// <summary>
/// 游戏框架模块抽象类。
/// </summary>
internal abstract class GameFrameworkModule
{
/// <summary>
/// 获取游戏框架模块优先级。
/// </summary>
/// <remarks>优先级较高的模块会优先轮询,并且关闭操作会后进行。</remarks>
internal virtual int Priority => 0;
/// <summary>
/// 游戏框架模块轮询。
/// </summary>
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
internal abstract void Update(float elapseSeconds, float realElapseSeconds);
/// <summary>
/// 关闭并清理游戏框架模块。
/// </summary>
internal abstract void Shutdown();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 23d586f8d3656a043ab81d1fdc0683d7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: