From 1a28eb62a8785ed28367e7360882a75c6ba723b7 Mon Sep 17 00:00:00 2001 From: ninemine <1371605831@qq.com> Date: Thu, 13 Nov 2025 16:39:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=8Eellan/GameFramework=E4=B8=AD=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E6=96=B0=E7=9A=84=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Convention/[Architecture].meta | 8 + Convention/[Architecture]/Architecture.cs | 108 +++++ .../[Architecture]/Architecture.cs.meta | 11 + Convention/[Architecture]/PublicType.meta | 8 + .../PublicType/GameException.cs | 52 ++ .../PublicType/GameException.cs.meta | 11 + .../[Architecture]/PublicType/GameModule.cs | 36 ++ .../PublicType/GameModule.cs.meta | 11 + .../PublicType/LinkedCacheList.cs | 455 ++++++++++++++++++ .../PublicType/LinkedCacheList.cs.meta | 11 + Convention/[Runtime]/Architecture.cs | 2 +- Convention/[Runtime]/Config.cs | 246 ++++++++++ 12 files changed, 958 insertions(+), 1 deletion(-) create mode 100644 Convention/[Architecture].meta create mode 100644 Convention/[Architecture]/Architecture.cs create mode 100644 Convention/[Architecture]/Architecture.cs.meta create mode 100644 Convention/[Architecture]/PublicType.meta create mode 100644 Convention/[Architecture]/PublicType/GameException.cs create mode 100644 Convention/[Architecture]/PublicType/GameException.cs.meta create mode 100644 Convention/[Architecture]/PublicType/GameModule.cs create mode 100644 Convention/[Architecture]/PublicType/GameModule.cs.meta create mode 100644 Convention/[Architecture]/PublicType/LinkedCacheList.cs create mode 100644 Convention/[Architecture]/PublicType/LinkedCacheList.cs.meta diff --git a/Convention/[Architecture].meta b/Convention/[Architecture].meta new file mode 100644 index 0000000..da0dedd --- /dev/null +++ b/Convention/[Architecture].meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: aedf6f9892e6a9545a8e4bfce4d03063 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Convention/[Architecture]/Architecture.cs b/Convention/[Architecture]/Architecture.cs new file mode 100644 index 0000000..9f0a59e --- /dev/null +++ b/Convention/[Architecture]/Architecture.cs @@ -0,0 +1,108 @@ +using Convention; +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using Convention.Experimental.PublicType; + +namespace Convention.Experimental +{ + public static class Architecture + { + private static readonly LinkedCacheList s_GameFrameworkModules = new(); + + /// + /// 创建 + /// + /// 要创建的类型 + /// 要创建的 + private static GameModule CreateModule(Type moduleType) + { + GameModule module = (GameModule)Activator.CreateInstance(moduleType); + if (module == null) + { + throw new GameException($"Can not create module '{moduleType.FullName}'"); + } + + LinkedListNode current = s_GameFrameworkModules.First; + while (current != null) + { + if (module.Priority > current.Value.Priority) + { + break; + } + + current = current.Next; + } + + if (current != null) + { + s_GameFrameworkModules.AddBefore(current, module); + } + else + { + s_GameFrameworkModules.AddLast(module); + } + + return module; + } + + /// + /// 获取 + /// + /// 要获取的 + /// 要获取的 + /// 如果要获取的不存在,则自动创建该实例。 + private static GameModule GetModule(Type moduleType) + { + foreach (GameModule module in s_GameFrameworkModules) + { + if (module.GetType() == moduleType) + { + return module; + } + } + + return CreateModule(moduleType); + } + + /// + /// 获取游戏框架模块。 + /// + /// 要获取的游戏框架模块类型。 + /// 要获取的游戏框架模块。 + /// 如果要获取的游戏框架模块不存在,则自动创建该游戏框架模块。 + public static T GetModule() where T : GameModule + { + return (T)GetModule(typeof(T)); + } + + /// + /// 关闭并清理所有游戏框架模块。 + /// + public static void Shutdown() + { + for (var current = s_GameFrameworkModules.Last; current != null; current = current.Previous) + { + current.Value.Shutdown(); + } + + s_GameFrameworkModules.Clear(); + ReferencePool.ClearAll(); + Utility.Marshal.FreeCachedHGlobal(); + } + + /// + /// 所有游戏框架模块轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public static void Update(float elapseSeconds, float realElapseSeconds) + { + foreach (var module in s_GameFrameworkModules) + { + module.Update(elapseSeconds, realElapseSeconds); + } + } + } +} \ No newline at end of file diff --git a/Convention/[Architecture]/Architecture.cs.meta b/Convention/[Architecture]/Architecture.cs.meta new file mode 100644 index 0000000..c2d1a61 --- /dev/null +++ b/Convention/[Architecture]/Architecture.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 07141d7da2b1cc74dbfaf880734228dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Convention/[Architecture]/PublicType.meta b/Convention/[Architecture]/PublicType.meta new file mode 100644 index 0000000..e2c59b0 --- /dev/null +++ b/Convention/[Architecture]/PublicType.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 997615a04b8d2844aa27b8d212998bd6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Convention/[Architecture]/PublicType/GameException.cs b/Convention/[Architecture]/PublicType/GameException.cs new file mode 100644 index 0000000..d89d034 --- /dev/null +++ b/Convention/[Architecture]/PublicType/GameException.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Serialization; +using UnityEngine; + +namespace Convention.Experimental.PublicType +{ + /// + /// 游戏框架异常类。 + /// + [Serializable] + public class GameException : Exception + { + /// + /// 初始化游戏框架异常类的新实例。 + /// + public GameException() + : base() + { + } + + /// + /// 使用指定错误消息初始化游戏框架异常类的新实例。 + /// + /// 描述错误的消息。 + public GameException(string message) + : base(message) + { + } + + /// + /// 使用指定错误消息和对作为此异常原因的内部异常的引用来初始化游戏框架异常类的新实例。 + /// + /// 解释异常原因的错误消息。 + /// 导致当前异常的异常。如果 innerException 参数不为空引用,则在处理内部异常的 catch 块中引发当前异常。 + public GameException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// 用序列化数据初始化游戏框架异常类的新实例。 + /// + /// 存有有关所引发异常的序列化的对象数据。 + /// 包含有关源或目标的上下文信息。 + protected GameException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/Convention/[Architecture]/PublicType/GameException.cs.meta b/Convention/[Architecture]/PublicType/GameException.cs.meta new file mode 100644 index 0000000..b3ef73c --- /dev/null +++ b/Convention/[Architecture]/PublicType/GameException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 93a229364c4ce134aa9548ad57f9e790 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Convention/[Architecture]/PublicType/GameModule.cs b/Convention/[Architecture]/PublicType/GameModule.cs new file mode 100644 index 0000000..7aee320 --- /dev/null +++ b/Convention/[Architecture]/PublicType/GameModule.cs @@ -0,0 +1,36 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Convention.Experimental.PublicType +{ + /// + /// 游戏框架模块抽象类。 + /// + public abstract class GameModule + { + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal virtual int Priority + { + get + { + return 0; + } + } + + /// + /// 游戏框架模块轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal abstract void Update(float elapseSeconds, float realElapseSeconds); + + /// + /// 关闭并清理游戏框架模块。 + /// + internal abstract void Shutdown(); + } +} diff --git a/Convention/[Architecture]/PublicType/GameModule.cs.meta b/Convention/[Architecture]/PublicType/GameModule.cs.meta new file mode 100644 index 0000000..f87e4e5 --- /dev/null +++ b/Convention/[Architecture]/PublicType/GameModule.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2f8a535a831e2c44097dcac4a87db7ff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Convention/[Architecture]/PublicType/LinkedCacheList.cs b/Convention/[Architecture]/PublicType/LinkedCacheList.cs new file mode 100644 index 0000000..edaaa73 --- /dev/null +++ b/Convention/[Architecture]/PublicType/LinkedCacheList.cs @@ -0,0 +1,455 @@ +锘縰sing System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using UnityEngine; + +namespace Convention.Experimental.PublicType +{ + + /// + /// 闄勫甫鏈夌紦瀛樻満鍒剁殑閾捐〃绫汇 + /// + /// 鎸囧畾閾捐〃鐨勫厓绱犵被鍨嬨 + public sealed class LinkedCacheList : ICollection, IEnumerable, ICollection, IEnumerable + { + private readonly LinkedList m_LinkedList; + /// + /// 涔嬫墍浠ラ渶瑕佽繖濂楃紦瀛樻満鍒讹紝涓昏鏈変笁鐐瑰ソ澶勶細 + /// 鍑忓皯 GC 鍘嬪姏锛氬ぇ閲忛绻佺殑鎻掑叆/鍒犻櫎浼氫骇鐢熷緢澶氱煭鐢熷懡鍛ㄦ湡鐨勮妭鐐瑰璞★紝閫氳繃澶嶇敤鍙互鏄捐憲闄嶄綆鎵樼鍫嗙殑鍒嗛厤涓庡洖鏀舵鏁 + /// 鎻愬崌鎬ц兘锛氶伩鍏嶉绻 new 鍜 GC锛岃兘鍑忓皯鍋滈】鏃堕棿锛屾彁楂橀摼琛ㄥ湪楂橀鎿嶄綔鍦烘櫙涓嬬殑鍚炲悙 + /// 渚夸簬瑙傚療涓庣鐞嗭細绫讳腑杩樻彁渚涗簡 CachedNodeCount 鏂逛究璋冭瘯缁熻缂撳瓨瑙勬ā锛屽繀瑕佹椂鍙氳繃 ClearCachedNodes 涓诲姩閲婃斁 + /// 閫傜敤鍦烘櫙鏄妭鐐逛娇鐢ㄦā寮忊滈珮棰戝鍒犱絾鎬婚噺鏈夐檺鈥濓紝姝ゆ椂缂撳瓨鑳界ǔ瀹氭ц兘锛涜嫢閾捐〃瑙勬ā濮嬬粓鍦ㄥ闀夸笖寰堝皯閲婃斁锛岀紦瀛樻敹鐩婁細杈冧綆銆 + /// + private readonly Queue> m_CachedNodes; + + /// + /// 鍒濆鍖栨父鎴忔鏋堕摼琛ㄧ被鐨勬柊瀹炰緥銆 + /// + public LinkedCacheList() + { + m_LinkedList = new LinkedList(); + m_CachedNodes = new Queue>(); + } + + /// + /// 鑾峰彇閾捐〃涓疄闄呭寘鍚殑缁撶偣鏁伴噺銆 + /// + public int Count + { + get + { + return m_LinkedList.Count; + } + } + + /// + /// 鑾峰彇閾捐〃缁撶偣缂撳瓨鏁伴噺銆 + /// + public int CachedNodeCount + { + get + { + return m_CachedNodes.Count; + } + } + + /// + /// 鑾峰彇閾捐〃鐨勭涓涓粨鐐广 + /// + public LinkedListNode First + { + get + { + return m_LinkedList.First; + } + } + + /// + /// 鑾峰彇閾捐〃鐨勬渶鍚庝竴涓粨鐐广 + /// + public LinkedListNode Last + { + get + { + return m_LinkedList.Last; + } + } + + /// + /// 鑾峰彇涓涓硷紝璇ュ兼寚绀 ICollection`1 鏄惁涓哄彧璇汇 + /// + public bool IsReadOnly + { + get + { + return ((ICollection)m_LinkedList).IsReadOnly; + } + } + + /// + /// 鑾峰彇鍙敤浜庡悓姝ュ ICollection 鐨勮闂殑瀵硅薄銆 + /// + public object SyncRoot + { + get + { + return ((ICollection)m_LinkedList).SyncRoot; + } + } + + /// + /// 鑾峰彇涓涓硷紝璇ュ兼寚绀烘槸鍚﹀悓姝ュ ICollection 鐨勮闂紙绾跨▼瀹夊叏锛夈 + /// + public bool IsSynchronized + { + get + { + return ((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 GameException("First is invalid."); + } + + m_LinkedList.RemoveFirst(); + ReleaseNode(first); + } + + /// + /// 绉婚櫎浣嶄簬閾捐〃缁撳熬澶勭殑缁撶偣銆 + /// + public void RemoveLast() + { + LinkedListNode last = m_LinkedList.Last; + if (last == null) + { + throw new GameException("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 GameException("Linked list is invalid."); + } + + m_Enumerator = linkedList.GetEnumerator(); + } + + /// + /// 鑾峰彇褰撳墠缁撶偣銆 + /// + public T Current + { + get + { + return m_Enumerator.Current; + } + } + + /// + /// 鑾峰彇褰撳墠鐨勬灇涓炬暟銆 + /// + object IEnumerator.Current + { + get + { + return 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/Convention/[Architecture]/PublicType/LinkedCacheList.cs.meta b/Convention/[Architecture]/PublicType/LinkedCacheList.cs.meta new file mode 100644 index 0000000..717b337 --- /dev/null +++ b/Convention/[Architecture]/PublicType/LinkedCacheList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34c26073576fd3b488f2b547e7e8eb0a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Convention/[Runtime]/Architecture.cs b/Convention/[Runtime]/Architecture.cs index 1c0dcd4..3968e78 100644 --- a/Convention/[Runtime]/Architecture.cs +++ b/Convention/[Runtime]/Architecture.cs @@ -421,4 +421,4 @@ namespace Convention #endregion } -} +} \ No newline at end of file diff --git a/Convention/[Runtime]/Config.cs b/Convention/[Runtime]/Config.cs index 71a7544..98953d6 100644 --- a/Convention/[Runtime]/Config.cs +++ b/Convention/[Runtime]/Config.cs @@ -424,6 +424,245 @@ namespace Convention { return DateTime.Now.ToString(format); } + + + /// + /// Marshal 鐩稿叧鐨勫疄鐢ㄥ嚱鏁般 + /// + public static class Marshal + { + + [Serializable] + public class MarshalException : Exception + { + public MarshalException() { } + public MarshalException(string message) : base(message) { } + public MarshalException(string message, Exception inner) : base(message, inner) { } + protected MarshalException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } + + private const int BlockSize = 1024 * 4; + private static IntPtr s_CachedHGlobalPtr = IntPtr.Zero; + private static int s_CachedHGlobalSize = 0; + + /// + /// 鑾峰彇缂撳瓨鐨勪粠杩涚▼鐨勯潪鎵樼鍐呭瓨涓垎閰嶇殑鍐呭瓨鐨勫ぇ灏忋 + /// + public static int CachedHGlobalSize + { + get + { + return s_CachedHGlobalSize; + } + } + + /// + /// 纭繚浠庤繘绋嬬殑闈炴墭绠″唴瀛樹腑鍒嗛厤瓒冲澶у皬鐨勫唴瀛樺苟缂撳瓨銆 + /// + /// 瑕佺‘淇濅粠杩涚▼鐨勯潪鎵樼鍐呭瓨涓垎閰嶅唴瀛樼殑澶у皬銆 + public static void EnsureCachedHGlobalSize(int ensureSize) + { + if (ensureSize < 0) + { + throw new MarshalException("Ensure size is invalid."); + } + + if (s_CachedHGlobalPtr == IntPtr.Zero || s_CachedHGlobalSize < ensureSize) + { + FreeCachedHGlobal(); + int size = (ensureSize - 1 + BlockSize) / BlockSize * BlockSize; + s_CachedHGlobalPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(size); + s_CachedHGlobalSize = size; + } + } + + /// + /// 閲婃斁缂撳瓨鐨勪粠杩涚▼鐨勯潪鎵樼鍐呭瓨涓垎閰嶇殑鍐呭瓨銆 + /// + public static void FreeCachedHGlobal() + { + if (s_CachedHGlobalPtr != IntPtr.Zero) + { + System.Runtime.InteropServices.Marshal.FreeHGlobal(s_CachedHGlobalPtr); + s_CachedHGlobalPtr = IntPtr.Zero; + s_CachedHGlobalSize = 0; + } + } + + /// + /// 灏嗘暟鎹粠瀵硅薄杞崲涓轰簩杩涘埗娴併 + /// + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勭被鍨嬨 + /// 瑕佽浆鎹㈢殑瀵硅薄銆 + /// 瀛樺偍杞崲缁撴灉鐨勪簩杩涘埗娴併 + public static byte[] StructureToBytes(T structure) + { + return StructureToBytes(structure, System.Runtime.InteropServices.Marshal.SizeOf(typeof(T))); + } + + /// + /// 灏嗘暟鎹粠瀵硅薄杞崲涓轰簩杩涘埗娴併 + /// + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勭被鍨嬨 + /// 瑕佽浆鎹㈢殑瀵硅薄銆 + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勫ぇ灏忋 + /// 瀛樺偍杞崲缁撴灉鐨勪簩杩涘埗娴併 + internal static byte[] StructureToBytes(T structure, int structureSize) + { + if (structureSize < 0) + { + throw new MarshalException("Structure size is invalid."); + } + + EnsureCachedHGlobalSize(structureSize); + System.Runtime.InteropServices.Marshal.StructureToPtr(structure, s_CachedHGlobalPtr, true); + byte[] result = new byte[structureSize]; + System.Runtime.InteropServices.Marshal.Copy(s_CachedHGlobalPtr, result, 0, structureSize); + return result; + } + + /// + /// 灏嗘暟鎹粠瀵硅薄杞崲涓轰簩杩涘埗娴併 + /// + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勭被鍨嬨 + /// 瑕佽浆鎹㈢殑瀵硅薄銆 + /// 瀛樺偍杞崲缁撴灉鐨勪簩杩涘埗娴併 + public static void StructureToBytes(T structure, byte[] result) + { + StructureToBytes(structure, System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), result, 0); + } + + /// + /// 灏嗘暟鎹粠瀵硅薄杞崲涓轰簩杩涘埗娴併 + /// + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勭被鍨嬨 + /// 瑕佽浆鎹㈢殑瀵硅薄銆 + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勫ぇ灏忋 + /// 瀛樺偍杞崲缁撴灉鐨勪簩杩涘埗娴併 + internal static void StructureToBytes(T structure, int structureSize, byte[] result) + { + StructureToBytes(structure, structureSize, result, 0); + } + + /// + /// 灏嗘暟鎹粠瀵硅薄杞崲涓轰簩杩涘埗娴併 + /// + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勭被鍨嬨 + /// 瑕佽浆鎹㈢殑瀵硅薄銆 + /// 瀛樺偍杞崲缁撴灉鐨勪簩杩涘埗娴併 + /// 鍐欏叆瀛樺偍杞崲缁撴灉鐨勪簩杩涘埗娴佺殑璧峰浣嶇疆銆 + public static void StructureToBytes(T structure, byte[] result, int startIndex) + { + StructureToBytes(structure, System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), result, startIndex); + } + + /// + /// 灏嗘暟鎹粠瀵硅薄杞崲涓轰簩杩涘埗娴併 + /// + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勭被鍨嬨 + /// 瑕佽浆鎹㈢殑瀵硅薄銆 + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勫ぇ灏忋 + /// 瀛樺偍杞崲缁撴灉鐨勪簩杩涘埗娴併 + /// 鍐欏叆瀛樺偍杞崲缁撴灉鐨勪簩杩涘埗娴佺殑璧峰浣嶇疆銆 + internal static void StructureToBytes(T structure, int structureSize, byte[] result, int startIndex) + { + if (structureSize < 0) + { + throw new MarshalException("Structure size is invalid."); + } + + if (result == null) + { + throw new MarshalException("Result is invalid."); + } + + if (startIndex < 0) + { + throw new MarshalException("Start index is invalid."); + } + + if (startIndex + structureSize > result.Length) + { + throw new MarshalException("Result length is not enough."); + } + + EnsureCachedHGlobalSize(structureSize); + System.Runtime.InteropServices.Marshal.StructureToPtr(structure, s_CachedHGlobalPtr, true); + System.Runtime.InteropServices.Marshal.Copy(s_CachedHGlobalPtr, result, startIndex, structureSize); + } + + /// + /// 灏嗘暟鎹粠浜岃繘鍒舵祦杞崲涓哄璞° + /// + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勭被鍨嬨 + /// 瑕佽浆鎹㈢殑浜岃繘鍒舵祦銆 + /// 瀛樺偍杞崲缁撴灉鐨勫璞° + public static T BytesToStructure(byte[] buffer) + { + return BytesToStructure(System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), buffer, 0); + } + + /// + /// 灏嗘暟鎹粠浜岃繘鍒舵祦杞崲涓哄璞° + /// + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勭被鍨嬨 + /// 瑕佽浆鎹㈢殑浜岃繘鍒舵祦銆 + /// 璇诲彇瑕佽浆鎹㈢殑浜岃繘鍒舵祦鐨勮捣濮嬩綅缃 + /// 瀛樺偍杞崲缁撴灉鐨勫璞° + public static T BytesToStructure(byte[] buffer, int startIndex) + { + return BytesToStructure(System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), buffer, startIndex); + } + + /// + /// 灏嗘暟鎹粠浜岃繘鍒舵祦杞崲涓哄璞° + /// + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勭被鍨嬨 + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勫ぇ灏忋 + /// 瑕佽浆鎹㈢殑浜岃繘鍒舵祦銆 + /// 瀛樺偍杞崲缁撴灉鐨勫璞° + internal static T BytesToStructure(int structureSize, byte[] buffer) + { + return BytesToStructure(structureSize, buffer, 0); + } + + /// + /// 灏嗘暟鎹粠浜岃繘鍒舵祦杞崲涓哄璞° + /// + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勭被鍨嬨 + /// 瑕佽浆鎹㈢殑瀵硅薄鐨勫ぇ灏忋 + /// 瑕佽浆鎹㈢殑浜岃繘鍒舵祦銆 + /// 璇诲彇瑕佽浆鎹㈢殑浜岃繘鍒舵祦鐨勮捣濮嬩綅缃 + /// 瀛樺偍杞崲缁撴灉鐨勫璞° + internal static T BytesToStructure(int structureSize, byte[] buffer, int startIndex) + { + if (structureSize < 0) + { + throw new MarshalException("Structure size is invalid."); + } + + if (buffer == null) + { + throw new MarshalException("Buffer is invalid."); + } + + if (startIndex < 0) + { + throw new MarshalException("Start index is invalid."); + } + + if (startIndex + structureSize > buffer.Length) + { + throw new MarshalException("Buffer length is not enough."); + } + + EnsureCachedHGlobalSize(structureSize); + System.Runtime.InteropServices.Marshal.Copy(buffer, startIndex, s_CachedHGlobalPtr, structureSize); + return (T)System.Runtime.InteropServices.Marshal.PtrToStructure(s_CachedHGlobalPtr, typeof(T)); + } + } } } @@ -2232,3 +2471,10 @@ namespace Convention } } } + +namespace Convention +{ + public static partial class ConventionUtility + { + } +} \ No newline at end of file