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

View File

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