2023-05-26 04:31:31 +08:00
using DCFApixels.DragonECS.Internal ;
using DCFApixels.DragonECS.RunnersCore ;
2023-04-23 17:55:01 +08:00
using System ;
2023-05-07 00:50:02 +08:00
using System.Collections ;
2023-03-26 11:19:03 +08:00
using System.Collections.Generic ;
2023-05-07 00:50:02 +08:00
using System.Linq ;
2023-03-26 11:19:03 +08:00
using System.Runtime.CompilerServices ;
namespace DCFApixels.DragonECS
{
2024-02-22 22:16:03 +08:00
public interface IEcsPipelineMember : IEcsProcess
2024-02-17 00:10:38 +08:00
{
2024-02-22 22:16:03 +08:00
EcsPipeline Pipeline { get ; set ; }
2024-02-17 00:10:38 +08:00
}
2023-03-30 05:32:43 +08:00
public sealed class EcsPipeline
2023-03-26 11:19:03 +08:00
{
2024-02-22 15:39:37 +08:00
private readonly IEcsPipelineConfig _config ;
2024-02-22 23:48:10 +08:00
private Injector . Builder _injectorBuilder ;
private Injector _injector ;
2023-03-26 11:19:03 +08:00
2024-02-22 22:16:03 +08:00
private IEcsProcess [ ] _allSystems ;
2024-02-22 15:39:37 +08:00
private Dictionary < Type , Array > _processes = new Dictionary < Type , Array > ( ) ;
private Dictionary < Type , IEcsRunner > _runners = new Dictionary < Type , IEcsRunner > ( ) ;
2024-02-23 18:34:40 +08:00
private EcsRunRunner _runRunnerCache ;
2023-03-26 11:19:03 +08:00
2023-06-26 02:53:55 +08:00
private bool _isInit = false ;
private bool _isDestoryed = false ;
2023-03-26 11:19:03 +08:00
2024-02-23 18:34:40 +08:00
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ENABLE_DRAGONECS_ASSERT_CHEKS
2024-02-25 18:33:17 +08:00
private EcsProfilerMarker _initMarker = new EcsProfilerMarker ( "EcsPipeline.Init" ) ;
2024-02-23 18:34:40 +08:00
#endif
2024-02-22 23:48:10 +08:00
2023-03-26 11:19:03 +08:00
#region Properties
2024-02-22 15:39:37 +08:00
public IEcsPipelineConfig Config
{
get { return _config ; }
}
2024-02-22 22:16:03 +08:00
public Injector Injector
2024-02-22 15:39:37 +08:00
{
2024-02-22 22:16:03 +08:00
get { return _injector ; }
}
public EcsProcess < IEcsProcess > AllSystems
{
get { return new EcsProcess < IEcsProcess > ( _allSystems ) ; }
2024-02-22 15:39:37 +08:00
}
public IReadOnlyDictionary < Type , IEcsRunner > AllRunners
{
get { return _runners ; }
}
2024-02-22 23:48:10 +08:00
public bool IsInit
{
get { return _isInit ; }
2024-02-22 15:39:37 +08:00
}
2024-02-22 23:48:10 +08:00
public bool IsDestoryed
{
get { return _isDestoryed ; }
2024-02-22 15:39:37 +08:00
}
2023-03-26 11:19:03 +08:00
#endregion
#region Constructors
2024-02-22 23:48:10 +08:00
private EcsPipeline ( IEcsPipelineConfig config , Injector . Builder injectorBuilder , IEcsProcess [ ] systems )
2023-03-26 11:19:03 +08:00
{
2024-02-22 15:39:37 +08:00
_config = config ;
2023-03-26 11:19:03 +08:00
_allSystems = systems ;
2024-02-22 23:48:10 +08:00
_injectorBuilder = injectorBuilder ;
2024-02-25 18:33:17 +08:00
_injectorBuilder . Inject ( this ) ;
2023-03-26 11:19:03 +08:00
}
#endregion
2024-02-26 08:31:35 +08:00
#region GetProcess
2024-02-22 22:16:03 +08:00
public EcsProcess < T > GetProcess < T > ( ) where T : IEcsProcess
2024-02-17 00:10:27 +08:00
{
2024-02-22 15:39:37 +08:00
Type type = typeof ( T ) ;
T [ ] result ;
2024-02-22 23:48:10 +08:00
if ( _processes . TryGetValue ( type , out Array array ) )
2024-02-22 15:39:37 +08:00
{
result = ( T [ ] ) array ;
}
else
{
result = _allSystems . OfType < T > ( ) . ToArray ( ) ;
_processes . Add ( type , result ) ;
}
return new EcsProcess < T > ( result ) ;
2024-02-17 00:10:27 +08:00
}
2024-02-23 18:34:40 +08:00
#endregion
2024-02-26 08:31:35 +08:00
#region GetRunner
public TRunner GetRunnerInstance < TRunner > ( ) where TRunner : EcsRunner , IEcsRunner , new ( )
2024-02-23 18:34:40 +08:00
{
Type runnerType = typeof ( TRunner ) ;
if ( _runners . TryGetValue ( runnerType , out IEcsRunner result ) )
{
return ( TRunner ) result ;
}
TRunner instance = new TRunner ( ) ;
#if DEBUG
EcsRunner . CheckRunnerTypeIsValide ( runnerType , instance . Interface ) ;
#endif
instance . Init_Internal ( this ) ;
_runners . Add ( runnerType , instance ) ;
_runners . Add ( instance . Interface , instance ) ;
return instance ;
}
2024-02-22 22:16:03 +08:00
public T GetRunner < T > ( ) where T : IEcsProcess
2024-01-26 02:26:17 +08:00
{
2024-02-23 18:34:40 +08:00
if ( _runners . TryGetValue ( typeof ( T ) , out IEcsRunner result ) )
2024-02-17 00:10:27 +08:00
{
2024-02-23 18:34:40 +08:00
return ( T ) result ;
2024-02-17 00:10:27 +08:00
}
2024-02-23 18:34:40 +08:00
Throw . UndefinedException ( ) ;
return default ;
2024-01-26 02:26:17 +08:00
}
2024-02-23 18:34:40 +08:00
public bool TryGetRunner < T > ( out T runner ) where T : IEcsProcess
2023-03-26 11:19:03 +08:00
{
2024-02-23 18:34:40 +08:00
if ( _runners . TryGetValue ( typeof ( T ) , out IEcsRunner result ) )
2024-01-26 02:26:17 +08:00
{
2024-02-23 18:34:40 +08:00
runner = ( T ) result ;
return true ;
2024-01-26 02:26:17 +08:00
}
2024-02-23 18:34:40 +08:00
runner = default ;
return false ;
2023-03-26 11:19:03 +08:00
}
2024-02-22 15:39:37 +08:00
#endregion
#region Internal
internal void OnRunnerDestroy_Internal ( IEcsRunner runner )
2023-03-30 05:32:43 +08:00
{
_runners . Remove ( runner . Interface ) ;
}
2023-03-26 11:19:03 +08:00
#endregion
#region LifeCycle
2023-03-29 04:23:37 +08:00
public void Init ( )
{
2023-04-01 20:45:37 +08:00
if ( _isInit = = true )
2023-03-29 04:23:37 +08:00
{
2023-12-06 20:35:07 +08:00
EcsDebug . PrintWarning ( $"This {nameof(EcsPipeline)} has already been initialized" ) ;
2023-03-29 04:23:37 +08:00
return ;
}
2024-02-23 18:34:40 +08:00
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ENABLE_DRAGONECS_ASSERT_CHEKS
2024-02-25 18:33:17 +08:00
_initMarker . Begin ( ) ;
2024-02-23 18:34:40 +08:00
#endif
2024-02-22 23:48:10 +08:00
_injector = _injectorBuilder . Build ( this ) ;
_injectorBuilder = null ;
2024-02-17 00:10:38 +08:00
2024-02-26 08:31:35 +08:00
GetRunnerInstance < EcsPreInitRunner > ( ) . PreInit ( ) ;
GetRunnerInstance < EcsInitRunner > ( ) . Init ( ) ;
_runRunnerCache = GetRunnerInstance < EcsRunRunner > ( ) ;
2023-03-29 04:23:37 +08:00
2023-06-10 19:46:35 +08:00
_isInit = true ;
2024-02-22 22:16:03 +08:00
2023-10-31 03:03:13 +08:00
GC . Collect ( ) ;
2024-02-23 18:34:40 +08:00
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ENABLE_DRAGONECS_ASSERT_CHEKS
2024-02-25 18:33:17 +08:00
_initMarker . End ( ) ;
2024-02-23 18:34:40 +08:00
#endif
2023-03-29 04:23:37 +08:00
}
2023-03-26 11:19:03 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Run ( )
{
2023-06-02 01:20:46 +08:00
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ENABLE_DRAGONECS_ASSERT_CHEKS
2024-02-23 18:34:40 +08:00
if ( ! _isInit ) { Throw . Pipeline_MethodCalledBeforeInitialisation ( nameof ( Run ) ) ; }
if ( _isDestoryed ) { Throw . Pipeline_MethodCalledAfterDestruction ( nameof ( Run ) ) ; }
2023-03-26 11:19:03 +08:00
#endif
2023-12-06 18:58:06 +08:00
_runRunnerCache . Run ( ) ;
2023-03-26 11:19:03 +08:00
}
public void Destroy ( )
{
2023-06-02 01:20:46 +08:00
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ENABLE_DRAGONECS_ASSERT_CHEKS
2024-02-23 18:34:40 +08:00
if ( ! _isInit ) { Throw . Pipeline_MethodCalledBeforeInitialisation ( nameof ( Destroy ) ) ; }
2023-03-26 11:19:03 +08:00
#endif
2023-06-26 02:53:55 +08:00
if ( _isDestoryed )
2023-03-29 04:23:37 +08:00
{
2023-06-26 01:57:50 +08:00
EcsDebug . PrintWarning ( $"This {nameof(EcsPipeline)} has already been destroyed" ) ;
2023-03-29 04:23:37 +08:00
return ;
}
2023-03-26 11:19:03 +08:00
_isDestoryed = true ;
2024-02-26 08:31:35 +08:00
GetRunnerInstance < EcsDestroyRunner > ( ) . Destroy ( ) ;
2023-03-26 11:19:03 +08:00
}
#endregion
#region Builder
2024-02-22 15:39:37 +08:00
public static Builder New ( IEcsPipelineConfigWriter config = null )
{
return new Builder ( config ) ;
}
2023-03-26 11:19:03 +08:00
public class Builder
{
private const int KEYS_CAPACITY = 4 ;
2023-03-30 05:32:43 +08:00
private HashSet < Type > _uniqueTypes ;
2024-02-22 22:16:03 +08:00
private readonly Dictionary < string , List < IEcsProcess > > _systems ;
2023-05-07 00:50:02 +08:00
private readonly string _basicLayer ;
public readonly LayerList Layers ;
2024-02-22 15:39:37 +08:00
private readonly IEcsPipelineConfigWriter _config ;
2024-02-22 22:16:03 +08:00
private readonly Injector . Builder _injector ;
2024-02-23 18:34:40 +08:00
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ENABLE_DRAGONECS_ASSERT_CHEKS
2024-02-22 23:48:10 +08:00
private EcsProfilerMarker _buildBarker = new EcsProfilerMarker ( "EcsPipeline.Build" ) ;
2024-02-23 18:34:40 +08:00
#endif
private List < InitDeclaredRunner > _initDeclaredRunners = new List < InitDeclaredRunner > ( 4 ) ;
2024-02-22 16:05:31 +08:00
2024-02-22 15:39:37 +08:00
public IEcsPipelineConfigWriter Config
{
get { return _config ; }
}
2024-02-22 22:16:03 +08:00
public Injector . Builder Injector
{
get { return _injector ; }
}
2024-02-22 15:39:37 +08:00
public Builder ( IEcsPipelineConfigWriter config = null )
2023-03-26 11:19:03 +08:00
{
2024-02-23 18:34:40 +08:00
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ENABLE_DRAGONECS_ASSERT_CHEKS
2024-02-22 16:05:31 +08:00
_buildBarker . Begin ( ) ;
2024-02-23 18:34:40 +08:00
#endif
2024-02-22 22:16:03 +08:00
if ( config = = null ) { config = new EcsPipelineConfig ( ) ; }
2024-02-22 15:39:37 +08:00
_config = config ;
2024-02-22 22:16:03 +08:00
_injector = new Injector . Builder ( this ) ;
2024-02-26 10:37:58 +08:00
_injector . AddNode < object > ( ) ;
_injector . AddNode < EcsWorld > ( ) ;
_injector . AddNode < EcsAspect > ( ) ;
_injector . AddCustomNode ( new PipelinePropertyInjectionNode ( ) ) ;
2024-02-22 22:16:03 +08:00
2023-05-07 00:50:02 +08:00
_basicLayer = EcsConsts . BASIC_LAYER ;
Layers = new LayerList ( this , _basicLayer ) ;
Layers . Insert ( EcsConsts . BASIC_LAYER , EcsConsts . PRE_BEGIN_LAYER , EcsConsts . BEGIN_LAYER ) ;
Layers . InsertAfter ( EcsConsts . BASIC_LAYER , EcsConsts . END_LAYER , EcsConsts . POST_END_LAYER ) ;
2024-02-22 22:16:03 +08:00
2023-05-07 00:50:02 +08:00
_uniqueTypes = new HashSet < Type > ( ) ;
2024-02-22 22:16:03 +08:00
_systems = new Dictionary < string , List < IEcsProcess > > ( KEYS_CAPACITY ) ;
2023-03-26 11:19:03 +08:00
}
2024-02-26 08:48:22 +08:00
public Builder AddRunner < TRunner > ( ) where TRunner : EcsRunner , IEcsRunner , new ( )
2024-02-23 18:34:40 +08:00
{
2024-02-26 08:48:22 +08:00
_initDeclaredRunners . Add ( new InitDeclaredRunner < TRunner > ( ) ) ;
2024-02-23 18:34:40 +08:00
return this ;
}
2024-02-22 22:16:03 +08:00
public Builder Add ( IEcsProcess system , string layerName = null )
2023-03-30 05:32:43 +08:00
{
2023-05-07 00:50:02 +08:00
AddInternal ( system , layerName , false ) ;
2023-03-30 05:32:43 +08:00
return this ;
}
2024-02-22 22:16:03 +08:00
public Builder AddUnique ( IEcsProcess system , string layerName = null )
2023-03-30 05:32:43 +08:00
{
2023-05-07 00:50:02 +08:00
AddInternal ( system , layerName , true ) ;
2023-03-30 05:32:43 +08:00
return this ;
}
2023-05-23 01:47:28 +08:00
public Builder Remove < TSystem > ( )
{
_uniqueTypes . Remove ( typeof ( TSystem ) ) ;
foreach ( var list in _systems . Values )
2024-02-22 22:16:03 +08:00
{
2023-05-23 01:47:28 +08:00
list . RemoveAll ( o = > o is TSystem ) ;
2024-02-22 22:16:03 +08:00
}
2023-05-23 01:47:28 +08:00
return this ;
}
2024-02-22 22:16:03 +08:00
private void AddInternal ( IEcsProcess system , string layerName , bool isUnique )
2023-03-26 11:19:03 +08:00
{
2023-05-07 00:50:02 +08:00
if ( layerName = = null ) layerName = _basicLayer ;
2024-02-22 22:16:03 +08:00
List < IEcsProcess > list ;
2023-05-07 00:50:02 +08:00
if ( ! _systems . TryGetValue ( layerName , out list ) )
2023-03-26 11:19:03 +08:00
{
2024-02-22 22:16:03 +08:00
list = new List < IEcsProcess > { new SystemsLayerMarkerSystem ( layerName . ToString ( ) ) } ;
2023-05-07 00:50:02 +08:00
_systems . Add ( layerName , list ) ;
2023-03-26 11:19:03 +08:00
}
2023-03-30 05:32:43 +08:00
if ( ( _uniqueTypes . Add ( system . GetType ( ) ) = = false & & isUnique ) )
return ;
2023-03-26 11:19:03 +08:00
list . Add ( system ) ;
2023-05-07 00:50:02 +08:00
if ( system is IEcsModule module ) //если система одновременно явялется и системой и модулем то за один Add будет вызван Add и AddModule
AddModule ( module ) ;
2023-03-26 11:19:03 +08:00
}
2023-04-26 16:45:37 +08:00
public Builder AddModule ( IEcsModule module )
2023-03-26 11:19:03 +08:00
{
2023-05-30 17:56:53 +08:00
module . Import ( this ) ;
2023-03-26 11:19:03 +08:00
return this ;
}
2023-05-07 00:50:02 +08:00
public EcsPipeline Build ( )
2023-03-26 11:19:03 +08:00
{
2024-02-22 22:16:03 +08:00
List < IEcsProcess > result = new List < IEcsProcess > ( 32 ) ;
List < IEcsProcess > basicBlockList = _systems [ _basicLayer ] ;
2023-05-07 00:50:02 +08:00
foreach ( var item in _systems )
{
2023-05-30 00:13:05 +08:00
if ( ! Layers . Contains ( item . Key ) )
2023-05-07 00:50:02 +08:00
basicBlockList . AddRange ( item . Value ) ;
}
foreach ( var item in Layers )
2023-04-26 16:45:37 +08:00
{
2023-05-30 18:30:10 +08:00
if ( _systems . TryGetValue ( item , out var list ) )
2023-05-07 00:50:02 +08:00
result . AddRange ( list ) ;
2023-04-26 16:45:37 +08:00
}
2024-02-23 18:34:40 +08:00
EcsPipeline pipeline = new EcsPipeline ( _config . GetPipelineConfig ( ) , _injector , result . ToArray ( ) ) ;
foreach ( var item in _initDeclaredRunners )
{
item . Declare ( pipeline ) ;
}
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ENABLE_DRAGONECS_ASSERT_CHEKS
2024-02-22 16:05:31 +08:00
_buildBarker . End ( ) ;
2024-02-23 18:34:40 +08:00
#endif
return pipeline ;
2023-04-26 16:45:37 +08:00
}
2024-02-22 22:16:03 +08:00
2024-02-23 18:34:40 +08:00
private abstract class InitDeclaredRunner
{
public abstract void Declare ( EcsPipeline pipeline ) ;
}
private class InitDeclaredRunner < T > : InitDeclaredRunner where T : EcsRunner , IEcsRunner , new ( )
{
public override void Declare ( EcsPipeline pipeline )
{
2024-02-26 08:31:35 +08:00
pipeline . GetRunnerInstance < T > ( ) ;
2024-02-23 18:34:40 +08:00
}
}
2023-05-07 00:50:02 +08:00
public class LayerList : IEnumerable < string >
2023-03-26 11:19:03 +08:00
{
2023-05-07 00:50:02 +08:00
private const string ADD_LAYER = nameof ( ADD_LAYER ) ; // автоматический слой нужный только для метода Add
private Builder _source ;
private List < string > _layers ;
private string _basicLayerName ;
public LayerList ( Builder source , string basicLayerName )
2023-03-26 11:19:03 +08:00
{
2023-05-07 00:50:02 +08:00
_source = source ;
_layers = new List < string > ( 16 ) { basicLayerName , ADD_LAYER } ;
2023-05-30 18:30:10 +08:00
_basicLayerName = basicLayerName ;
2023-03-26 11:19:03 +08:00
}
2023-05-07 00:50:02 +08:00
public Builder Add ( string newLayer ) = > Insert ( ADD_LAYER , newLayer ) ;
public Builder Insert ( string targetLayer , string newLayer )
{
2023-05-30 00:13:05 +08:00
if ( Contains ( newLayer ) ) return _source ;
2023-03-26 11:19:03 +08:00
2023-05-07 00:50:02 +08:00
int index = _layers . IndexOf ( targetLayer ) ;
if ( index < 0 )
throw new KeyNotFoundException ( $"Layer {targetLayer} not found" ) ;
_layers . Insert ( index , newLayer ) ;
return _source ;
}
public Builder InsertAfter ( string targetLayer , string newLayer )
{
2023-05-30 00:13:05 +08:00
if ( Contains ( newLayer ) ) return _source ;
2023-03-26 11:19:03 +08:00
2023-05-07 00:50:02 +08:00
if ( targetLayer = = _basicLayerName ) // нужно чтобы метод Add работал правильно. _basicLayerName и ADD_LAYER считается одним слоем, поэтому Before = _basicLayerName After = ADD_LAYER
targetLayer = ADD_LAYER ;
2023-03-26 11:19:03 +08:00
2023-05-07 00:50:02 +08:00
int index = _layers . IndexOf ( targetLayer ) ;
if ( index < 0 )
throw new KeyNotFoundException ( $"Layer {targetLayer} not found" ) ;
if ( + + index > = _layers . Count )
_layers . Add ( newLayer ) ;
else
_layers . Insert ( index , newLayer ) ;
return _source ;
}
public Builder Move ( string targetLayer , string movingLayer )
2023-03-26 11:19:03 +08:00
{
2023-05-07 00:50:02 +08:00
_layers . Remove ( movingLayer ) ;
return Insert ( targetLayer , movingLayer ) ;
2023-03-26 11:19:03 +08:00
}
2023-05-07 00:50:02 +08:00
public Builder MoveAfter ( string targetLayer , string movingLayer )
2023-03-26 11:19:03 +08:00
{
2023-05-07 00:50:02 +08:00
if ( targetLayer = = _basicLayerName ) // нужно чтобы метод Add работал правильно. _basicLayerName и ADD_LAYER считается одним слоем, поэтому Before = _basicLayerName After = ADD_LAYER
targetLayer = ADD_LAYER ;
_layers . Remove ( movingLayer ) ;
return InsertAfter ( targetLayer , movingLayer ) ;
2023-03-26 11:19:03 +08:00
}
2023-05-07 00:50:02 +08:00
public Builder Add ( params string [ ] newLayers ) = > Insert ( ADD_LAYER , newLayers ) ;
public Builder Insert ( string targetLayer , params string [ ] newLayers )
{
int index = _layers . IndexOf ( targetLayer ) ;
if ( index < 0 )
throw new KeyNotFoundException ( $"Layer {targetLayer} not found" ) ;
2023-05-30 00:13:05 +08:00
_layers . InsertRange ( index , newLayers . Where ( o = > ! Contains ( o ) ) ) ;
2023-05-07 00:50:02 +08:00
return _source ;
}
public Builder InsertAfter ( string targetLayer , params string [ ] newLayers )
{
int index = _layers . IndexOf ( targetLayer ) ;
if ( index < 0 )
throw new KeyNotFoundException ( $"Layer {targetLayer} not found" ) ;
if ( targetLayer = = _basicLayerName ) // нужно чтобы метод Add работал правильно. _basicLayerName и ADD_LAYER считается одним слоем, поэтому Before = _basicLayerName After = ADD_LAYER
targetLayer = ADD_LAYER ;
if ( + + index > = _layers . Count )
2023-05-30 00:13:05 +08:00
_layers . AddRange ( newLayers . Where ( o = > ! Contains ( o ) ) ) ;
2023-05-07 00:50:02 +08:00
else
2023-05-30 00:13:05 +08:00
_layers . InsertRange ( index , newLayers . Where ( o = > ! Contains ( o ) ) ) ;
2023-05-07 00:50:02 +08:00
return _source ;
}
public Builder Move ( string targetLayer , params string [ ] movingLayers )
{
foreach ( var movingLayer in movingLayers )
_layers . Remove ( movingLayer ) ;
return Insert ( targetLayer , movingLayers ) ;
}
public Builder MoveAfter ( string targetLayer , params string [ ] movingLayers )
{
if ( targetLayer = = _basicLayerName ) // нужно чтобы метод Add работал правильно. _basicLayerName и ADD_LAYER считается одним слоем, поэтому Before = _basicLayerName After = ADD_LAYER
targetLayer = ADD_LAYER ;
foreach ( var movingLayer in movingLayers )
_layers . Remove ( movingLayer ) ;
return InsertAfter ( targetLayer , movingLayers ) ;
}
2023-05-30 00:13:05 +08:00
public bool Contains ( string layer ) = > _layers . Contains ( layer ) ;
2023-05-07 00:50:02 +08:00
public List < string > . Enumerator GetEnumerator ( ) = > _layers . GetEnumerator ( ) ;
IEnumerator < string > IEnumerable < string > . GetEnumerator ( ) = > _layers . GetEnumerator ( ) ;
IEnumerator IEnumerable . GetEnumerator ( ) = > _layers . GetEnumerator ( ) ;
2023-03-26 11:19:03 +08:00
}
}
#endregion
}
public interface IEcsModule
{
2023-05-30 17:56:53 +08:00
void Import ( EcsPipeline . Builder b ) ;
2023-03-26 11:19:03 +08:00
}
2023-03-30 05:32:43 +08:00
#region Extensions
2023-06-22 14:31:13 +08:00
public static partial class EcsPipelineExtensions
2023-03-26 11:19:03 +08:00
{
2024-02-22 15:39:37 +08:00
public static bool IsNullOrDestroyed ( this EcsPipeline self )
2023-03-26 11:19:03 +08:00
{
2024-02-22 15:39:37 +08:00
return self = = null | | self . IsDestoryed ;
}
2024-02-22 22:16:03 +08:00
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , IEnumerable < IEcsProcess > range , string layerName = null )
2024-02-22 15:39:37 +08:00
{
foreach ( var item in range )
{
self . Add ( item , layerName ) ;
}
2023-03-26 11:19:03 +08:00
return self ;
}
2024-02-22 22:16:03 +08:00
public static EcsPipeline . Builder AddUnique ( this EcsPipeline . Builder self , IEnumerable < IEcsProcess > range , string layerName = null )
2023-03-30 05:32:43 +08:00
{
2024-02-22 15:39:37 +08:00
foreach ( var item in range )
{
self . AddUnique ( item , layerName ) ;
}
2023-03-30 05:32:43 +08:00
return self ;
}
public static EcsPipeline BuildAndInit ( this EcsPipeline . Builder self )
2023-03-29 04:23:37 +08:00
{
2023-03-30 05:32:43 +08:00
EcsPipeline result = self . Build ( ) ;
2023-03-29 04:23:37 +08:00
result . Init ( ) ;
return result ;
}
2023-03-26 11:19:03 +08:00
}
2023-03-30 05:32:43 +08:00
#endregion
2024-02-22 15:39:37 +08:00
#region SystemsLayerMarkerSystem
[MetaTags(MetaTags.HIDDEN)]
[MetaColor(MetaColor.Black)]
2024-02-22 22:16:03 +08:00
public class SystemsLayerMarkerSystem : IEcsProcess
2024-02-22 15:39:37 +08:00
{
public readonly string name ;
public SystemsLayerMarkerSystem ( string name ) = > this . name = name ;
}
#endregion
#region EcsProcess
public readonly struct EcsProcessRaw : IEnumerable
{
private readonly Array _systems ;
public int Length
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _systems . Length ; }
}
2024-02-22 22:16:03 +08:00
public IEcsProcess this [ int index ]
2024-02-22 15:39:37 +08:00
{
2024-02-22 22:16:03 +08:00
get { return ( IEcsProcess ) _systems . GetValue ( index ) ; }
2024-02-22 15:39:37 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal EcsProcessRaw ( Array systems )
{
_systems = systems ;
}
public IEnumerator GetEnumerator ( )
{
return _systems . GetEnumerator ( ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal T [ ] GetSystems_Internal < T > ( )
{
return ( T [ ] ) _systems ;
}
}
public readonly struct EcsProcess < TProcess > : IReadOnlyCollection < TProcess >
2024-02-22 22:16:03 +08:00
where TProcess : IEcsProcess
2024-02-22 15:39:37 +08:00
{
public readonly static EcsProcess < TProcess > Empty = new EcsProcess < TProcess > ( Array . Empty < TProcess > ( ) ) ;
private readonly TProcess [ ] _systems ;
public bool IsNullOrEmpty
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _systems = = null | | _systems . Length < = 0 ; }
}
public int Length
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _systems . Length ; }
}
int IReadOnlyCollection < TProcess > . Count
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _systems . Length ; }
}
public TProcess this [ int index ]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _systems [ index ] ; }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal EcsProcess ( TProcess [ ] systems )
{
_systems = systems ;
}
public static explicit operator EcsProcess < TProcess > ( EcsProcessRaw raw )
{
return new EcsProcess < TProcess > ( raw . GetSystems_Internal < TProcess > ( ) ) ;
}
public static implicit operator EcsProcessRaw ( EcsProcess < TProcess > process )
{
return new EcsProcessRaw ( process . _systems ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator ( ) { return new Enumerator ( _systems ) ; }
IEnumerator < TProcess > IEnumerable < TProcess > . GetEnumerator ( ) { return GetEnumerator ( ) ; }
IEnumerator IEnumerable . GetEnumerator ( ) { return GetEnumerator ( ) ; }
public struct Enumerator : IEnumerator < TProcess >
{
private readonly TProcess [ ] _systems ;
private int _index ;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator ( TProcess [ ] systems )
{
_systems = systems ;
_index = - 1 ;
}
public TProcess Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _systems [ _index ] ; }
}
object IEnumerator . Current { get { return Current ; } }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext ( ) { return + + _index < _systems . Length ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Reset ( ) { _index = - 1 ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose ( ) { }
}
}
#endregion
2024-02-25 18:33:17 +08:00
}
namespace DCFApixels.DragonECS.Internal
{
internal sealed class PipelinePropertyInjectionNode : CustomInjectionNode < IEcsPipelineMember , EcsPipeline >
{
public sealed override void InjectTo ( IEcsPipelineMember system , EcsPipeline obj )
{
system . Pipeline = obj ;
}
}
2024-02-22 15:39:37 +08:00
}