This commit is contained in:
陈思海 2025-04-27 19:27:48 +08:00
parent d523bac4f5
commit 341f153ad1
2 changed files with 84 additions and 98 deletions

View File

@ -11,22 +11,32 @@ namespace AlicizaX
private static readonly Dictionary<Type, IModule> _moduleMaps = new Dictionary<Type, IModule>(DesignModuleCount); private static readonly Dictionary<Type, IModule> _moduleMaps = new Dictionary<Type, IModule>(DesignModuleCount);
private static readonly GameFrameworkLinkedList<IModule> _modules = new GameFrameworkLinkedList<IModule>(); private static readonly GameFrameworkLinkedList<IModule> _modules = new GameFrameworkLinkedList<IModule>();
// Update systems
private static readonly GameFrameworkLinkedList<IModuleUpdate> _updateModules = new GameFrameworkLinkedList<IModuleUpdate>(); private static readonly GameFrameworkLinkedList<IModuleUpdate> _updateModules = new GameFrameworkLinkedList<IModuleUpdate>();
private static readonly IModuleUpdate[] _updateExecuteArray = new IModuleUpdate[DesignModuleCount]; private static readonly IModuleUpdate[] _updateExecuteArray = new IModuleUpdate[DesignModuleCount];
private static int _updateExecuteCount;
// LateUpdate systems
private static readonly GameFrameworkLinkedList<IModuleLateUpdate> _lateUpdateModules = new GameFrameworkLinkedList<IModuleLateUpdate>(); private static readonly GameFrameworkLinkedList<IModuleLateUpdate> _lateUpdateModules = new GameFrameworkLinkedList<IModuleLateUpdate>();
private static readonly IModuleLateUpdate[] _lateUpdateExecuteArray = new IModuleLateUpdate[DesignModuleCount]; private static readonly IModuleLateUpdate[] _lateUpdateExecuteArray = new IModuleLateUpdate[DesignModuleCount];
private static int _lateUpdateExecuteCount;
// FixedUpdate systems
private static readonly GameFrameworkLinkedList<IModuleFixedUpdate> _fixedUpdateModules = new GameFrameworkLinkedList<IModuleFixedUpdate>(); private static readonly GameFrameworkLinkedList<IModuleFixedUpdate> _fixedUpdateModules = new GameFrameworkLinkedList<IModuleFixedUpdate>();
private static readonly IModuleFixedUpdate[] _fixedUpdateExecuteArray = new IModuleFixedUpdate[DesignModuleCount]; private static readonly IModuleFixedUpdate[] _fixedUpdateExecuteArray = new IModuleFixedUpdate[DesignModuleCount];
private static int _fixedUpdateExecuteCount;
// Gizmos systems
private static readonly GameFrameworkLinkedList<IModuleDrawGizmos> _gizmosUpdateModules = new GameFrameworkLinkedList<IModuleDrawGizmos>(); private static readonly GameFrameworkLinkedList<IModuleDrawGizmos> _gizmosUpdateModules = new GameFrameworkLinkedList<IModuleDrawGizmos>();
private static readonly IModuleDrawGizmos[] _gizmosUpdateExecuteArray = new IModuleDrawGizmos[DesignModuleCount]; private static readonly IModuleDrawGizmos[] _gizmosUpdateExecuteArray = new IModuleDrawGizmos[DesignModuleCount];
private static int _gizmosExecuteCount;
// GUI systems
private static readonly GameFrameworkLinkedList<IModuleGUI> _guiUpdateModules = new GameFrameworkLinkedList<IModuleGUI>(); private static readonly GameFrameworkLinkedList<IModuleGUI> _guiUpdateModules = new GameFrameworkLinkedList<IModuleGUI>();
private static readonly IModuleGUI[] _guiUpdateExecuteArray = new IModuleGUI[DesignModuleCount]; private static readonly IModuleGUI[] _guiUpdateExecuteArray = new IModuleGUI[DesignModuleCount];
private static int _guiExecuteCount;
// Dirty flags
private static bool _isExecuteListDirty; private static bool _isExecuteListDirty;
private static bool _isLateExecuteListDirty; private static bool _isLateExecuteListDirty;
private static bool _isFixedExecuteListDirty; private static bool _isFixedExecuteListDirty;
@ -35,23 +45,29 @@ namespace AlicizaX
internal static void Dispose() internal static void Dispose()
{ {
// Clear all modules and execute arrays
_updateModules.Clear(); _updateModules.Clear();
Array.Clear(_updateExecuteArray, 0, _updateExecuteArray.Length); Array.Clear(_updateExecuteArray, 0, _updateExecuteArray.Length);
_updateExecuteCount = 0;
_lateUpdateModules.Clear(); _lateUpdateModules.Clear();
Array.Clear(_lateUpdateExecuteArray, 0, _lateUpdateExecuteArray.Length); Array.Clear(_lateUpdateExecuteArray, 0, _lateUpdateExecuteArray.Length);
_lateUpdateExecuteCount = 0;
_fixedUpdateModules.Clear(); _fixedUpdateModules.Clear();
Array.Clear(_fixedUpdateExecuteArray, 0, _fixedUpdateExecuteArray.Length); Array.Clear(_fixedUpdateExecuteArray, 0, _fixedUpdateExecuteArray.Length);
_fixedUpdateExecuteCount = 0;
_gizmosUpdateModules.Clear(); _gizmosUpdateModules.Clear();
Array.Clear(_gizmosUpdateExecuteArray, 0, _gizmosUpdateExecuteArray.Length); Array.Clear(_gizmosUpdateExecuteArray, 0, _gizmosUpdateExecuteArray.Length);
_gizmosExecuteCount = 0;
_guiUpdateModules.Clear(); _guiUpdateModules.Clear();
Array.Clear(_guiUpdateExecuteArray, 0, _guiUpdateExecuteArray.Length); Array.Clear(_guiUpdateExecuteArray, 0, _guiUpdateExecuteArray.Length);
_guiExecuteCount = 0;
for (LinkedListNode<IModule> current = _modules.Last; current != null; current = current.Previous) // Dispose all modules
for (var current = _modules.Last; current != null; current = current.Previous)
{ {
current.Value.Dispose(); current.Value.Dispose();
} }
@ -87,13 +103,10 @@ namespace AlicizaX
#region Public System #region Public System
public static T RegisterModule<T>(Type implType) public static T RegisterModule<T, TImple>() where T : IModule where TImple : class, T, new()
{
return (T)RegisterModule(typeof(T), implType);
}
public static IModule RegisterModule(Type interfaceType, Type implType)
{ {
Type interfaceType = typeof(T);
Type implType = typeof(TImple);
if (!interfaceType.IsInterface) if (!interfaceType.IsInterface)
{ {
throw new GameFrameworkException(Utility.Text.Format("You must register module by interface, but '{0}' is not.", interfaceType.FullName)); throw new GameFrameworkException(Utility.Text.Format("You must register module by interface, but '{0}' is not.", interfaceType.FullName));
@ -106,7 +119,7 @@ namespace AlicizaX
if (!typeof(IModule).IsAssignableFrom(interfaceType)) if (!typeof(IModule).IsAssignableFrom(interfaceType))
{ {
throw new GameFrameworkException(Utility.Text.Format("You must register module by Class and not Interface and Abstract, but '{0}' is not.", implType.FullName)); throw new GameFrameworkException(Utility.Text.Format("Module must implement IModule.", interfaceType.FullName));
} }
if (GetModule(interfaceType) != null) if (GetModule(interfaceType) != null)
@ -115,13 +128,13 @@ namespace AlicizaX
return default; return default;
} }
return SetModuleInstance(interfaceType, implType); TImple impl = new TImple();
return (T)SetModuleInstance(interfaceType, impl);
} }
public static T GetModule<T>() where T : class public static T GetModule<T>() where T : class
{ {
Type interfaceType = typeof(T); Type interfaceType = typeof(T);
if (!interfaceType.IsInterface) if (!interfaceType.IsInterface)
{ {
throw new GameFrameworkException(Utility.Text.Format("You must get module by interface, but '{0}' is not.", interfaceType.FullName)); throw new GameFrameworkException(Utility.Text.Format("You must get module by interface, but '{0}' is not.", interfaceType.FullName));
@ -132,28 +145,21 @@ namespace AlicizaX
public static IModule GetModule(Type moduleType) public static IModule GetModule(Type moduleType)
{ {
if (_moduleMaps.TryGetValue(moduleType, out var ret)) return _moduleMaps.TryGetValue(moduleType, out var ret) ? ret : default;
{
return ret;
}
return default;
} }
private static IModule SetModuleInstance(Type interfaceType, Type implType) private static IModule SetModuleInstance<TImpl>(Type interfaceType, TImpl impl) where TImpl : class, IModule
{ {
IModule module = (IModule)Activator.CreateInstance(implType); _moduleMaps[interfaceType] = impl;
_modules.AddLast(impl);
_moduleMaps[interfaceType] = module; if (impl is IModuleAwake awakeSystem)
_modules.AddLast(module);
if (module is IModuleAwake awakeSystem)
{ {
awakeSystem.Awake(); awakeSystem.Awake();
} }
CheckSystemLife(module); CheckSystemLife(impl);
return module; return impl;
} }
#endregion #endregion
@ -162,46 +168,41 @@ namespace AlicizaX
{ {
if (module is IModuleUpdate updateSystem) if (module is IModuleUpdate updateSystem)
{ {
BindSystemLife<IModuleUpdate>(updateSystem, _updateModules, ref _isExecuteListDirty); BindSystemLife(updateSystem, _updateModules, ref _isExecuteListDirty);
} }
if (module is IModuleLateUpdate lateUpdate) if (module is IModuleLateUpdate lateUpdate)
{ {
BindSystemLife<IModuleLateUpdate>(lateUpdate, _lateUpdateModules, ref _isLateExecuteListDirty); BindSystemLife(lateUpdate, _lateUpdateModules, ref _isLateExecuteListDirty);
} }
if (module is IModuleFixedUpdate fixedUpdate) if (module is IModuleFixedUpdate fixedUpdate)
{ {
BindSystemLife<IModuleFixedUpdate>(fixedUpdate, _fixedUpdateModules, ref _isFixedExecuteListDirty); BindSystemLife(fixedUpdate, _fixedUpdateModules, ref _isFixedExecuteListDirty);
} }
if (module is IModuleDrawGizmos drawGizmosUpdate) if (module is IModuleDrawGizmos drawGizmosUpdate)
{ {
BindSystemLife<IModuleDrawGizmos>(drawGizmosUpdate, _gizmosUpdateModules, ref _isGizmosExecuteListDirty); BindSystemLife(drawGizmosUpdate, _gizmosUpdateModules, ref _isGizmosExecuteListDirty);
} }
if (module is IModuleGUI guiUpdate) if (module is IModuleGUI guiUpdate)
{ {
BindSystemLife<IModuleGUI>(guiUpdate, _guiUpdateModules, ref _isGUIExecuteListDirty); BindSystemLife(guiUpdate, _guiUpdateModules, ref _isGUIExecuteListDirty);
} }
} }
internal static void BindSystemLife<T>(T system, GameFrameworkLinkedList<T> updateModule, ref bool executeDirty) where T : IExecuteSystem private static void BindSystemLife<T>(T system, GameFrameworkLinkedList<T> updateModule, ref bool executeDirty) where T : IExecuteSystem
{ {
LinkedListNode<T> currentUpdate = updateModule.First; var current = updateModule.First;
while (currentUpdate != null) while (current != null && system.Priority <= current.Value.Priority)
{ {
if (system.Priority > currentUpdate.Value.Priority) current = current.Next;
{
break;
}
currentUpdate = currentUpdate.Next;
} }
if (currentUpdate != null) if (current != null)
{ {
updateModule.AddBefore(currentUpdate, system); updateModule.AddBefore(current, system);
} }
else else
{ {
@ -215,71 +216,61 @@ namespace AlicizaX
private static void BuildExecuteList() private static void BuildExecuteList()
{ {
if (_isExecuteListDirty) if (!_isExecuteListDirty) return;
_isExecuteListDirty = false;
_updateExecuteCount = 0;
foreach (var module in _updateModules)
{ {
_isExecuteListDirty = false; if (_updateExecuteCount >= _updateExecuteArray.Length) break;
Array.Clear(_updateExecuteArray, 0, _updateExecuteArray.Length); _updateExecuteArray[_updateExecuteCount++] = module;
int index = 0;
foreach (var module in _updateModules)
{
_updateExecuteArray[index++] = module;
}
} }
} }
private static void BuildLateExecuteList() private static void BuildLateExecuteList()
{ {
if (_isLateExecuteListDirty) if (!_isLateExecuteListDirty) return;
_isLateExecuteListDirty = false;
_lateUpdateExecuteCount = 0;
foreach (var module in _lateUpdateModules)
{ {
_isLateExecuteListDirty = false; if (_lateUpdateExecuteCount >= _lateUpdateExecuteArray.Length) break;
Array.Clear(_lateUpdateExecuteArray, 0, _lateUpdateExecuteArray.Length); _lateUpdateExecuteArray[_lateUpdateExecuteCount++] = module;
int index = 0;
foreach (var module in _lateUpdateModules)
{
_lateUpdateExecuteArray[index++] = module;
}
} }
} }
private static void BuildFixedExecuteList() private static void BuildFixedExecuteList()
{ {
if (_isFixedExecuteListDirty) if (!_isFixedExecuteListDirty) return;
_isFixedExecuteListDirty = false;
_fixedUpdateExecuteCount = 0;
foreach (var module in _fixedUpdateModules)
{ {
_isFixedExecuteListDirty = false; if (_fixedUpdateExecuteCount >= _fixedUpdateExecuteArray.Length) break;
Array.Clear(_fixedUpdateExecuteArray, 0, _fixedUpdateExecuteArray.Length); _fixedUpdateExecuteArray[_fixedUpdateExecuteCount++] = module;
int index = 0;
foreach (var module in _fixedUpdateModules)
{
_fixedUpdateExecuteArray[index++] = module;
}
} }
} }
private static void BuildGizmosExecuteList() private static void BuildGizmosExecuteList()
{ {
if (_isGizmosExecuteListDirty) if (!_isGizmosExecuteListDirty) return;
_isGizmosExecuteListDirty = false;
_gizmosExecuteCount = 0;
foreach (var module in _gizmosUpdateModules)
{ {
_isGizmosExecuteListDirty = false; if (_gizmosExecuteCount >= _gizmosUpdateExecuteArray.Length) break;
Array.Clear(_gizmosUpdateExecuteArray, 0, _gizmosUpdateExecuteArray.Length); _gizmosUpdateExecuteArray[_gizmosExecuteCount++] = module;
int index = 0;
foreach (var module in _gizmosUpdateModules)
{
_gizmosUpdateExecuteArray[index++] = module;
}
} }
} }
private static void BuildGUIExecuteList() private static void BuildGUIExecuteList()
{ {
if (_isGUIExecuteListDirty) if (!_isGUIExecuteListDirty) return;
_isGUIExecuteListDirty = false;
_guiExecuteCount = 0;
foreach (var module in _guiUpdateModules)
{ {
_isGUIExecuteListDirty = false; if (_guiExecuteCount >= _guiUpdateExecuteArray.Length) break;
Array.Clear(_guiUpdateExecuteArray, 0, _guiUpdateExecuteArray.Length); _guiUpdateExecuteArray[_guiExecuteCount++] = module;
int index = 0;
foreach (var module in _guiUpdateModules)
{
_guiUpdateExecuteArray[index++] = module;
}
} }
} }
@ -290,50 +281,45 @@ namespace AlicizaX
internal static void UpdateExecuteList(float elapseSeconds, float realElapseSeconds) internal static void UpdateExecuteList(float elapseSeconds, float realElapseSeconds)
{ {
BuildExecuteList(); BuildExecuteList();
int executeCount = _updateExecuteArray.Length; for (int i = 0; i < _updateExecuteCount; i++)
for (int i = 0; i < executeCount; i++)
{ {
_updateExecuteArray[i]?.Update(elapseSeconds, realElapseSeconds); _updateExecuteArray[i].Update(elapseSeconds, realElapseSeconds);
} }
} }
internal static void UpdateLateExecuteList() internal static void UpdateLateExecuteList()
{ {
BuildLateExecuteList(); BuildLateExecuteList();
int executeCount = _lateUpdateExecuteArray.Length; for (int i = 0; i < _lateUpdateExecuteCount; i++)
for (int i = 0; i < executeCount; i++)
{ {
_lateUpdateExecuteArray[i]?.LateUpdate(); _lateUpdateExecuteArray[i].LateUpdate();
} }
} }
internal static void UpdateFixedExecuteList() internal static void UpdateFixedExecuteList()
{ {
BuildFixedExecuteList(); BuildFixedExecuteList();
int executeCount = _fixedUpdateExecuteArray.Length; for (int i = 0; i < _fixedUpdateExecuteCount; i++)
for (int i = 0; i < executeCount; i++)
{ {
_fixedUpdateExecuteArray[i]?.FixedUpdate(); _fixedUpdateExecuteArray[i].FixedUpdate();
} }
} }
internal static void UpdateGizmosExecuteList() internal static void UpdateGizmosExecuteList()
{ {
BuildGizmosExecuteList(); BuildGizmosExecuteList();
int executeCount = _gizmosUpdateExecuteArray.Length; for (int i = 0; i < _gizmosExecuteCount; i++)
for (int i = 0; i < executeCount; i++)
{ {
_gizmosUpdateExecuteArray[i]?.DrawGizmos(); _gizmosUpdateExecuteArray[i].DrawGizmos();
} }
} }
internal static void UpdateGUIExecuteList() internal static void UpdateGUIExecuteList()
{ {
BuildGUIExecuteList(); BuildGUIExecuteList();
int executeCount = _guiUpdateExecuteArray.Length; for (int i = 0; i < _guiExecuteCount; i++)
for (int i = 0; i < executeCount; i++)
{ {
_guiUpdateExecuteArray[i]?.OnGUI(); _guiUpdateExecuteArray[i].OnGUI();
} }
} }

View File

@ -20,7 +20,7 @@ namespace AlicizaX
private void Awake() private void Awake()
{ {
_mObjectPoolModule = ModuleSystem.RegisterModule<IObjectPoolModule>(typeof(ObjectPoolModule)); _mObjectPoolModule = ModuleSystem.RegisterModule<IObjectPoolModule,ObjectPoolModule>();
if (_mObjectPoolModule == null) if (_mObjectPoolModule == null)
{ {
Log.Error("Object pool manager is invalid."); Log.Error("Object pool manager is invalid.");