From bf81df9581e34fcfc0c118f5f5aaabdcebbad46a Mon Sep 17 00:00:00 2001
From: ninemine <1371605831@qq.com>
Date: Fri, 14 Nov 2025 17:14:08 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AE=9E=E9=AA=8C=E6=A1=86?=
=?UTF-8?q?=E6=9E=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Convention/[Architecture]/Architecture.cs | 22 +-
Convention/[Architecture]/Modules.meta | 8 +
.../[Architecture]/PublicType/GameModule.cs | 26 +-
.../PublicType/ReferencePool.cs | 491 ++++++++++++++++++
.../PublicType/ReferencePool.cs.meta | 11 +
Convention/[Runtime]/Config.cs | 1 +
6 files changed, 540 insertions(+), 19 deletions(-)
create mode 100644 Convention/[Architecture]/Modules.meta
create mode 100644 Convention/[Architecture]/PublicType/ReferencePool.cs
create mode 100644 Convention/[Architecture]/PublicType/ReferencePool.cs.meta
diff --git a/Convention/[Architecture]/Architecture.cs b/Convention/[Architecture]/Architecture.cs
index 9f0a59e..e4405cd 100644
--- a/Convention/[Architecture]/Architecture.cs
+++ b/Convention/[Architecture]/Architecture.cs
@@ -1,9 +1,6 @@
-using Convention;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
using Convention.Experimental.PublicType;
+using System;
+using System.Collections.Generic;
namespace Convention.Experimental
{
@@ -16,14 +13,23 @@ namespace Convention.Experimental
///
/// 要创建的类型
/// 要创建的
- private static GameModule CreateModule(Type moduleType)
+ private static GameModule CreateModule(Type moduleType, int stackLayer = 0)
{
+ if (stackLayer >= 100)
+ {
+ throw new GameException($"Create module '{moduleType.FullName}' failed, recursion too deep, there may be a circular dependency.");
+ }
+
GameModule module = (GameModule)Activator.CreateInstance(moduleType);
if (module == null)
{
throw new GameException($"Can not create module '{moduleType.FullName}'");
}
+ // 递归创建依赖模块
+ foreach (var dependenceType in module.Dependences())
+ _ = GetModule(dependenceType, stackLayer + 1);
+
LinkedListNode current = s_GameFrameworkModules.First;
while (current != null)
{
@@ -53,7 +59,7 @@ namespace Convention.Experimental
/// 要获取的
/// 要获取的
/// 如果要获取的不存在,则自动创建该实例。
- private static GameModule GetModule(Type moduleType)
+ private static GameModule GetModule(Type moduleType, int stackLayer = 0)
{
foreach (GameModule module in s_GameFrameworkModules)
{
@@ -63,7 +69,7 @@ namespace Convention.Experimental
}
}
- return CreateModule(moduleType);
+ return CreateModule(moduleType, stackLayer + 1);
}
///
diff --git a/Convention/[Architecture]/Modules.meta b/Convention/[Architecture]/Modules.meta
new file mode 100644
index 0000000..2376210
--- /dev/null
+++ b/Convention/[Architecture]/Modules.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 591a2c63cd01a22408284eeaa811e930
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Convention/[Architecture]/PublicType/GameModule.cs b/Convention/[Architecture]/PublicType/GameModule.cs
index 7aee320..bbf4ca7 100644
--- a/Convention/[Architecture]/PublicType/GameModule.cs
+++ b/Convention/[Architecture]/PublicType/GameModule.cs
@@ -1,18 +1,17 @@
-using System.Collections;
+using System;
using System.Collections.Generic;
-using UnityEngine;
namespace Convention.Experimental.PublicType
{
///
- /// 游戏框架模块抽象类。
+ /// 游戏框架模块抽象类
///
public abstract class GameModule
{
///
- /// 获取游戏框架模块优先级。
+ /// 获取游戏框架模块优先级
///
- /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。
+ /// 优先级较高的模块会优先轮询,优先级较低的模块会优先卸载
internal virtual int Priority
{
get
@@ -22,15 +21,20 @@ namespace Convention.Experimental.PublicType
}
///
- /// 游戏框架模块轮询。
+ /// 游戏框架模块轮询
///
- /// 逻辑流逝时间,以秒为单位。
- /// 真实流逝时间,以秒为单位。
- internal abstract void Update(float elapseSeconds, float realElapseSeconds);
+ /// 逻辑流逝时间,以秒为单位
+ /// 真实流逝时间,以秒为单位
+ internal virtual void Update(float elapseSeconds, float realElapseSeconds) { }
///
- /// 关闭并清理游戏框架模块。
+ /// 关闭并清理游戏框架模块
///
- internal abstract void Shutdown();
+ internal virtual void Shutdown() { }
+
+ ///
+ /// 前置依赖的游戏框架模块类型集合
+ ///
+ internal virtual IEnumerable Dependences() => Array.Empty();
}
}
diff --git a/Convention/[Architecture]/PublicType/ReferencePool.cs b/Convention/[Architecture]/PublicType/ReferencePool.cs
new file mode 100644
index 0000000..f6bfbd9
--- /dev/null
+++ b/Convention/[Architecture]/PublicType/ReferencePool.cs
@@ -0,0 +1,491 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using Unity.VisualScripting;
+using UnityEngine;
+
+namespace Convention.Experimental.PublicType
+{
+ ///
+ /// 引用接口。
+ ///
+ public interface IReference
+ {
+ ///
+ /// 清理引用。
+ ///
+ void Clear();
+ }
+
+ ///
+ /// 引用池
+ ///
+ public static partial class ReferencePool
+ {
+ private static bool m_EnableStrictCheck = false;
+
+ ///
+ /// 获取或设置是否开启强制检查
+ ///
+ public static bool EnableStrictCheck
+ {
+ get
+ {
+ return m_EnableStrictCheck;
+ }
+ set
+ {
+ m_EnableStrictCheck = value;
+ }
+ }
+
+
+ private sealed class ReferenceCollection
+ {
+ private readonly Queue 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();
+ 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() 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(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 s_ReferenceCollections = new();
+
+ ///
+ /// 获取引用池的数量。
+ ///
+ public static int Count
+ {
+ get
+ {
+ return s_ReferenceCollections.Count;
+ }
+ }
+
+ ///
+ /// 引用池信息
+ ///
+ [StructLayout(LayoutKind.Auto)]
+ public readonly struct ReferencePoolInfo
+ {
+ ///
+ /// 引用池类型
+ ///
+ public readonly Type Type;
+ ///
+ /// 未使用引用数量
+ ///
+ public readonly int UnusedReferenceCount;
+ ///
+ /// 正在使用引用数量
+ ///
+ public readonly int UsingReferenceCount;
+ ///
+ /// 获取引用数量
+ ///
+ public readonly int AcquireReferenceCount;
+ ///
+ /// 归还引用数量
+ ///
+ public readonly int ReleaseReferenceCount;
+ ///
+ /// 增加引用数量
+ ///
+ public readonly int AddReferenceCount;
+ ///
+ /// 移除引用数量
+ ///
+ public readonly int RemoveReferenceCount;
+
+ ///
+ /// 初始化引用池信息的新实例。
+ ///
+ /// 引用池类型。
+ /// 未使用引用数量。
+ /// 正在使用引用数量。
+ /// 获取引用数量。
+ /// 归还引用数量。
+ /// 增加引用数量。
+ /// 移除引用数量。
+ 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;
+ }
+ }
+
+ ///
+ /// 获取所有引用池的信息
+ ///
+ /// 所有引用池的信息
+ 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;
+ }
+
+ ///
+ /// 清除所有引用池
+ ///
+ 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.");
+ }
+ }
+
+ ///
+ /// 从引用池获取引用
+ ///
+ /// 引用类型
+ /// 引用
+ public static IReference Acquire(Type referenceType)
+ {
+ InternalCheckReferenceType(referenceType);
+ return GetReferenceCollection(referenceType).Acquire();
+ }
+
+ ///
+ /// 从引用池获取引用
+ ///
+ /// 引用类型
+ /// 引用
+ public static T Acquire() where T : class, IReference, new()
+ {
+ return GetReferenceCollection(typeof(T)).Acquire();
+ }
+
+ ///
+ /// 将引用归还引用池
+ ///
+ /// 引用
+ 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);
+ }
+
+ ///
+ /// 向引用池中追加指定数量的引用
+ ///
+ /// 引用类型
+ /// 追加数量
+ public static void Add(int count) where T : class, IReference, new()
+ {
+ GetReferenceCollection(typeof(T)).Add(count);
+ }
+
+ ///
+ /// 向引用池中追加指定数量的引用
+ ///
+ /// 引用类型
+ /// 追加数量
+ public static void Add(Type referenceType, int count)
+ {
+ InternalCheckReferenceType(referenceType);
+ GetReferenceCollection(referenceType).Add(count);
+ }
+
+ ///
+ /// 从引用池中移除指定数量的引用
+ ///
+ /// 引用类型
+ /// 移除数量
+ public static void Remove(int count) where T : class, IReference
+ {
+ GetReferenceCollection(typeof(T)).Remove(count);
+ }
+
+ ///
+ /// 从引用池中移除指定数量的引用
+ ///
+ /// 引用类型
+ /// 移除数量
+ public static void Remove(Type referenceType, int count)
+ {
+ InternalCheckReferenceType(referenceType);
+ GetReferenceCollection(referenceType).Remove(count);
+ }
+
+ ///
+ /// 从引用池中移除所有的引用
+ ///
+ /// 引用类型
+ public static void RemoveAll() where T : class, IReference
+ {
+ GetReferenceCollection(typeof(T)).RemoveAll();
+ }
+
+ ///
+ /// 从引用池中移除所有的引用。
+ ///
+ /// 引用类型。
+ public static void RemoveAll(Type referenceType)
+ {
+ InternalCheckReferenceType(referenceType);
+ GetReferenceCollection(referenceType).RemoveAll();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Convention/[Architecture]/PublicType/ReferencePool.cs.meta b/Convention/[Architecture]/PublicType/ReferencePool.cs.meta
new file mode 100644
index 0000000..ce23ab7
--- /dev/null
+++ b/Convention/[Architecture]/PublicType/ReferencePool.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7a8ec3e4cc6e7e242b158fc02010c774
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Convention/[Runtime]/Config.cs b/Convention/[Runtime]/Config.cs
index 98953d6..361ce2c 100644
--- a/Convention/[Runtime]/Config.cs
+++ b/Convention/[Runtime]/Config.cs
@@ -1285,6 +1285,7 @@ namespace Convention
}
private static CoroutineMonoStarterUtil CoroutineStarter;
+ public static GameObject Singleton => CoroutineStarter.gameObject;
private class CoroutineMonoStarterUtil : MonoBehaviour
{