2024-02-23 18:34:40 +08:00
using DCFApixels.DragonECS.Internal ;
using DCFApixels.DragonECS.RunnersCore ;
2023-05-27 23:02:32 +08:00
using System ;
2023-03-11 17:11:40 +08:00
using System.Linq ;
2024-10-31 14:48:56 +08:00
using System.Runtime.CompilerServices ;
2023-05-26 04:25:09 +08:00
using static DCFApixels . DragonECS . EcsDebugUtility ;
2023-03-11 17:11:40 +08:00
namespace DCFApixels.DragonECS
{
2024-06-13 18:04:18 +08:00
[MetaColor(MetaColor.DragonRose)]
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.OTHER_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaTags(MetaTags.HIDDEN)]
2024-10-12 00:08:12 +08:00
[MetaID("EF8A557C9201E6F04D4A76DC670BDE19")]
2024-06-05 14:39:19 +08:00
public interface IEcsProcess : IEcsMember { }
2023-03-16 01:49:14 +08:00
2023-04-23 17:55:01 +08:00
namespace RunnersCore
2023-03-11 17:11:40 +08:00
{
2024-02-23 18:34:40 +08:00
public abstract class EcsRunner
2023-03-11 17:11:40 +08:00
{
2024-02-23 18:34:40 +08:00
internal abstract void Init_Internal ( EcsPipeline source ) ;
2023-03-11 17:11:40 +08:00
2024-02-23 18:34:40 +08:00
#region CheckRunnerValide
public static void CheckRunnerTypeIsValide ( Type runnerType , Type processInterfaceType )
2023-12-06 21:15:35 +08:00
{
2024-02-23 18:34:40 +08:00
#region DEBUG
#pragma warning disable IL2070 // 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The parameter of method does not have matching annotations.
Type targetInterface = processInterfaceType ;
if ( runnerType . IsAbstract | | runnerType . IsInterface )
2023-12-06 21:15:35 +08:00
{
2024-11-06 19:55:33 +08:00
Throw . Exception ( "The instance of a runner cannot be abstract." ) ;
2023-12-06 21:15:35 +08:00
}
2024-01-08 13:39:38 +08:00
Type GetRunnerBaseType ( Type inType )
2023-12-06 21:15:35 +08:00
{
2024-01-08 13:39:38 +08:00
if ( inType . IsGenericType & & inType . GetGenericTypeDefinition ( ) = = typeof ( EcsRunner < > ) )
2024-02-23 18:34:40 +08:00
{
2024-01-08 13:39:38 +08:00
return inType ;
2024-02-23 18:34:40 +08:00
}
2024-01-08 13:39:38 +08:00
if ( inType . BaseType ! = null )
2024-02-23 18:34:40 +08:00
{
2024-01-08 13:39:38 +08:00
return GetRunnerBaseType ( inType . BaseType ) ;
2024-02-23 18:34:40 +08:00
}
2023-12-06 21:15:35 +08:00
return null ;
}
2024-02-23 18:34:40 +08:00
Type baseType = GetRunnerBaseType ( runnerType ) ;
2023-12-06 21:15:35 +08:00
Type baseTypeArgument = baseType . GenericTypeArguments [ 0 ] ;
if ( baseTypeArgument ! = targetInterface )
{
2024-02-23 18:34:40 +08:00
Throw . UndefinedException ( ) ;
2023-12-06 21:15:35 +08:00
}
2024-02-23 18:34:40 +08:00
if ( ! runnerType . GetInterfaces ( ) . Any ( o = > o = = targetInterface ) )
2023-12-06 20:34:33 +08:00
{
2024-02-23 18:34:40 +08:00
throw new EcsRunnerImplementationException ( $"Runner {GetGenericTypeFullName(runnerType, 1)} does not implement interface {GetGenericTypeFullName(baseTypeArgument, 1)}." ) ;
2023-12-06 20:34:33 +08:00
}
2024-02-23 18:34:40 +08:00
#pragma warning restore IL2070 // 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The parameter of method does not have matching annotations.
#endregion
2023-04-23 17:55:01 +08:00
}
#endregion
2024-02-23 18:34:40 +08:00
}
2024-06-13 18:04:18 +08:00
[MetaColor(MetaColor.DragonRose)]
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.OTHER_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaTags(MetaTags.HIDDEN)]
2024-10-12 00:08:12 +08:00
[MetaID("E49B557C92010E46DF1602972BC988BC")]
2024-02-23 18:34:40 +08:00
public interface IEcsRunner : IEcsProcess
{
EcsPipeline Pipeline { get ; }
Type Interface { get ; }
EcsProcessRaw ProcessRaw { get ; }
bool IsEmpty { get ; }
}
2024-10-31 14:48:56 +08:00
//TODO добавить функцию фильтрации систем по string, за счет создания отдельных ранеров для отдельных string
2024-06-13 18:04:18 +08:00
[MetaColor(MetaColor.DragonRose)]
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.OTHER_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaTags(MetaTags.HIDDEN)]
2024-10-12 00:08:12 +08:00
[MetaID("7DB3557C9201F85E0E1C17D7B19D9CEE")]
2024-02-23 18:34:40 +08:00
public abstract class EcsRunner < TProcess > : EcsRunner , IEcsRunner , IEcsProcess
where TProcess : IEcsProcess
{
2023-04-23 17:55:01 +08:00
private EcsPipeline _source ;
2024-02-22 15:39:37 +08:00
private EcsProcess < TProcess > _process ;
2024-02-23 18:34:40 +08:00
private bool _isInit = false ;
2023-03-26 11:19:03 +08:00
2023-04-23 17:55:01 +08:00
#region Properties
2024-02-22 15:39:37 +08:00
public EcsPipeline Pipeline
{
get { return _source ; }
}
public Type Interface
{
get { return typeof ( TProcess ) ; }
}
public EcsProcessRaw ProcessRaw
{
get { return _process ; }
}
public EcsProcess < TProcess > Process
{
get { return _process ; }
}
public bool IsEmpty
{
2024-02-22 23:48:10 +08:00
get { return _process . IsNullOrEmpty ; }
2024-02-22 15:39:37 +08:00
}
2023-04-23 17:55:01 +08:00
#endregion
2023-03-27 17:34:12 +08:00
2024-02-23 18:34:40 +08:00
#region Constructor Init OnSetup
public EcsRunner ( ) { }
internal override sealed void Init_Internal ( EcsPipeline source )
2023-04-23 17:55:01 +08:00
{
2024-02-23 18:34:40 +08:00
if ( _isInit )
{
2024-04-22 17:49:24 +08:00
Throw . Exception ( "Reinitialization." ) ;
2024-02-23 18:34:40 +08:00
}
_isInit = true ;
2023-04-23 17:55:01 +08:00
_source = source ;
2024-02-23 18:34:40 +08:00
_process = source . GetProcess < TProcess > ( ) ;
2023-04-23 17:55:01 +08:00
OnSetup ( ) ;
}
2024-02-23 18:34:40 +08:00
protected virtual void OnSetup ( ) { }
#endregion
2024-10-31 14:48:56 +08:00
#region Simple
public struct RunHelper
{
private readonly EcsProcess < TProcess > _process ;
2024-10-31 15:27:53 +08:00
#if DEBUG & & ! DISABLE_DEBUG
2024-10-31 14:48:56 +08:00
private Delegate _cacheCheck ;
private bool _cacheCheckInit ;
private readonly EcsProfilerMarker [ ] _markers ;
#endif
#region Constructors
2024-11-06 20:17:07 +08:00
public RunHelper ( EcsRunner < TProcess > runner ) : this ( runner ,
#if DEBUG & & ! DISABLE_DEBUG
typeof ( TProcess ) . ToMeta ( ) . Name )
#else
string . Empty
#endif
{ }
2024-10-31 15:27:53 +08:00
public RunHelper ( EcsRunner < TProcess > runner , string methodName )
2024-10-31 14:48:56 +08:00
{
_process = runner . Process ;
2024-10-31 15:27:53 +08:00
#if DEBUG & & ! DISABLE_DEBUG
2024-10-31 14:48:56 +08:00
_cacheCheck = null ;
_cacheCheckInit = false ;
_markers = new EcsProfilerMarker [ _process . Length ] ;
for ( int i = 0 ; i < _process . Length ; i + + )
{
_markers [ i ] = new EcsProfilerMarker ( $"{_process[i].GetMeta().Name}.{methodName}" ) ;
}
#endif
}
#endregion
2024-10-31 14:53:08 +08:00
#region Utils
2024-10-31 15:27:53 +08:00
#if DEBUG & & ! DISABLE_DEBUG
2024-10-31 14:48:56 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void CheckCache ( Delegate d )
{
if ( _cacheCheckInit = = false )
{
if ( _cacheCheck = = null )
{
_cacheCheck = d ;
}
else
{
if ( ReferenceEquals ( _cacheCheck , d ) = = false )
{
EcsDebug . PrintWarning ( "The delegate is not cached" ) ;
}
_cacheCheckInit = true ;
}
}
}
2024-10-31 15:27:53 +08:00
#endif
2024-10-31 14:48:56 +08:00
#endregion
#region Do
2024-10-31 15:27:53 +08:00
#pragma warning disable CS0162 // Обнаружен недостижимый код
2024-10-31 14:48:56 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-31 14:53:08 +08:00
public void Run ( Action < TProcess > translationCallback )
2024-10-31 14:48:56 +08:00
{
#if DEBUG & & ! DISABLE_DEBUG
2024-10-31 15:27:53 +08:00
CheckCache ( translationCallback ) ;
2024-10-31 14:48:56 +08:00
for ( int i = 0 , n = _process . Length < _markers . Length ? _process . Length : _markers . Length ; i < n ; i + + )
{
_markers [ i ] . Begin ( ) ;
try
{
translationCallback ( _process [ i ] ) ;
}
catch ( Exception e )
{
#if DISABLE_CATH_EXCEPTIONS
throw ;
#endif
EcsDebug . PrintError ( e ) ;
}
_markers [ i ] . End ( ) ;
}
#else
foreach ( var item in _process )
{
try
{
translationCallback ( item ) ;
}
catch ( Exception e )
{
#if DISABLE_CATH_EXCEPTIONS
throw ;
#endif
EcsDebug . PrintError ( e ) ;
}
}
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-31 15:27:53 +08:00
public void Run < T0 > ( Action < TProcess , T0 > translationCallback , T0 t0 )
2024-10-31 14:48:56 +08:00
{
#if DEBUG & & ! DISABLE_DEBUG
2024-10-31 15:27:53 +08:00
CheckCache ( translationCallback ) ;
2024-10-31 14:48:56 +08:00
for ( int i = 0 , n = _process . Length < _markers . Length ? _process . Length : _markers . Length ; i < n ; i + + )
{
_markers [ i ] . Begin ( ) ;
try
{
translationCallback ( _process [ i ] , t0 ) ;
}
catch ( Exception e )
{
#if DISABLE_CATH_EXCEPTIONS
throw ;
#endif
EcsDebug . PrintError ( e ) ;
}
_markers [ i ] . End ( ) ;
}
#else
foreach ( var item in _process )
{
try
{
2024-10-31 15:27:53 +08:00
translationCallback ( item , t0 ) ;
2024-10-31 14:48:56 +08:00
}
catch ( Exception e )
{
#if DISABLE_CATH_EXCEPTIONS
throw ;
#endif
EcsDebug . PrintError ( e ) ;
}
}
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-31 15:27:53 +08:00
public void Run < T0 , T1 > ( Action < TProcess , T0 , T1 > translationCallback , T0 t0 , T1 t1 )
2024-10-31 14:48:56 +08:00
{
#if DEBUG & & ! DISABLE_DEBUG
2024-10-31 15:27:53 +08:00
CheckCache ( translationCallback ) ;
2024-10-31 14:48:56 +08:00
for ( int i = 0 , n = _process . Length < _markers . Length ? _process . Length : _markers . Length ; i < n ; i + + )
{
_markers [ i ] . Begin ( ) ;
try
{
translationCallback ( _process [ i ] , t0 , t1 ) ;
}
catch ( Exception e )
{
#if DISABLE_CATH_EXCEPTIONS
throw ;
#endif
EcsDebug . PrintError ( e ) ;
}
_markers [ i ] . End ( ) ;
}
#else
foreach ( var item in _process )
{
try
{
2024-10-31 15:27:53 +08:00
translationCallback ( item , t0 , t1 ) ;
2024-10-31 14:48:56 +08:00
}
catch ( Exception e )
{
#if DISABLE_CATH_EXCEPTIONS
throw ;
#endif
EcsDebug . PrintError ( e ) ;
}
}
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-31 15:27:53 +08:00
public void Run < T0 , T1 , T2 > ( Action < TProcess , T0 , T1 , T2 > translationCallback , T0 t0 , T1 t1 , T2 t2 )
2024-10-31 14:48:56 +08:00
{
#if DEBUG & & ! DISABLE_DEBUG
2024-10-31 15:27:53 +08:00
CheckCache ( translationCallback ) ;
2024-10-31 14:48:56 +08:00
for ( int i = 0 , n = _process . Length < _markers . Length ? _process . Length : _markers . Length ; i < n ; i + + )
{
_markers [ i ] . Begin ( ) ;
try
{
translationCallback ( _process [ i ] , t0 , t1 , t2 ) ;
}
catch ( Exception e )
{
#if DISABLE_CATH_EXCEPTIONS
throw ;
#endif
EcsDebug . PrintError ( e ) ;
}
_markers [ i ] . End ( ) ;
}
#else
foreach ( var item in _process )
{
try
{
2024-10-31 15:27:53 +08:00
translationCallback ( item , t0 , t1 , t2 ) ;
2024-10-31 14:48:56 +08:00
}
catch ( Exception e )
{
#if DISABLE_CATH_EXCEPTIONS
throw ;
#endif
EcsDebug . PrintError ( e ) ;
}
}
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-31 15:27:53 +08:00
public void Run < T0 , T1 , T2 , T3 > ( Action < TProcess , T0 , T1 , T2 , T3 > translationCallback , T0 t0 , T1 t1 , T2 t2 , T3 t3 )
2024-10-31 14:48:56 +08:00
{
#if DEBUG & & ! DISABLE_DEBUG
2024-11-01 14:04:19 +08:00
CheckCache ( translationCallback ) ;
2024-10-31 14:48:56 +08:00
for ( int i = 0 , n = _process . Length < _markers . Length ? _process . Length : _markers . Length ; i < n ; i + + )
{
_markers [ i ] . Begin ( ) ;
try
{
translationCallback ( _process [ i ] , t0 , t1 , t2 , t3 ) ;
}
catch ( Exception e )
{
#if DISABLE_CATH_EXCEPTIONS
throw ;
#endif
EcsDebug . PrintError ( e ) ;
}
_markers [ i ] . End ( ) ;
}
#else
foreach ( var item in _process )
{
try
{
2024-10-31 15:27:53 +08:00
translationCallback ( item , t0 , t1 , t2 , t3 ) ;
2024-10-31 14:48:56 +08:00
}
catch ( Exception e )
{
#if DISABLE_CATH_EXCEPTIONS
throw ;
#endif
EcsDebug . PrintError ( e ) ;
}
}
#endif
}
2024-10-31 15:27:53 +08:00
#pragma warning restore CS0162 // Обнаружен недостижимый код
2024-10-31 14:48:56 +08:00
//------------------------
#endregion
}
#endregion
2023-04-23 17:55:01 +08:00
}
2023-03-11 17:11:40 +08:00
}
2023-05-26 04:25:09 +08:00
2023-03-30 01:57:10 +08:00
#region Extensions
2024-02-23 18:34:40 +08:00
public static class IEcsProcessExtensions
2023-03-30 01:57:10 +08:00
{
2024-02-22 22:16:03 +08:00
public static bool IsRunner ( this IEcsProcess self )
2023-03-30 01:57:10 +08:00
{
return self is IEcsRunner ;
}
}
#endregion
2024-10-31 14:48:56 +08:00
}