2025-02-07 16:04:12 +08:00
using System ;
using System.Buffers ;
using System.Collections.Generic ;
2025-03-24 13:16:51 +08:00
namespace AlicizaX
2025-02-07 16:04:12 +08:00
{
2025-03-20 20:47:11 +08:00
public static class ModuleSystem
2025-02-07 16:04:12 +08:00
{
internal const int DesignModuleCount = 32 ;
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 < IModuleUpdate > _updateModules = new GameFrameworkLinkedList < IModuleUpdate > ( ) ;
private static readonly IModuleUpdate [ ] _updateExecuteArray = new IModuleUpdate [ DesignModuleCount ] ;
private static readonly GameFrameworkLinkedList < IModuleLateUpdate > _lateUpdateModules = new GameFrameworkLinkedList < IModuleLateUpdate > ( ) ;
private static readonly IModuleLateUpdate [ ] _lateUpdateExecuteArray = new IModuleLateUpdate [ DesignModuleCount ] ;
private static readonly GameFrameworkLinkedList < IModuleFixedUpdate > _fixedUpdateModules = new GameFrameworkLinkedList < IModuleFixedUpdate > ( ) ;
private static readonly IModuleFixedUpdate [ ] _fixedUpdateExecuteArray = new IModuleFixedUpdate [ DesignModuleCount ] ;
private static readonly GameFrameworkLinkedList < IModuleDrawGizmos > _gizmosUpdateModules = new GameFrameworkLinkedList < IModuleDrawGizmos > ( ) ;
private static readonly IModuleDrawGizmos [ ] _gizmosUpdateExecuteArray = new IModuleDrawGizmos [ DesignModuleCount ] ;
private static readonly GameFrameworkLinkedList < IModuleGUI > _guiUpdateModules = new GameFrameworkLinkedList < IModuleGUI > ( ) ;
private static readonly IModuleGUI [ ] _guiUpdateExecuteArray = new IModuleGUI [ DesignModuleCount ] ;
private static bool _isExecuteListDirty ;
private static bool _isLateExecuteListDirty ;
private static bool _isFixedExecuteListDirty ;
private static bool _isGizmosExecuteListDirty ;
private static bool _isGUIExecuteListDirty ;
internal static void Dispose ( )
{
_updateModules . Clear ( ) ;
Array . Clear ( _updateExecuteArray , 0 , _updateExecuteArray . Length ) ;
_lateUpdateModules . Clear ( ) ;
Array . Clear ( _lateUpdateExecuteArray , 0 , _lateUpdateExecuteArray . Length ) ;
_fixedUpdateModules . Clear ( ) ;
Array . Clear ( _fixedUpdateExecuteArray , 0 , _fixedUpdateExecuteArray . Length ) ;
_gizmosUpdateModules . Clear ( ) ;
Array . Clear ( _gizmosUpdateExecuteArray , 0 , _gizmosUpdateExecuteArray . Length ) ;
_guiUpdateModules . Clear ( ) ;
Array . Clear ( _guiUpdateExecuteArray , 0 , _guiUpdateExecuteArray . Length ) ;
for ( LinkedListNode < IModule > current = _modules . Last ; current ! = null ; current = current . Previous )
{
current . Value . Dispose ( ) ;
}
_modules . Clear ( ) ;
_moduleMaps . Clear ( ) ;
}
#region Public Manager
public static T RegisterManager < T > ( ) where T : AManager , new ( )
{
T manager = new T ( ) ;
if ( manager is IModuleAwake awakeManager )
{
awakeManager . Awake ( ) ;
}
AddManager ( manager ) ;
return manager ;
}
private static void AddManager ( AManager manager )
{
Type type = manager . GetType ( ) ;
_moduleMaps [ type ] = manager ;
_modules . AddLast ( manager ) ;
manager . Register ( ) ;
CheckSystemLife ( manager ) ;
}
#endregion
#region Public System
2025-03-20 20:47:11 +08:00
public static T RegisterModule < T > ( Type implType )
2025-02-07 16:04:12 +08:00
{
return ( T ) RegisterModule ( typeof ( T ) , implType ) ;
}
public static IModule RegisterModule ( Type interfaceType , Type implType )
{
if ( ! interfaceType . IsInterface )
{
throw new GameFrameworkException ( Utility . Text . Format ( "You must register module by interface, but '{0}' is not." , interfaceType . FullName ) ) ;
}
if ( ! implType . IsClass | | implType . IsInterface | | implType . IsAbstract )
{
throw new GameFrameworkException ( Utility . Text . Format ( "You must register module by Class and not Interface and Abstract, but '{0}' is not." , implType . FullName ) ) ;
}
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 ) ) ;
}
if ( GetModule ( interfaceType ) ! = null )
{
Log . Error ( "Already Register {0}" , interfaceType . FullName ) ;
return default ;
}
return SetModuleInstance ( interfaceType , implType ) ;
}
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 ) ) ;
}
return GetModule ( interfaceType ) as T ;
}
public static IModule GetModule ( Type moduleType )
{
if ( _moduleMaps . TryGetValue ( moduleType , out var ret ) )
{
return ret ;
}
return default ;
}
private static IModule SetModuleInstance ( Type interfaceType , Type implType )
{
IModule module = ( IModule ) Activator . CreateInstance ( implType ) ;
_moduleMaps [ interfaceType ] = module ;
_modules . AddLast ( module ) ;
if ( module is IModuleAwake awakeSystem )
{
awakeSystem . Awake ( ) ;
}
CheckSystemLife ( module ) ;
return module ;
}
#endregion
private static void CheckSystemLife ( IModule module )
{
if ( module is IModuleUpdate updateSystem )
{
BindSystemLife < IModuleUpdate > ( updateSystem , _updateModules , ref _isExecuteListDirty ) ;
}
if ( module is IModuleLateUpdate lateUpdate )
{
BindSystemLife < IModuleLateUpdate > ( lateUpdate , _lateUpdateModules , ref _isLateExecuteListDirty ) ;
}
if ( module is IModuleFixedUpdate fixedUpdate )
{
BindSystemLife < IModuleFixedUpdate > ( fixedUpdate , _fixedUpdateModules , ref _isFixedExecuteListDirty ) ;
}
if ( module is IModuleDrawGizmos drawGizmosUpdate )
{
BindSystemLife < IModuleDrawGizmos > ( drawGizmosUpdate , _gizmosUpdateModules , ref _isGizmosExecuteListDirty ) ;
}
if ( module is IModuleGUI guiUpdate )
{
BindSystemLife < IModuleGUI > ( guiUpdate , _guiUpdateModules , ref _isGUIExecuteListDirty ) ;
}
}
internal static void BindSystemLife < T > ( T system , GameFrameworkLinkedList < T > updateModule , ref bool executeDirty ) where T : IExecuteSystem
{
LinkedListNode < T > currentUpdate = updateModule . First ;
while ( currentUpdate ! = null )
{
if ( system . Priority > currentUpdate . Value . Priority )
{
break ;
}
currentUpdate = currentUpdate . Next ;
}
if ( currentUpdate ! = null )
{
updateModule . AddBefore ( currentUpdate , system ) ;
}
else
{
updateModule . AddLast ( system ) ;
}
executeDirty = true ;
}
#region BuildExecuteList
private static void BuildExecuteList ( )
{
if ( _isExecuteListDirty )
{
_isExecuteListDirty = false ;
Array . Clear ( _updateExecuteArray , 0 , _updateExecuteArray . Length ) ;
int index = 0 ;
foreach ( var module in _updateModules )
{
_updateExecuteArray [ index + + ] = module ;
}
}
}
private static void BuildLateExecuteList ( )
{
if ( _isLateExecuteListDirty )
{
_isLateExecuteListDirty = false ;
Array . Clear ( _lateUpdateExecuteArray , 0 , _lateUpdateExecuteArray . Length ) ;
int index = 0 ;
foreach ( var module in _lateUpdateModules )
{
_lateUpdateExecuteArray [ index + + ] = module ;
}
}
}
private static void BuildFixedExecuteList ( )
{
if ( _isFixedExecuteListDirty )
{
_isFixedExecuteListDirty = false ;
Array . Clear ( _fixedUpdateExecuteArray , 0 , _fixedUpdateExecuteArray . Length ) ;
int index = 0 ;
foreach ( var module in _fixedUpdateModules )
{
_fixedUpdateExecuteArray [ index + + ] = module ;
}
}
}
private static void BuildGizmosExecuteList ( )
{
if ( _isGizmosExecuteListDirty )
{
_isGizmosExecuteListDirty = false ;
Array . Clear ( _gizmosUpdateExecuteArray , 0 , _gizmosUpdateExecuteArray . Length ) ;
int index = 0 ;
foreach ( var module in _gizmosUpdateModules )
{
_gizmosUpdateExecuteArray [ index + + ] = module ;
}
}
}
private static void BuildGUIExecuteList ( )
{
if ( _isGUIExecuteListDirty )
{
_isGUIExecuteListDirty = false ;
Array . Clear ( _guiUpdateExecuteArray , 0 , _guiUpdateExecuteArray . Length ) ;
int index = 0 ;
foreach ( var module in _guiUpdateModules )
{
_guiUpdateExecuteArray [ index + + ] = module ;
}
}
}
#endregion
#region RunExecuteList
internal static void UpdateExecuteList ( float elapseSeconds , float realElapseSeconds )
{
BuildExecuteList ( ) ;
int executeCount = _updateExecuteArray . Length ;
for ( int i = 0 ; i < executeCount ; i + + )
{
_updateExecuteArray [ i ] ? . Update ( elapseSeconds , realElapseSeconds ) ;
}
}
internal static void UpdateLateExecuteList ( )
{
BuildLateExecuteList ( ) ;
int executeCount = _lateUpdateExecuteArray . Length ;
for ( int i = 0 ; i < executeCount ; i + + )
{
_lateUpdateExecuteArray [ i ] ? . LateUpdate ( ) ;
}
}
internal static void UpdateFixedExecuteList ( )
{
BuildFixedExecuteList ( ) ;
int executeCount = _fixedUpdateExecuteArray . Length ;
for ( int i = 0 ; i < executeCount ; i + + )
{
_fixedUpdateExecuteArray [ i ] ? . FixedUpdate ( ) ;
}
}
internal static void UpdateGizmosExecuteList ( )
{
BuildGizmosExecuteList ( ) ;
int executeCount = _gizmosUpdateExecuteArray . Length ;
for ( int i = 0 ; i < executeCount ; i + + )
{
_gizmosUpdateExecuteArray [ i ] ? . DrawGizmos ( ) ;
}
}
internal static void UpdateGUIExecuteList ( )
{
BuildGUIExecuteList ( ) ;
int executeCount = _guiUpdateExecuteArray . Length ;
for ( int i = 0 ; i < executeCount ; i + + )
{
_guiUpdateExecuteArray [ i ] ? . OnGUI ( ) ;
}
}
#endregion
}
}