diff --git a/Assets/TEngine/Runtime/GameFramework.meta b/Assets/TEngine/Runtime/GameFramework.meta new file mode 100644 index 00000000..7cb67d16 --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 29e774698f38311488a7c2a40eb56f7b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/GameFramework/DataStruct.meta b/Assets/TEngine/Runtime/GameFramework/DataStruct.meta new file mode 100644 index 00000000..b25992aa --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/DataStruct.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1f66b41634e398e41a3c030782a0cc17 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkLinkedList.cs b/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkLinkedList.cs new file mode 100644 index 00000000..11ac4e53 --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkLinkedList.cs @@ -0,0 +1,392 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace TEngine +{ + /// + /// 游戏框架链表类。 + /// + /// 指定链表的元素类型。 + public sealed class GameFrameworkLinkedList : ICollection, IEnumerable, ICollection, IEnumerable + { + private readonly LinkedList m_LinkedList; + private readonly Queue> m_CachedNodes; + + /// + /// 初始化游戏框架链表类的新实例。 + /// + public GameFrameworkLinkedList() + { + m_LinkedList = new LinkedList(); + m_CachedNodes = new Queue>(); + } + + /// + /// 获取链表中实际包含的结点数量。 + /// + public int Count => m_LinkedList.Count; + + /// + /// 获取链表结点缓存数量。 + /// + public int CachedNodeCount => m_CachedNodes.Count; + + /// + /// 获取链表的第一个结点。 + /// + public LinkedListNode First => m_LinkedList.First; + + /// + /// 获取链表的最后一个结点。 + /// + public LinkedListNode Last => m_LinkedList.Last; + + /// + /// 获取一个值,该值指示 ICollection`1 是否为只读。 + /// + public bool IsReadOnly => ((ICollection)m_LinkedList).IsReadOnly; + + /// + /// 获取可用于同步对 ICollection 的访问的对象。 + /// + public object SyncRoot => ((ICollection)m_LinkedList).SyncRoot; + + /// + /// 获取一个值,该值指示是否同步对 ICollection 的访问(线程安全)。 + /// + public bool IsSynchronized => ((ICollection)m_LinkedList).IsSynchronized; + + /// + /// 在链表中指定的现有结点后添加包含指定值的新结点。 + /// + /// 指定的现有结点。 + /// 指定值。 + /// 包含指定值的新结点。 + public LinkedListNode AddAfter(LinkedListNode node, T value) + { + LinkedListNode newNode = AcquireNode(value); + m_LinkedList.AddAfter(node, newNode); + return newNode; + } + + /// + /// 在链表中指定的现有结点后添加指定的新结点。 + /// + /// 指定的现有结点。 + /// 指定的新结点。 + public void AddAfter(LinkedListNode node, LinkedListNode newNode) + { + m_LinkedList.AddAfter(node, newNode); + } + + /// + /// 在链表中指定的现有结点前添加包含指定值的新结点。 + /// + /// 指定的现有结点。 + /// 指定值。 + /// 包含指定值的新结点。 + public LinkedListNode AddBefore(LinkedListNode node, T value) + { + LinkedListNode newNode = AcquireNode(value); + m_LinkedList.AddBefore(node, newNode); + return newNode; + } + + /// + /// 在链表中指定的现有结点前添加指定的新结点。 + /// + /// 指定的现有结点。 + /// 指定的新结点。 + public void AddBefore(LinkedListNode node, LinkedListNode newNode) + { + m_LinkedList.AddBefore(node, newNode); + } + + /// + /// 在链表的开头处添加包含指定值的新结点。 + /// + /// 指定值。 + /// 包含指定值的新结点。 + public LinkedListNode AddFirst(T value) + { + LinkedListNode node = AcquireNode(value); + m_LinkedList.AddFirst(node); + return node; + } + + /// + /// 在链表的开头处添加指定的新结点。 + /// + /// 指定的新结点。 + public void AddFirst(LinkedListNode node) + { + m_LinkedList.AddFirst(node); + } + + /// + /// 在链表的结尾处添加包含指定值的新结点。 + /// + /// 指定值。 + /// 包含指定值的新结点。 + public LinkedListNode AddLast(T value) + { + LinkedListNode node = AcquireNode(value); + m_LinkedList.AddLast(node); + return node; + } + + /// + /// 在链表的结尾处添加指定的新结点。 + /// + /// 指定的新结点。 + public void AddLast(LinkedListNode node) + { + m_LinkedList.AddLast(node); + } + + /// + /// 从链表中移除所有结点。 + /// + public void Clear() + { + LinkedListNode current = m_LinkedList.First; + while (current != null) + { + ReleaseNode(current); + current = current.Next; + } + + m_LinkedList.Clear(); + } + + /// + /// 清除链表结点缓存。 + /// + public void ClearCachedNodes() + { + m_CachedNodes.Clear(); + } + + /// + /// 确定某值是否在链表中。 + /// + /// 指定值。 + /// 某值是否在链表中。 + public bool Contains(T value) + { + return m_LinkedList.Contains(value); + } + + /// + /// 从目标数组的指定索引处开始将整个链表复制到兼容的一维数组。 + /// + /// 一维数组,它是从链表复制的元素的目标。数组必须具有从零开始的索引。 + /// array 中从零开始的索引,从此处开始复制。 + public void CopyTo(T[] array, int index) + { + m_LinkedList.CopyTo(array, index); + } + + /// + /// 从特定的 ICollection 索引开始,将数组的元素复制到一个数组中。 + /// + /// 一维数组,它是从 ICollection 复制的元素的目标。数组必须具有从零开始的索引。 + /// array 中从零开始的索引,从此处开始复制。 + public void CopyTo(Array array, int index) + { + ((ICollection)m_LinkedList).CopyTo(array, index); + } + + /// + /// 查找包含指定值的第一个结点。 + /// + /// 要查找的指定值。 + /// 包含指定值的第一个结点。 + public LinkedListNode Find(T value) + { + return m_LinkedList.Find(value); + } + + /// + /// 查找包含指定值的最后一个结点。 + /// + /// 要查找的指定值。 + /// 包含指定值的最后一个结点。 + public LinkedListNode FindLast(T value) + { + return m_LinkedList.FindLast(value); + } + + /// + /// 从链表中移除指定值的第一个匹配项。 + /// + /// 指定值。 + /// 是否移除成功。 + public bool Remove(T value) + { + LinkedListNode node = m_LinkedList.Find(value); + if (node != null) + { + m_LinkedList.Remove(node); + ReleaseNode(node); + return true; + } + + return false; + } + + /// + /// 从链表中移除指定的结点。 + /// + /// 指定的结点。 + public void Remove(LinkedListNode node) + { + m_LinkedList.Remove(node); + ReleaseNode(node); + } + + /// + /// 移除位于链表开头处的结点。 + /// + public void RemoveFirst() + { + LinkedListNode first = m_LinkedList.First; + if (first == null) + { + throw new GameFrameworkException("First is invalid."); + } + + m_LinkedList.RemoveFirst(); + ReleaseNode(first); + } + + /// + /// 移除位于链表结尾处的结点。 + /// + public void RemoveLast() + { + LinkedListNode last = m_LinkedList.Last; + if (last == null) + { + throw new GameFrameworkException("Last is invalid."); + } + + m_LinkedList.RemoveLast(); + ReleaseNode(last); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + public Enumerator GetEnumerator() + { + return new Enumerator(m_LinkedList); + } + + private LinkedListNode AcquireNode(T value) + { + LinkedListNode node = null; + if (m_CachedNodes.Count > 0) + { + node = m_CachedNodes.Dequeue(); + node.Value = value; + } + else + { + node = new LinkedListNode(value); + } + + return node; + } + + private void ReleaseNode(LinkedListNode node) + { + node.Value = default(T); + m_CachedNodes.Enqueue(node); + } + + /// + /// 将值添加到 ICollection`1 的结尾处。 + /// + /// 要添加的值。 + void ICollection.Add(T value) + { + AddLast(value); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// 循环访问集合的枚举数。 + /// + [StructLayout(LayoutKind.Auto)] + public struct Enumerator : IEnumerator, IEnumerator + { + private LinkedList.Enumerator m_Enumerator; + + internal Enumerator(LinkedList linkedList) + { + if (linkedList == null) + { + throw new GameFrameworkException("Linked list is invalid."); + } + + m_Enumerator = linkedList.GetEnumerator(); + } + + /// + /// 获取当前结点。 + /// + public T Current => m_Enumerator.Current; + + /// + /// 获取当前的枚举数。 + /// + object IEnumerator.Current => m_Enumerator.Current; + + /// + /// 清理枚举数。 + /// + public void Dispose() + { + m_Enumerator.Dispose(); + } + + /// + /// 获取下一个结点。 + /// + /// 返回下一个结点。 + public bool MoveNext() + { + return m_Enumerator.MoveNext(); + } + + /// + /// 重置枚举数。 + /// + void IEnumerator.Reset() + { + ((IEnumerator)m_Enumerator).Reset(); + } + } + } +} diff --git a/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkLinkedList.cs.meta b/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkLinkedList.cs.meta new file mode 100644 index 00000000..83842970 --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkLinkedList.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 91989cb9547740bfaa7b7ed8dbd4646a +timeCreated: 1680336403 \ No newline at end of file diff --git a/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkLinkedListRange.cs b/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkLinkedListRange.cs new file mode 100644 index 00000000..d68f84a5 --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkLinkedListRange.cs @@ -0,0 +1,180 @@ +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace TEngine +{ + /// + /// 游戏框架链表范围。 + /// + /// 指定链表范围的元素类型。 + [StructLayout(LayoutKind.Auto)] + public struct GameFrameworkLinkedListRange : IEnumerable, IEnumerable + { + private readonly LinkedListNode m_First; + private readonly LinkedListNode m_Terminal; + + /// + /// 初始化游戏框架链表范围的新实例。 + /// + /// 链表范围的开始结点。 + /// 链表范围的终结标记结点。 + public GameFrameworkLinkedListRange(LinkedListNode first, LinkedListNode terminal) + { + if (first == null || terminal == null || first == terminal) + { + throw new GameFrameworkException("Range is invalid."); + } + + m_First = first; + m_Terminal = terminal; + } + + /// + /// 获取链表范围是否有效。 + /// + public bool IsValid => m_First != null && m_Terminal != null && m_First != m_Terminal; + + /// + /// 获取链表范围的开始结点。 + /// + public LinkedListNode First => m_First; + + /// + /// 获取链表范围的终结标记结点。 + /// + public LinkedListNode Terminal => m_Terminal; + + /// + /// 获取链表范围的结点数量。 + /// + public int Count + { + get + { + if (!IsValid) + { + return 0; + } + + int count = 0; + for (LinkedListNode current = m_First; current != null && current != m_Terminal; current = current.Next) + { + count++; + } + + return count; + } + } + + /// + /// 检查是否包含指定值。 + /// + /// 要检查的值。 + /// 是否包含指定值。 + public bool Contains(T value) + { + for (LinkedListNode current = m_First; current != null && current != m_Terminal; current = current.Next) + { + if (current.Value.Equals(value)) + { + return true; + } + } + + return false; + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + public Enumerator GetEnumerator() + { + return new Enumerator(this); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// 循环访问集合的枚举数。 + /// + [StructLayout(LayoutKind.Auto)] + public struct Enumerator : IEnumerator, IEnumerator + { + private readonly GameFrameworkLinkedListRange m_GameFrameworkLinkedListRange; + private LinkedListNode m_Current; + private T m_CurrentValue; + + internal Enumerator(GameFrameworkLinkedListRange range) + { + if (!range.IsValid) + { + throw new GameFrameworkException("Range is invalid."); + } + + m_GameFrameworkLinkedListRange = range; + m_Current = m_GameFrameworkLinkedListRange.m_First; + m_CurrentValue = default(T); + } + + /// + /// 获取当前结点。 + /// + public T Current => m_CurrentValue; + + /// + /// 获取当前的枚举数。 + /// + object IEnumerator.Current => m_CurrentValue; + + /// + /// 清理枚举数。 + /// + public void Dispose() + { + } + + /// + /// 获取下一个结点。 + /// + /// 返回下一个结点。 + 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; + } + + /// + /// 重置枚举数。 + /// + void IEnumerator.Reset() + { + m_Current = m_GameFrameworkLinkedListRange.m_First; + m_CurrentValue = default(T); + } + } + } +} diff --git a/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkLinkedListRange.cs.meta b/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkLinkedListRange.cs.meta new file mode 100644 index 00000000..f033cc9a --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkLinkedListRange.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3c15a1f4b89d404b8ff77419386ff26a +timeCreated: 1680337062 \ No newline at end of file diff --git a/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkMultiDictionary.cs b/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkMultiDictionary.cs new file mode 100644 index 00000000..0296aaf3 --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkMultiDictionary.cs @@ -0,0 +1,258 @@ +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace TEngine +{ + /// + /// 游戏框架多值字典类。 + /// + /// 指定多值字典的主键类型。 + /// 指定多值字典的值类型。 + public sealed class GameFrameworkMultiDictionary : IEnumerable>>, IEnumerable + { + private readonly GameFrameworkLinkedList m_LinkedList; + private readonly Dictionary> m_Dictionary; + + /// + /// 初始化游戏框架多值字典类的新实例。 + /// + public GameFrameworkMultiDictionary() + { + m_LinkedList = new GameFrameworkLinkedList(); + m_Dictionary = new Dictionary>(); + } + + /// + /// 获取多值字典中实际包含的主键数量。 + /// + public int Count => m_Dictionary.Count; + + /// + /// 获取多值字典中指定主键的范围。 + /// + /// 指定的主键。 + /// 指定主键的范围。 + public GameFrameworkLinkedListRange this[TKey key] + { + get + { + GameFrameworkLinkedListRange range = default(GameFrameworkLinkedListRange); + m_Dictionary.TryGetValue(key, out range); + return range; + } + } + + /// + /// 清理多值字典。 + /// + public void Clear() + { + m_Dictionary.Clear(); + m_LinkedList.Clear(); + } + + /// + /// 检查多值字典中是否包含指定主键。 + /// + /// 要检查的主键。 + /// 多值字典中是否包含指定主键。 + public bool Contains(TKey key) + { + return m_Dictionary.ContainsKey(key); + } + + /// + /// 检查多值字典中是否包含指定值。 + /// + /// 要检查的主键。 + /// 要检查的值。 + /// 多值字典中是否包含指定值。 + public bool Contains(TKey key, TValue value) + { + GameFrameworkLinkedListRange range = default(GameFrameworkLinkedListRange); + if (m_Dictionary.TryGetValue(key, out range)) + { + return range.Contains(value); + } + + return false; + } + + /// + /// 尝试获取多值字典中指定主键的范围。 + /// + /// 指定的主键。 + /// 指定主键的范围。 + /// 是否获取成功。 + public bool TryGetValue(TKey key, out GameFrameworkLinkedListRange range) + { + return m_Dictionary.TryGetValue(key, out range); + } + + /// + /// 向指定的主键增加指定的值。 + /// + /// 指定的主键。 + /// 指定的值。 + public void Add(TKey key, TValue value) + { + GameFrameworkLinkedListRange range = default(GameFrameworkLinkedListRange); + if (m_Dictionary.TryGetValue(key, out range)) + { + m_LinkedList.AddBefore(range.Terminal, value); + } + else + { + LinkedListNode first = m_LinkedList.AddLast(value); + LinkedListNode terminal = m_LinkedList.AddLast(default(TValue)); + m_Dictionary.Add(key, new GameFrameworkLinkedListRange(first, terminal)); + } + } + + /// + /// 从指定的主键中移除指定的值。 + /// + /// 指定的主键。 + /// 指定的值。 + /// 是否移除成功。 + public bool Remove(TKey key, TValue value) + { + GameFrameworkLinkedListRange range = default(GameFrameworkLinkedListRange); + if (m_Dictionary.TryGetValue(key, out range)) + { + for (LinkedListNode current = range.First; current != null && current != range.Terminal; current = current.Next) + { + if (current.Value.Equals(value)) + { + if (current == range.First) + { + LinkedListNode next = current.Next; + if (next == range.Terminal) + { + m_LinkedList.Remove(next); + m_Dictionary.Remove(key); + } + else + { + m_Dictionary[key] = new GameFrameworkLinkedListRange(next, range.Terminal); + } + } + + m_LinkedList.Remove(current); + return true; + } + } + } + + return false; + } + + /// + /// 从指定的主键中移除所有的值。 + /// + /// 指定的主键。 + /// 是否移除成功。 + public bool RemoveAll(TKey key) + { + GameFrameworkLinkedListRange range = default(GameFrameworkLinkedListRange); + if (m_Dictionary.TryGetValue(key, out range)) + { + m_Dictionary.Remove(key); + + LinkedListNode current = range.First; + while (current != null) + { + LinkedListNode next = current != range.Terminal ? current.Next : null; + m_LinkedList.Remove(current); + current = next; + } + + return true; + } + + return false; + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + public Enumerator GetEnumerator() + { + return new Enumerator(m_Dictionary); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + IEnumerator>> IEnumerable>>.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// 返回循环访问集合的枚举数。 + /// + /// 循环访问集合的枚举数。 + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// 循环访问集合的枚举数。 + /// + [StructLayout(LayoutKind.Auto)] + public struct Enumerator : IEnumerator>>, IEnumerator + { + private Dictionary>.Enumerator m_Enumerator; + + internal Enumerator(Dictionary> dictionary) + { + if (dictionary == null) + { + throw new GameFrameworkException("Dictionary is invalid."); + } + + m_Enumerator = dictionary.GetEnumerator(); + } + + /// + /// 获取当前结点。 + /// + public KeyValuePair> Current => m_Enumerator.Current; + + /// + /// 获取当前的枚举数。 + /// + object IEnumerator.Current => m_Enumerator.Current; + + /// + /// 清理枚举数。 + /// + public void Dispose() + { + m_Enumerator.Dispose(); + } + + /// + /// 获取下一个结点。 + /// + /// 返回下一个结点。 + public bool MoveNext() + { + return m_Enumerator.MoveNext(); + } + + /// + /// 重置枚举数。 + /// + void IEnumerator.Reset() + { + ((IEnumerator>>)m_Enumerator).Reset(); + } + } + } +} diff --git a/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkMultiDictionary.cs.meta b/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkMultiDictionary.cs.meta new file mode 100644 index 00000000..340b2e56 --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/DataStruct/GameFrameworkMultiDictionary.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4f09e27ffe754d8894a4ced69a0f90b6 +timeCreated: 1680337042 \ No newline at end of file diff --git a/Assets/TEngine/Runtime/GameFramework/DataStruct/TypeNamePair.cs b/Assets/TEngine/Runtime/GameFramework/DataStruct/TypeNamePair.cs new file mode 100644 index 00000000..f732c6fb --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/DataStruct/TypeNamePair.cs @@ -0,0 +1,116 @@ +using System; +using System.Runtime.InteropServices; + +namespace TEngine +{ + /// + /// 类型和名称的组合值。 + /// + [StructLayout(LayoutKind.Auto)] + internal struct TypeNamePair : IEquatable + { + private readonly Type m_Type; + private readonly string m_Name; + + /// + /// 初始化类型和名称的组合值的新实例。 + /// + /// 类型。 + public TypeNamePair(Type type) + : this(type, string.Empty) + { + } + + /// + /// 初始化类型和名称的组合值的新实例。 + /// + /// 类型。 + /// 名称。 + public TypeNamePair(Type type, string name) + { + if (type == null) + { + throw new GameFrameworkException("Type is invalid."); + } + + m_Type = type; + m_Name = name ?? string.Empty; + } + + /// + /// 获取类型。 + /// + public Type Type => m_Type; + + /// + /// 获取名称。 + /// + public string Name => m_Name; + + /// + /// 获取类型和名称的组合值字符串。 + /// + /// 类型和名称的组合值字符串。 + 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); + } + + /// + /// 获取对象的哈希值。 + /// + /// 对象的哈希值。 + public override int GetHashCode() + { + return m_Type.GetHashCode() ^ m_Name.GetHashCode(); + } + + /// + /// 比较对象是否与自身相等。 + /// + /// 要比较的对象。 + /// 被比较的对象是否与自身相等。 + public override bool Equals(object obj) + { + return obj is TypeNamePair && Equals((TypeNamePair)obj); + } + + /// + /// 比较对象是否与自身相等。 + /// + /// 要比较的对象。 + /// 被比较的对象是否与自身相等。 + public bool Equals(TypeNamePair value) + { + return m_Type == value.m_Type && m_Name == value.m_Name; + } + + /// + /// 判断两个对象是否相等。 + /// + /// 值 a。 + /// 值 b。 + /// 两个对象是否相等。 + public static bool operator ==(TypeNamePair a, TypeNamePair b) + { + return a.Equals(b); + } + + /// + /// 判断两个对象是否不相等。 + /// + /// 值 a。 + /// 值 b。 + /// 两个对象是否不相等。 + public static bool operator !=(TypeNamePair a, TypeNamePair b) + { + return !(a == b); + } + } +} diff --git a/Assets/TEngine/Runtime/GameFramework/DataStruct/TypeNamePair.cs.meta b/Assets/TEngine/Runtime/GameFramework/DataStruct/TypeNamePair.cs.meta new file mode 100644 index 00000000..b0031d60 --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/DataStruct/TypeNamePair.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f6fa0da056e31b4bb6d9a31b5da6af8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/Exception.meta b/Assets/TEngine/Runtime/GameFramework/Exception.meta similarity index 100% rename from Assets/TEngine/Runtime/Exception.meta rename to Assets/TEngine/Runtime/GameFramework/Exception.meta diff --git a/Assets/TEngine/Runtime/Exception/GameFrameworkException.cs b/Assets/TEngine/Runtime/GameFramework/Exception/GameFrameworkException.cs similarity index 100% rename from Assets/TEngine/Runtime/Exception/GameFrameworkException.cs rename to Assets/TEngine/Runtime/GameFramework/Exception/GameFrameworkException.cs diff --git a/Assets/TEngine/Runtime/Exception/GameFrameworkException.cs.meta b/Assets/TEngine/Runtime/GameFramework/Exception/GameFrameworkException.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/Exception/GameFrameworkException.cs.meta rename to Assets/TEngine/Runtime/GameFramework/Exception/GameFrameworkException.cs.meta diff --git a/Assets/TEngine/Runtime/GameEvent.meta b/Assets/TEngine/Runtime/GameFramework/GameEvent.meta similarity index 100% rename from Assets/TEngine/Runtime/GameEvent.meta rename to Assets/TEngine/Runtime/GameFramework/GameEvent.meta diff --git a/Assets/TEngine/Runtime/GameEvent/EventDispatcher.cs b/Assets/TEngine/Runtime/GameFramework/GameEvent/EventDispatcher.cs similarity index 100% rename from Assets/TEngine/Runtime/GameEvent/EventDispatcher.cs rename to Assets/TEngine/Runtime/GameFramework/GameEvent/EventDispatcher.cs diff --git a/Assets/TEngine/Runtime/GameEvent/EventDispatcher.cs.meta b/Assets/TEngine/Runtime/GameFramework/GameEvent/EventDispatcher.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/GameEvent/EventDispatcher.cs.meta rename to Assets/TEngine/Runtime/GameFramework/GameEvent/EventDispatcher.cs.meta diff --git a/Assets/TEngine/Runtime/GameEvent/EventInterfaceAttribute.cs b/Assets/TEngine/Runtime/GameFramework/GameEvent/EventInterfaceAttribute.cs similarity index 100% rename from Assets/TEngine/Runtime/GameEvent/EventInterfaceAttribute.cs rename to Assets/TEngine/Runtime/GameFramework/GameEvent/EventInterfaceAttribute.cs diff --git a/Assets/TEngine/Runtime/GameEvent/EventInterfaceAttribute.cs.meta b/Assets/TEngine/Runtime/GameFramework/GameEvent/EventInterfaceAttribute.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/GameEvent/EventInterfaceAttribute.cs.meta rename to Assets/TEngine/Runtime/GameFramework/GameEvent/EventInterfaceAttribute.cs.meta diff --git a/Assets/TEngine/Runtime/GameEvent/EventMgr.cs b/Assets/TEngine/Runtime/GameFramework/GameEvent/EventMgr.cs similarity index 100% rename from Assets/TEngine/Runtime/GameEvent/EventMgr.cs rename to Assets/TEngine/Runtime/GameFramework/GameEvent/EventMgr.cs diff --git a/Assets/TEngine/Runtime/GameEvent/EventMgr.cs.meta b/Assets/TEngine/Runtime/GameFramework/GameEvent/EventMgr.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/GameEvent/EventMgr.cs.meta rename to Assets/TEngine/Runtime/GameFramework/GameEvent/EventMgr.cs.meta diff --git a/Assets/TEngine/Runtime/GameEvent/GameEvent.cs b/Assets/TEngine/Runtime/GameFramework/GameEvent/GameEvent.cs similarity index 100% rename from Assets/TEngine/Runtime/GameEvent/GameEvent.cs rename to Assets/TEngine/Runtime/GameFramework/GameEvent/GameEvent.cs diff --git a/Assets/TEngine/Runtime/GameEvent/GameEvent.cs.meta b/Assets/TEngine/Runtime/GameFramework/GameEvent/GameEvent.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/GameEvent/GameEvent.cs.meta rename to Assets/TEngine/Runtime/GameFramework/GameEvent/GameEvent.cs.meta diff --git a/Assets/TEngine/Runtime/GameEvent/GameEventMgr.cs b/Assets/TEngine/Runtime/GameFramework/GameEvent/GameEventMgr.cs similarity index 100% rename from Assets/TEngine/Runtime/GameEvent/GameEventMgr.cs rename to Assets/TEngine/Runtime/GameFramework/GameEvent/GameEventMgr.cs diff --git a/Assets/TEngine/Runtime/GameEvent/GameEventMgr.cs.meta b/Assets/TEngine/Runtime/GameFramework/GameEvent/GameEventMgr.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/GameEvent/GameEventMgr.cs.meta rename to Assets/TEngine/Runtime/GameFramework/GameEvent/GameEventMgr.cs.meta diff --git a/Assets/TEngine/Runtime/GameEvent/StringId.cs b/Assets/TEngine/Runtime/GameFramework/GameEvent/StringId.cs similarity index 100% rename from Assets/TEngine/Runtime/GameEvent/StringId.cs rename to Assets/TEngine/Runtime/GameFramework/GameEvent/StringId.cs diff --git a/Assets/TEngine/Runtime/GameEvent/StringId.cs.meta b/Assets/TEngine/Runtime/GameFramework/GameEvent/StringId.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/GameEvent/StringId.cs.meta rename to Assets/TEngine/Runtime/GameFramework/GameEvent/StringId.cs.meta diff --git a/Assets/TEngine/Runtime/GameFramework/GameFrameworkEntry.cs b/Assets/TEngine/Runtime/GameFramework/GameFrameworkEntry.cs new file mode 100644 index 00000000..cf71cc09 --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/GameFrameworkEntry.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; + +namespace TEngine +{ + /// + /// 游戏框架入口。 + /// + public static class GameFrameworkEntry + { + private static readonly GameFrameworkLinkedList GameFrameworkModules = new GameFrameworkLinkedList(); + + /// + /// 所有游戏框架模块轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public static void Update(float elapseSeconds, float realElapseSeconds) + { + foreach (GameFrameworkModule module in GameFrameworkModules) + { + module.Update(elapseSeconds, realElapseSeconds); + } + } + + /// + /// 关闭并清理所有游戏框架模块。 + /// + public static void Shutdown() + { + for (LinkedListNode current = GameFrameworkModules.Last; current != null; current = current.Previous) + { + current.Value.Shutdown(); + } + + GameFrameworkModules.Clear(); + MemoryPool.ClearAll(); + Utility.Marshal.FreeCachedHGlobal(); + GameFrameworkLog.SetLogHelper(null); + } + + /// + /// 获取游戏框架模块。 + /// + /// 要获取的游戏框架模块类型。 + /// 要获取的游戏框架模块。 + /// 如果要获取的游戏框架模块不存在,则自动创建该游戏框架模块。 + public static T GetModule() 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; + } + + /// + /// 获取游戏框架模块。 + /// + /// 要获取的游戏框架模块类型。 + /// 要获取的游戏框架模块。 + /// 如果要获取的游戏框架模块不存在,则自动创建该游戏框架模块。 + private static GameFrameworkModule GetModule(Type moduleType) + { + foreach (GameFrameworkModule module in GameFrameworkModules) + { + if (module.GetType() == moduleType) + { + return module; + } + } + + return CreateModule(moduleType); + } + + /// + /// 创建游戏框架模块。 + /// + /// 要创建的游戏框架模块类型。 + /// 要创建的游戏框架模块。 + 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 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; + } + } +} diff --git a/Assets/TEngine/Runtime/GameFramework/GameFrameworkEntry.cs.meta b/Assets/TEngine/Runtime/GameFramework/GameFrameworkEntry.cs.meta new file mode 100644 index 00000000..cbf4d67e --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/GameFrameworkEntry.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 31ef1cbcd71f47629a509e5171661a52 +timeCreated: 1680336346 \ No newline at end of file diff --git a/Assets/TEngine/Runtime/GameFramework/GameFrameworkModule.cs b/Assets/TEngine/Runtime/GameFramework/GameFrameworkModule.cs new file mode 100644 index 00000000..c836d0bb --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/GameFrameworkModule.cs @@ -0,0 +1,26 @@ +namespace TEngine +{ + /// + /// 游戏框架模块抽象类。 + /// + internal abstract class GameFrameworkModule + { + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal virtual int Priority => 0; + + /// + /// 游戏框架模块轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal abstract void Update(float elapseSeconds, float realElapseSeconds); + + /// + /// 关闭并清理游戏框架模块。 + /// + internal abstract void Shutdown(); + } +} diff --git a/Assets/TEngine/Runtime/GameFramework/GameFrameworkModule.cs.meta b/Assets/TEngine/Runtime/GameFramework/GameFrameworkModule.cs.meta new file mode 100644 index 00000000..4f1599d0 --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/GameFrameworkModule.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 23d586f8d3656a043ab81d1fdc0683d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/Log.meta b/Assets/TEngine/Runtime/GameFramework/Log.meta similarity index 100% rename from Assets/TEngine/Runtime/Log.meta rename to Assets/TEngine/Runtime/GameFramework/Log.meta diff --git a/Assets/TEngine/Runtime/Log/GameFrameworkLog.ILogHelper.cs b/Assets/TEngine/Runtime/GameFramework/Log/GameFrameworkLog.ILogHelper.cs similarity index 100% rename from Assets/TEngine/Runtime/Log/GameFrameworkLog.ILogHelper.cs rename to Assets/TEngine/Runtime/GameFramework/Log/GameFrameworkLog.ILogHelper.cs diff --git a/Assets/TEngine/Runtime/Log/GameFrameworkLog.ILogHelper.cs.meta b/Assets/TEngine/Runtime/GameFramework/Log/GameFrameworkLog.ILogHelper.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/Log/GameFrameworkLog.ILogHelper.cs.meta rename to Assets/TEngine/Runtime/GameFramework/Log/GameFrameworkLog.ILogHelper.cs.meta diff --git a/Assets/TEngine/Runtime/Log/GameFrameworkLog.cs b/Assets/TEngine/Runtime/GameFramework/Log/GameFrameworkLog.cs similarity index 100% rename from Assets/TEngine/Runtime/Log/GameFrameworkLog.cs rename to Assets/TEngine/Runtime/GameFramework/Log/GameFrameworkLog.cs diff --git a/Assets/TEngine/Runtime/Log/GameFrameworkLog.cs.meta b/Assets/TEngine/Runtime/GameFramework/Log/GameFrameworkLog.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/Log/GameFrameworkLog.cs.meta rename to Assets/TEngine/Runtime/GameFramework/Log/GameFrameworkLog.cs.meta diff --git a/Assets/TEngine/Runtime/Log/GameFrameworkLogLevel.cs b/Assets/TEngine/Runtime/GameFramework/Log/GameFrameworkLogLevel.cs similarity index 100% rename from Assets/TEngine/Runtime/Log/GameFrameworkLogLevel.cs rename to Assets/TEngine/Runtime/GameFramework/Log/GameFrameworkLogLevel.cs diff --git a/Assets/TEngine/Runtime/Log/GameFrameworkLogLevel.cs.meta b/Assets/TEngine/Runtime/GameFramework/Log/GameFrameworkLogLevel.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/Log/GameFrameworkLogLevel.cs.meta rename to Assets/TEngine/Runtime/GameFramework/Log/GameFrameworkLogLevel.cs.meta diff --git a/Assets/TEngine/Runtime/Log/Log.cs b/Assets/TEngine/Runtime/GameFramework/Log/Log.cs similarity index 100% rename from Assets/TEngine/Runtime/Log/Log.cs rename to Assets/TEngine/Runtime/GameFramework/Log/Log.cs diff --git a/Assets/TEngine/Runtime/Log/Log.cs.meta b/Assets/TEngine/Runtime/GameFramework/Log/Log.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/Log/Log.cs.meta rename to Assets/TEngine/Runtime/GameFramework/Log/Log.cs.meta diff --git a/Assets/TEngine/Runtime/Log/TEngineLogHelper.cs b/Assets/TEngine/Runtime/GameFramework/Log/TEngineLogHelper.cs similarity index 100% rename from Assets/TEngine/Runtime/Log/TEngineLogHelper.cs rename to Assets/TEngine/Runtime/GameFramework/Log/TEngineLogHelper.cs diff --git a/Assets/TEngine/Runtime/Log/TEngineLogHelper.cs.meta b/Assets/TEngine/Runtime/GameFramework/Log/TEngineLogHelper.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/Log/TEngineLogHelper.cs.meta rename to Assets/TEngine/Runtime/GameFramework/Log/TEngineLogHelper.cs.meta diff --git a/Assets/TEngine/Runtime/MemoryPool.meta b/Assets/TEngine/Runtime/GameFramework/MemoryPool.meta similarity index 100% rename from Assets/TEngine/Runtime/MemoryPool.meta rename to Assets/TEngine/Runtime/GameFramework/MemoryPool.meta diff --git a/Assets/TEngine/Runtime/MemoryPool/IMemory.cs b/Assets/TEngine/Runtime/GameFramework/MemoryPool/IMemory.cs similarity index 100% rename from Assets/TEngine/Runtime/MemoryPool/IMemory.cs rename to Assets/TEngine/Runtime/GameFramework/MemoryPool/IMemory.cs diff --git a/Assets/TEngine/Runtime/MemoryPool/IMemory.cs.meta b/Assets/TEngine/Runtime/GameFramework/MemoryPool/IMemory.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/MemoryPool/IMemory.cs.meta rename to Assets/TEngine/Runtime/GameFramework/MemoryPool/IMemory.cs.meta diff --git a/Assets/TEngine/Runtime/MemoryPool/MemoryPool.MemoryCollection.cs b/Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPool.MemoryCollection.cs similarity index 100% rename from Assets/TEngine/Runtime/MemoryPool/MemoryPool.MemoryCollection.cs rename to Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPool.MemoryCollection.cs diff --git a/Assets/TEngine/Runtime/MemoryPool/MemoryPool.MemoryCollection.cs.meta b/Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPool.MemoryCollection.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/MemoryPool/MemoryPool.MemoryCollection.cs.meta rename to Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPool.MemoryCollection.cs.meta diff --git a/Assets/TEngine/Runtime/MemoryPool/MemoryPool.cs b/Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPool.cs similarity index 100% rename from Assets/TEngine/Runtime/MemoryPool/MemoryPool.cs rename to Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPool.cs diff --git a/Assets/TEngine/Runtime/MemoryPool/MemoryPool.cs.meta b/Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPool.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/MemoryPool/MemoryPool.cs.meta rename to Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPool.cs.meta diff --git a/Assets/TEngine/Runtime/MemoryPool/MemoryPoolComponent.cs b/Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPoolComponent.cs similarity index 100% rename from Assets/TEngine/Runtime/MemoryPool/MemoryPoolComponent.cs rename to Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPoolComponent.cs diff --git a/Assets/TEngine/Runtime/MemoryPool/MemoryPoolComponent.cs.meta b/Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPoolComponent.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/MemoryPool/MemoryPoolComponent.cs.meta rename to Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPoolComponent.cs.meta diff --git a/Assets/TEngine/Runtime/MemoryPool/MemoryPoolInfo.cs b/Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPoolInfo.cs similarity index 100% rename from Assets/TEngine/Runtime/MemoryPool/MemoryPoolInfo.cs rename to Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPoolInfo.cs diff --git a/Assets/TEngine/Runtime/MemoryPool/MemoryPoolInfo.cs.meta b/Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPoolInfo.cs.meta similarity index 100% rename from Assets/TEngine/Runtime/MemoryPool/MemoryPoolInfo.cs.meta rename to Assets/TEngine/Runtime/GameFramework/MemoryPool/MemoryPoolInfo.cs.meta