2024-06-25 22:02:39 +08:00
using DCFApixels.DragonECS.Internal ;
using DCFApixels.DragonECS.RunnersCore ;
2024-06-24 22:06:02 +08:00
using System ;
using System.Collections ;
using System.Collections.Generic ;
using System.Linq ;
2024-08-12 21:36:21 +08:00
using System.Runtime.CompilerServices ;
using System.Runtime.InteropServices ;
2024-08-20 11:53:14 +08:00
using System.Runtime.Serialization ;
2024-07-08 20:31:42 +08:00
using static DCFApixels . DragonECS . EcsConsts ;
2024-06-24 22:06:02 +08:00
namespace DCFApixels.DragonECS
{
2024-08-12 21:36:21 +08:00
[MetaColor(MetaColor.DragonRose)]
[MetaGroup(PACK_GROUP, OTHER_GROUP)]
[MetaDescription(AUTHOR, "...")]
2024-08-20 11:53:14 +08:00
public interface IEcsDefaultAddParams
2024-08-12 21:36:21 +08:00
{
AddParams AddParams { get ; }
}
2024-06-24 22:06:02 +08:00
public sealed partial class EcsPipeline
{
public class Builder : IEcsModule
{
2024-09-02 17:29:19 +08:00
private SystemNode [ ] _systemNodes = new SystemNode [ 256 ] ;
private int _startIndex = - 1 ;
private int _endIndex = - 1 ;
private int _systemNodesCount = 0 ;
private int _freeIndex = - 1 ;
private int _freeNodesCount = 0 ;
2024-06-25 22:02:39 +08:00
2024-07-08 20:31:42 +08:00
private readonly Dictionary < string , LayerSystemsList > _layerLists = new Dictionary < string , LayerSystemsList > ( 8 ) ;
2024-06-24 22:06:02 +08:00
private readonly List < InitDeclaredRunner > _initDeclaredRunners = new List < InitDeclaredRunner > ( 4 ) ;
2024-06-25 22:02:39 +08:00
2024-06-24 22:06:02 +08:00
public readonly LayerList Layers ;
public readonly Injector . Builder Injector ;
public readonly Configurator Configs ;
2024-08-14 21:23:34 +08:00
private AddParams _defaultAddParams = new AddParams ( BASIC_LAYER , 0 , false ) ;
2024-07-08 20:31:42 +08:00
2024-09-08 19:39:43 +08:00
private HashSet < Type > _uniqueSystemsSet = new HashSet < Type > ( ) ;
2024-07-08 20:31:42 +08:00
#region Properties
2024-09-05 17:27:09 +08:00
//private ReadOnlySpan<SystemNode> SystemRecords
//{
// get { return new ReadOnlySpan<SystemNode>(_systemNodes, 0, _systemNodesCount); }
//}
2024-07-08 20:31:42 +08:00
#endregion
2024-06-24 22:06:02 +08:00
#region Constructors
public Builder ( IConfigContainerWriter config = null )
{
if ( config = = null ) { config = new ConfigContainer ( ) ; }
Configs = new Configurator ( config , this ) ;
Injector = new Injector . Builder ( this ) ;
Injector . AddNode < object > ( ) ;
Injector . AddNode < EcsWorld > ( ) ;
Injector . AddNode < EcsAspect > ( ) ;
Injector . AddNode < EcsPipeline > ( ) ;
2024-07-08 20:31:42 +08:00
Layers = new LayerList ( this , PRE_BEGIN_LAYER , BEGIN_LAYER , BASIC_LAYER , END_LAYER , POST_END_LAYER ) ;
2024-06-24 22:06:02 +08:00
}
#endregion
2024-08-14 20:39:55 +08:00
#region Add IEcsProcess
public Builder Add ( IEcsProcess system , AddParams parameters )
{
return AddSystem_Internal ( system , parameters ) ;
}
2024-09-05 17:27:09 +08:00
private IEcsProcess _systemModule ;
private bool _systemModuleAdded ;
2024-08-14 20:39:55 +08:00
private Builder AddSystem_Internal ( IEcsProcess system , AddParams settedAddParams )
{
AddParams prms = _defaultAddParams ;
2024-08-20 11:53:14 +08:00
if ( system is IEcsDefaultAddParams overrideInterface )
2024-06-24 22:06:02 +08:00
{
2024-08-14 20:39:55 +08:00
prms = prms . Overwrite ( overrideInterface . AddParams ) ;
2024-06-24 22:06:02 +08:00
}
2024-08-14 20:39:55 +08:00
prms = prms . Overwrite ( settedAddParams ) ;
2024-06-24 22:06:02 +08:00
2024-09-05 17:27:09 +08:00
// Если система одновременно явялется и системой и модулем то сначала будет вызван IEcsModule
// При этом дается возможность ручной установки порядка импорта системы вызовом Add(this)
2024-10-10 19:57:19 +08:00
if ( _systemModule = = system )
2024-10-09 01:55:30 +08:00
{
_systemModuleAdded = true ;
}
else
{
if ( system is IEcsModule module )
{
IEcsProcess systemModulePrev = _systemModule ;
bool systemModuleAddedPrev = _systemModuleAdded ;
_systemModule = system ;
_systemModuleAdded = false ;
int importHeadIndex = _endIndex ;
AddModule_Internal ( module , prms ) ;
if ( _systemModuleAdded = = false )
{ //Если система не была добавлена вручную, то она будет добавлена перед тем что было импортировано через IEcsModule
InsertAfterNode_Internal ( importHeadIndex , system , prms . layerName , prms . sortOrder , prms . isUnique ) ;
}
2024-08-14 20:39:55 +08:00
2024-10-09 01:55:30 +08:00
_systemModule = systemModulePrev ;
_systemModuleAdded = systemModuleAddedPrev ;
return this ;
}
2024-06-24 22:06:02 +08:00
}
2024-09-02 17:29:19 +08:00
AddNode_Internal ( system , prms . layerName , prms . sortOrder , prms . isUnique ) ;
2024-06-24 22:06:02 +08:00
return this ;
}
2024-09-02 17:29:19 +08:00
private void AddNode_Internal ( IEcsProcess system , string layer , int sortOrder , bool isUnique )
2024-06-25 22:02:39 +08:00
{
2024-09-05 17:27:09 +08:00
InsertAfterNode_Internal ( _endIndex , system , layer , sortOrder , isUnique ) ;
}
private void InsertAfterNode_Internal ( int insertAfterIndex , IEcsProcess system , string layer , int sortOrder , bool isUnique )
{
2024-09-08 19:39:43 +08:00
//TODO нужно потестить
if ( isUnique & & _uniqueSystemsSet . Add ( system . GetType ( ) ) = = false )
{
2024-10-06 15:35:01 +08:00
//EcsDebug.PrintWarning($"The pipeline already contains a unique instance of {system.GetType().Name}");
return ;
}
if ( string . IsNullOrEmpty ( layer ) )
{
layer = BASIC_LAYER ;
2024-09-08 19:39:43 +08:00
}
2024-09-02 17:29:19 +08:00
SystemNode record = new SystemNode ( system , layer , sortOrder , isUnique ) ;
int newIndex ;
if ( _freeNodesCount < = 0 )
{
if ( _systemNodes . Length < = _systemNodesCount )
{
2024-09-05 17:27:09 +08:00
Array . Resize ( ref _systemNodes , _systemNodes . Length < < 1 ) ;
2024-09-02 17:29:19 +08:00
}
newIndex = _systemNodesCount ;
_systemNodes [ newIndex ] = record ;
}
else
{
_freeNodesCount - - ;
newIndex = _freeIndex ;
_freeIndex = _systemNodes [ _freeIndex ] . next ;
}
_systemNodesCount + + ;
2024-09-05 17:27:09 +08:00
_systemNodes [ newIndex ] = record ;
2024-09-02 17:29:19 +08:00
if ( _systemNodesCount = = 1 )
{
_startIndex = newIndex ;
}
else
{
2024-09-05 17:27:09 +08:00
_systemNodes [ newIndex ] . next = _systemNodes [ insertAfterIndex ] . next ;
_systemNodes [ insertAfterIndex ] . next = newIndex ;
}
if ( insertAfterIndex = = _endIndex )
{
_endIndex = newIndex ;
2024-09-02 17:29:19 +08:00
}
2024-06-25 23:35:51 +08:00
if ( _layerLists . TryGetValue ( layer , out LayerSystemsList list ) = = false )
2024-06-25 22:02:39 +08:00
{
list = new LayerSystemsList ( layer ) ;
_layerLists . Add ( layer , list ) ;
}
list . lasyInitSystemsCount + + ;
}
2024-06-24 22:06:02 +08:00
#endregion
2024-08-14 20:39:55 +08:00
#region AddModule IEcsModule
public Builder AddModule ( IEcsModule module , AddParams parameters )
{
return AddModule_Internal ( module , parameters ) ;
}
private Builder AddModule_Internal ( IEcsModule module , AddParams settedAddParams )
{
2024-09-07 22:17:08 +08:00
if ( settedAddParams . flags . IsNoImport ( ) = = false )
2024-09-05 17:27:09 +08:00
{
2024-09-07 22:17:08 +08:00
AddParams prms = _defaultAddParams ;
if ( module is IEcsDefaultAddParams overrideInterface )
{
prms = prms . Overwrite ( overrideInterface . AddParams ) ;
}
var oldDefaultAddParams = _defaultAddParams ;
_defaultAddParams = prms . Overwrite ( settedAddParams ) ;
module . Import ( this ) ;
_defaultAddParams = oldDefaultAddParams ;
2024-07-08 20:31:42 +08:00
}
2024-09-08 19:39:43 +08:00
Injector . Inject ( module ) ;
2024-08-12 21:36:21 +08:00
return this ;
}
#endregion
2024-08-14 20:39:55 +08:00
#region Add Raw
public Builder Add ( object raw , AddParams parameters )
{
return AddRaw_Internal ( raw , parameters ) ;
}
private Builder AddRaw_Internal ( object raw , AddParams settedAddParams )
{
switch ( raw )
{
case IEcsProcess system : return AddSystem_Internal ( system , settedAddParams ) ;
case IEcsModule module : return AddModule_Internal ( module , settedAddParams ) ;
default : Throw . UndefinedException ( ) ; return this ;
}
2024-06-24 22:06:02 +08:00
}
2024-07-08 20:31:42 +08:00
#endregion
#region Add other
2024-06-24 22:06:02 +08:00
public Builder AddRunner < TRunner > ( ) where TRunner : EcsRunner , IEcsRunner , new ( )
{
_initDeclaredRunners . Add ( new InitDeclaredRunner < TRunner > ( ) ) ;
return this ;
}
void IEcsModule . Import ( Builder into )
{
into . MergeWith ( this ) ;
}
private void MergeWith ( Builder other )
{
Injector . Add ( other . Injector ) ;
foreach ( var declaredRunners in other . _initDeclaredRunners )
{
_initDeclaredRunners . Add ( declaredRunners ) ;
}
foreach ( var config in other . Configs . Instance . GetAllConfigs ( ) )
{
Configs . Instance . Set ( config . Key , config . Value ) ;
}
Layers . MergeWith ( other . Layers ) ;
2024-09-05 17:27:09 +08:00
foreach ( ref readonly SystemNode otherRecord in new LinkedListIterator < SystemNode > ( _systemNodes , _systemNodesCount , _startIndex ) )
2024-06-24 22:06:02 +08:00
{
2024-09-02 17:29:19 +08:00
AddNode_Internal ( otherRecord . system , otherRecord . layerName , otherRecord . sortOrder , otherRecord . isUnique ) ;
2024-06-24 22:06:02 +08:00
}
}
#endregion
#region Remove
2024-09-02 17:29:19 +08:00
private void RemoveAt ( int prevIndex , int removedNodeIndex )
2024-06-25 22:02:39 +08:00
{
2024-09-02 17:29:19 +08:00
ref var removedeNode = ref _systemNodes [ removedNodeIndex ] ;
_layerLists [ removedeNode . layerName ] . lasyInitSystemsCount - - ;
_systemNodes [ prevIndex ] . next = removedeNode . next ;
removedeNode = default ;
if ( _endIndex = = removedNodeIndex )
{
_endIndex = prevIndex ;
}
if ( _freeNodesCount > 0 )
{
removedeNode . next = _freeIndex ;
}
_freeIndex = removedNodeIndex ;
_freeNodesCount + + ;
_systemNodesCount - - ;
2024-06-25 22:02:39 +08:00
}
2024-06-24 22:06:02 +08:00
public Builder Remove < TSystem > ( )
{
2024-09-08 19:39:43 +08:00
_uniqueSystemsSet . Remove ( typeof ( TSystem ) ) ;
2024-09-02 17:29:19 +08:00
if ( _systemNodesCount < = 1 )
2024-06-24 22:06:02 +08:00
{
2024-09-02 17:29:19 +08:00
if ( _systemNodesCount = = 1 & & _systemNodes [ 0 ] . system is TSystem )
2024-06-25 22:02:39 +08:00
{
2024-09-02 17:29:19 +08:00
_systemNodesCount = 0 ;
2024-06-25 22:02:39 +08:00
}
2024-09-02 17:29:19 +08:00
return this ;
}
int enumIndex = _startIndex ;
for ( int i = 1 ; i < _systemNodesCount ; i + + )
{
int nextIndex = _systemNodes [ enumIndex ] . next ;
if ( _systemNodes [ nextIndex ] . system is TSystem )
{
RemoveAt ( enumIndex , nextIndex ) ;
nextIndex = _systemNodes [ enumIndex ] . next ;
}
enumIndex = nextIndex ;
2024-06-24 22:06:02 +08:00
}
return this ;
}
#endregion
#region Build
2024-06-25 22:02:39 +08:00
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ENABLE_DRAGONECS_ASSERT_CHEKS
private EcsProfilerMarker _buildBarker = new EcsProfilerMarker ( "EcsPipeline.Build" ) ;
#endif
2024-06-24 22:06:02 +08:00
public EcsPipeline Build ( )
{
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ENABLE_DRAGONECS_ASSERT_CHEKS
_buildBarker . Begin ( ) ;
#endif
2024-09-05 17:27:09 +08:00
var it = new LinkedListIterator < SystemNode > ( _systemNodes , _systemNodesCount , _startIndex ) ;
2024-06-25 22:02:39 +08:00
LayerSystemsList basicLayerList ;
if ( _layerLists . TryGetValue ( BASIC_LAYER , out basicLayerList ) = = false )
{
basicLayerList = new LayerSystemsList ( BASIC_LAYER ) ;
_layerLists . Add ( BASIC_LAYER , basicLayerList ) ;
}
2024-06-24 22:06:02 +08:00
int allSystemsLength = 0 ;
2024-06-25 22:02:39 +08:00
foreach ( var item in _layerLists )
2024-06-24 22:06:02 +08:00
{
2024-06-25 22:02:39 +08:00
if ( item . Key = = BASIC_LAYER ) { continue ; }
2024-09-05 17:27:09 +08:00
if ( Layers . Contains ( item . Key ) )
2024-06-24 22:06:02 +08:00
{
2024-09-05 17:27:09 +08:00
item . Value . Init ( ) ;
allSystemsLength + = item . Value . lasyInitSystemsCount + 1 ;
2024-06-24 22:06:02 +08:00
}
else
{
2024-09-05 17:27:09 +08:00
basicLayerList . lasyInitSystemsCount + = item . Value . lasyInitSystemsCount ;
2024-06-24 22:06:02 +08:00
}
}
2024-06-25 22:02:39 +08:00
allSystemsLength + = basicLayerList . lasyInitSystemsCount + 1 ;
basicLayerList . Init ( ) ;
2024-09-05 17:27:09 +08:00
foreach ( ref readonly SystemNode node in it )
2024-06-25 22:02:39 +08:00
{
2024-09-02 17:29:19 +08:00
var list = _layerLists [ node . layerName ] ;
2024-06-25 23:35:51 +08:00
if ( list . IsInit = = false )
2024-06-25 22:02:39 +08:00
{
list = basicLayerList ;
}
2024-09-08 19:39:43 +08:00
list . Add ( node . system , node . sortOrder , node . isUnique ) ;
//if (node.isUnique == false || uniqueSystemsSet.Add(node.system.GetType()))
//{
// list.Add(node.system, node.sortOrder, node.isUnique);
//}
2024-06-25 22:02:39 +08:00
}
2024-06-24 22:06:02 +08:00
IEcsProcess [ ] allSystems = new IEcsProcess [ allSystemsLength ] ;
{
int i = 0 ;
foreach ( var item in Layers )
{
2024-06-25 22:02:39 +08:00
if ( _layerLists . TryGetValue ( item , out var list ) & & list . IsInit )
2024-06-24 22:06:02 +08:00
{
2024-06-25 22:02:39 +08:00
list . Sort ( ) ;
2024-06-24 22:06:02 +08:00
for ( int j = 0 ; j < list . recordsCount ; j + + )
{
allSystems [ i + + ] = list . records [ j ] . system ;
}
}
}
}
EcsPipeline pipeline = new EcsPipeline ( Configs . Instance . GetContainer ( ) , Injector , allSystems ) ;
foreach ( var item in _initDeclaredRunners )
{
item . Declare ( pipeline ) ;
}
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ENABLE_DRAGONECS_ASSERT_CHEKS
_buildBarker . End ( ) ;
#endif
return pipeline ;
}
#endregion
#region InitDeclaredRunner
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 )
{
pipeline . GetRunnerInstance < T > ( ) ;
}
}
#endregion
#region Configurator
public class Configurator
{
private readonly IConfigContainerWriter _configs ;
private readonly Builder _builder ;
public Configurator ( IConfigContainerWriter configs , Builder builder )
{
_configs = configs ;
_builder = builder ;
}
public IConfigContainerWriter Instance
{
get { return _configs ; }
}
public Builder Set < T > ( T value )
{
_configs . Set ( value ) ;
return _builder ;
}
}
#endregion
#region LayerList
public class LayerList : IEnumerable < string >
{
2024-10-09 01:55:30 +08:00
// Автоматический слой нужный только для метода Add
// Идея в том что метод Add добавляет слои до EcsConsts.END_LAYER и EcsConsts.POST_END_LAYER
private const string ADD_LAYERS_LAYER = nameof ( LayerList ) + "." + nameof ( ADD_LAYERS_LAYER ) ;
2024-10-10 19:57:19 +08:00
2024-06-24 22:06:02 +08:00
private Builder _source ;
private List < string > _layers ;
private string _basicLayerName ;
2024-10-09 01:55:30 +08:00
#region Properties
2024-06-26 01:35:40 +08:00
public int Count { get { return _layers . Count ; } }
public object this [ int index ] { get { return _layers [ index ] ; } }
2024-10-09 01:55:30 +08:00
#endregion
2024-06-26 01:35:40 +08:00
2024-10-09 01:55:30 +08:00
#region Constructors
2024-06-24 22:06:02 +08:00
public LayerList ( Builder source , string basicLayerName )
{
_source = source ;
2024-10-09 01:55:30 +08:00
_layers = new List < string > ( 16 ) { basicLayerName , ADD_LAYERS_LAYER } ;
2024-06-24 22:06:02 +08:00
_basicLayerName = basicLayerName ;
}
2024-07-08 20:31:42 +08:00
public LayerList ( Builder source , string preBeginlayer , string beginlayer , string basicLayer , string endLayer , string postEndLayer )
{
_source = source ;
2024-10-09 01:55:30 +08:00
_layers = new List < string > ( 16 ) { preBeginlayer , beginlayer , basicLayer , ADD_LAYERS_LAYER , endLayer , postEndLayer } ;
2024-07-08 20:31:42 +08:00
_basicLayerName = basicLayer ;
}
2024-10-09 01:55:30 +08:00
#endregion
#region Edit
2024-06-24 22:06:02 +08:00
2024-10-09 01:55:30 +08:00
#region Single
public Builder Add ( string newLayer ) { return InsertAfter ( ADD_LAYERS_LAYER , newLayer ) ; }
2024-06-24 22:06:02 +08:00
public Builder Insert ( string targetLayer , string newLayer )
{
if ( Contains ( newLayer ) ) { return _source ; }
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 )
{
if ( Contains ( newLayer ) ) { return _source ; }
if ( targetLayer = = _basicLayerName ) // нужно чтобы метод Add работал правильно. _basicLayerName и ADD_LAYER считается одним слоем, поэтому Before = _basicLayerName After = ADD_LAYER
{
2024-10-09 01:55:30 +08:00
targetLayer = ADD_LAYERS_LAYER ;
2024-06-24 22:06:02 +08:00
}
int index = _layers . IndexOf ( targetLayer ) ;
if ( index < 0 )
{
throw new KeyNotFoundException ( $"Layer {targetLayer} not found" ) ;
}
2024-10-09 01:55:30 +08:00
_layers . Insert ( + + index , newLayer ) ;
2024-06-24 22:06:02 +08:00
return _source ;
}
public Builder Move ( string targetLayer , string movingLayer )
{
_layers . Remove ( movingLayer ) ;
return Insert ( targetLayer , movingLayer ) ;
}
public Builder MoveAfter ( string targetLayer , string movingLayer )
{
if ( targetLayer = = _basicLayerName ) // нужно чтобы метод Add работал правильно. _basicLayerName и ADD_LAYER считается одним слоем, поэтому Before = _basicLayerName After = ADD_LAYER
{
2024-10-09 01:55:30 +08:00
targetLayer = ADD_LAYERS_LAYER ;
2024-06-24 22:06:02 +08:00
}
_layers . Remove ( movingLayer ) ;
return InsertAfter ( targetLayer , movingLayer ) ;
}
2024-10-09 01:55:30 +08:00
#endregion
2024-06-24 22:06:02 +08:00
2024-10-09 01:55:30 +08:00
#region Range
public Builder Add ( params string [ ] newLayers ) { return InsertAfter ( ADD_LAYERS_LAYER , newLayers ) ; }
2024-06-24 22:06:02 +08:00
public Builder Insert ( string targetLayer , params string [ ] newLayers )
{
int index = _layers . IndexOf ( targetLayer ) ;
if ( index < 0 )
{
throw new KeyNotFoundException ( $"Layer {targetLayer} not found" ) ;
}
_layers . InsertRange ( index , newLayers . Where ( o = > ! Contains ( o ) ) ) ;
return _source ;
}
public Builder InsertAfter ( string targetLayer , params string [ ] newLayers )
{
if ( targetLayer = = _basicLayerName ) // нужно чтобы метод Add работал правильно. _basicLayerName и ADD_LAYER считается одним слоем, поэтому Before = _basicLayerName After = ADD_LAYER
{
2024-10-09 01:55:30 +08:00
targetLayer = ADD_LAYERS_LAYER ;
2024-06-24 22:06:02 +08:00
}
2024-10-09 01:55:30 +08:00
int index = _layers . IndexOf ( targetLayer ) ;
if ( index < 0 )
2024-06-24 22:06:02 +08:00
{
2024-10-09 01:55:30 +08:00
throw new KeyNotFoundException ( $"Layer {targetLayer} not found" ) ;
2024-06-24 22:06:02 +08:00
}
2024-10-09 01:55:30 +08:00
_layers . InsertRange ( + + index , newLayers . Where ( o = > ! Contains ( o ) ) ) ;
2024-06-24 22:06: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
{
2024-10-09 01:55:30 +08:00
targetLayer = ADD_LAYERS_LAYER ;
2024-06-24 22:06:02 +08:00
}
foreach ( var movingLayer in movingLayers )
{
_layers . Remove ( movingLayer ) ;
}
return InsertAfter ( targetLayer , movingLayers ) ;
}
2024-10-09 01:55:30 +08:00
#endregion
#endregion
2024-09-08 19:39:43 +08:00
2024-10-09 01:55:30 +08:00
#region MergeWith
2024-09-08 19:39:43 +08:00
private static bool AreMatchingOrderIdentical ( IReadOnlyList < string > listA , IReadOnlyList < string > listB )
{
int indexA = 0 ;
foreach ( string itemB in listB )
{
if ( indexA < listA . Count & & listA [ indexA ] = = itemB )
{
indexA + + ;
}
}
return indexA = = listA . Count ;
}
2024-06-26 00:07:31 +08:00
public void MergeWith ( IReadOnlyList < string > other )
2024-06-24 22:06:02 +08:00
{
List < string > listA = _layers ;
2024-06-26 00:07:31 +08:00
IReadOnlyList < string > listB = other ;
2024-06-24 22:06:02 +08:00
2024-09-08 19:39:43 +08:00
if ( AreMatchingOrderIdentical ( listA , listB ) = = false )
{
Throw . Exception ( "Для слияния списков слоев, нужно чтобы названия слоев, присутствующие в обоих списках, появлялись в одном и том же порядке в обоих списках" ) ;
}
HashSet < string > seen = new HashSet < string > ( ) ;
List < string > result = new List < string > ( ) ;
2024-06-24 22:06:02 +08:00
foreach ( string item in listA )
{
seen . Add ( item ) ;
}
foreach ( string item in listB )
{
if ( seen . Add ( item ) = = false )
{
seen . Remove ( item ) ;
}
}
int i = 0 , j = 0 ;
while ( i < listA . Count | | j < listB . Count )
{
while ( i < listA . Count & & seen . Contains ( listA [ i ] ) )
{
result . Add ( listA [ i ] ) ;
i + + ;
}
while ( j < listB . Count & & seen . Contains ( listB [ j ] ) )
{
result . Add ( listB [ j ] ) ;
j + + ;
}
if ( i < listA . Count ) { i + + ; }
if ( j < listB . Count )
{
result . Add ( listB [ j ] ) ;
j + + ;
}
}
_layers = result ;
}
2024-06-26 00:07:31 +08:00
public void MergeWith ( LayerList other )
{
MergeWith ( other . _layers ) ;
}
2024-10-09 01:55:30 +08:00
#endregion
2024-06-24 22:06:02 +08:00
2024-10-09 01:55:30 +08:00
#region Other
2024-06-24 22:06:02 +08:00
public bool Contains ( string layer ) { return _layers . Contains ( layer ) ; }
public List < string > . Enumerator GetEnumerator ( ) { return _layers . GetEnumerator ( ) ; }
IEnumerator < string > IEnumerable < string > . GetEnumerator ( ) { return _layers . GetEnumerator ( ) ; }
IEnumerator IEnumerable . GetEnumerator ( ) { return _layers . GetEnumerator ( ) ; }
2024-10-09 01:55:30 +08:00
#endregion
2024-06-24 22:06:02 +08:00
}
#endregion
#region SystemsList
2024-06-25 22:02:39 +08:00
private class LayerSystemsList
2024-06-24 22:06:02 +08:00
{
2024-06-25 22:02:39 +08:00
public int lasyInitSystemsCount = 0 ;
public Item [ ] records = null ;
2024-06-24 22:06:02 +08:00
public int recordsCount = 0 ;
2024-06-25 20:24:11 +08:00
2024-08-07 10:40:31 +08:00
//отслеживание осортированности систем
2024-06-26 01:35:40 +08:00
private int _lastSortOrder ;
private int _lastAddOrder ;
2024-06-25 22:02:39 +08:00
private bool _isSorted = true ;
private string _layerName ;
public bool IsInit { get { return records ! = null ; } }
public bool IsSorted { get { return _isSorted ; } }
public ReadOnlySpan < Item > Records { get { return new ReadOnlySpan < Item > ( records , 1 , recordsCount - 1 ) ; } }
public LayerSystemsList ( string layerName ) { _layerName = layerName ; }
public void Init ( )
2024-06-24 22:06:02 +08:00
{
2024-06-25 22:02:39 +08:00
if ( IsInit ) { Throw . UndefinedException ( ) ; }
records = new Item [ lasyInitSystemsCount + 1 ] ;
2024-09-02 17:29:19 +08:00
Add ( new SystemsLayerMarkerSystem ( _layerName ) , int . MinValue , false ) ;
2024-06-24 22:06:02 +08:00
}
2024-06-25 22:02:39 +08:00
public void AddList ( LayerSystemsList other )
2024-06-24 22:06:02 +08:00
{
for ( int i = 1 ; i < other . recordsCount ; i + + )
{
var otherRecord = other . records [ i ] ;
2024-08-07 10:40:31 +08:00
AddItem_Internal ( otherRecord ) ;
2024-06-24 22:06:02 +08:00
}
}
2024-09-02 17:29:19 +08:00
public void Add ( IEcsProcess system , int sortOrder , bool isUnique )
2024-06-24 22:06:02 +08:00
{
2024-09-02 17:29:19 +08:00
AddItem_Internal ( new Item ( system , sortOrder , isUnique ) ) ;
2024-06-25 22:02:39 +08:00
}
2024-08-07 10:40:31 +08:00
private void AddItem_Internal ( Item item )
2024-06-25 22:02:39 +08:00
{
2024-06-26 01:35:40 +08:00
if ( _isSorted )
{
if ( recordsCount < = 1 )
{
_lastSortOrder = item . sortOrder ;
2024-08-14 20:39:55 +08:00
}
2024-09-02 17:29:19 +08:00
else if ( _lastSortOrder > item . sortOrder )
2024-06-26 01:35:40 +08:00
{
_isSorted = false ;
}
2024-08-07 10:40:31 +08:00
else
2024-06-26 01:35:40 +08:00
{
2024-08-07 10:40:31 +08:00
_lastSortOrder = item . sortOrder ;
2024-06-26 01:35:40 +08:00
}
}
2024-06-24 22:06:02 +08:00
if ( records . Length < = recordsCount )
{
Array . Resize ( ref records , recordsCount < < 1 ) ;
}
2024-06-25 22:02:39 +08:00
records [ recordsCount + + ] = item ;
2024-06-24 22:06:02 +08:00
}
public void RemoveAll < T > ( )
{
2024-06-25 22:02:39 +08:00
for ( int i = 0 ; i < recordsCount ; i + + )
2024-06-24 22:06:02 +08:00
{
2024-06-25 22:02:39 +08:00
if ( records [ i ] . system is T )
2024-06-24 22:06:02 +08:00
{
2024-06-25 22:02:39 +08:00
records [ i ] = records [ - - recordsCount ] ;
2024-06-24 22:06:02 +08:00
}
}
2024-06-25 22:02:39 +08:00
_isSorted = false ;
2024-06-24 22:06:02 +08:00
}
public void Sort ( )
{
2024-06-25 22:02:39 +08:00
if ( _isSorted ) { return ; }
2024-06-24 22:06:02 +08:00
//Игнорирую первую систему, так как это чисто система с названием слоя
Array . Sort ( records , 1 , recordsCount - 1 ) ;
2024-06-25 22:02:39 +08:00
_isSorted = true ;
2024-08-07 10:40:31 +08:00
_lastSortOrder = records [ recordsCount - 1 ] . sortOrder ;
2024-06-24 22:06:02 +08:00
}
}
2024-06-25 22:02:39 +08:00
private readonly struct Item : IComparable < Item >
2024-06-24 22:06:02 +08:00
{
public readonly IEcsProcess system ;
2024-06-25 20:24:11 +08:00
public readonly int sortOrder ;
2024-06-25 15:31:25 +08:00
public readonly bool isUnique ;
2024-09-02 17:29:19 +08:00
public Item ( IEcsProcess system , int sortOrder , bool isUnique )
2024-06-24 22:06:02 +08:00
{
this . system = system ;
2024-06-25 20:24:11 +08:00
this . sortOrder = sortOrder ;
2024-06-25 15:31:25 +08:00
this . isUnique = isUnique ;
2024-06-24 22:06:02 +08:00
}
2024-06-25 22:02:39 +08:00
public int CompareTo ( Item other )
2024-06-25 20:24:11 +08:00
{
2024-09-02 17:29:19 +08:00
return sortOrder - other . sortOrder ;
2024-06-25 20:24:11 +08:00
}
2024-06-24 22:06:02 +08:00
}
#endregion
2024-06-25 22:02:39 +08:00
2024-06-26 01:35:40 +08:00
#region SerializableTemplate
public EcsPipelineTemplate GenerateSerializableTemplate ( )
{
2024-09-05 17:27:09 +08:00
var it = new LinkedListIterator < SystemNode > ( _systemNodes , _systemNodesCount , _startIndex ) ;
2024-06-26 01:35:40 +08:00
EcsPipelineTemplate result = new EcsPipelineTemplate ( ) ;
result . layers = new string [ Layers . Count ] ;
2024-09-16 12:25:14 +08:00
result . records = new EcsPipelineTemplate . Record [ it . Count ] ;
2024-09-05 17:27:09 +08:00
int i = 0 ;
foreach ( ref readonly SystemNode node in it )
2024-06-26 01:35:40 +08:00
{
2024-09-14 18:34:13 +08:00
var prms = new AddParams ( node . layerName , node . sortOrder , node . isUnique , AddParamsFlags . None . SetOverwriteAll ( true ) . SetNoImport ( true ) ) ;
2024-09-16 12:25:14 +08:00
result . records [ i + + ] = new EcsPipelineTemplate . Record ( node . system , prms ) ;
2024-06-26 01:35:40 +08:00
}
return result ;
}
#endregion
2024-08-20 11:53:14 +08:00
#region SystemRecord
2024-08-14 20:39:55 +08:00
[StructLayout(LayoutKind.Auto)]
2024-09-05 17:27:09 +08:00
private struct SystemNode : ILinkedNext
2024-06-25 22:02:39 +08:00
{
public readonly IEcsProcess system ;
2024-08-14 21:23:34 +08:00
public readonly string layerName ;
2024-06-25 22:02:39 +08:00
public readonly int sortOrder ;
public readonly bool isUnique ;
2024-09-02 17:29:19 +08:00
public int next ;
2024-09-05 17:27:09 +08:00
public int Next
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return next ; }
}
2024-09-02 17:29:19 +08:00
public SystemNode ( IEcsProcess system , string layerName , int sortOrder , bool isUnique , int next = - 1 )
2024-06-25 22:02:39 +08:00
{
this . system = system ;
2024-08-14 21:23:34 +08:00
this . layerName = layerName ;
2024-06-25 22:02:39 +08:00
this . sortOrder = sortOrder ;
this . isUnique = isUnique ;
2024-09-02 17:29:19 +08:00
this . next = next ;
2024-06-26 01:35:40 +08:00
}
2024-09-05 17:27:09 +08:00
public override string ToString ( )
{
return this . AutoToString ( ) ;
}
2024-06-25 22:02:39 +08:00
}
2024-08-20 11:53:14 +08:00
#endregion
2024-06-24 22:06:02 +08:00
}
}
2024-08-14 22:40:58 +08:00
public static partial class EcsPipelineBuilderExtensions
{
#region Add IEcsProcess
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , IEcsProcess system )
{
return self . Add ( system , AddParams . Default ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , IEcsProcess system , string layerName )
{
return self . Add ( system , new AddParams ( layerName : layerName ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , IEcsProcess system , int sortOrder )
{
return self . Add ( system , new AddParams ( sortOrder : sortOrder ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , IEcsProcess system , bool isUnique )
{
return self . Add ( system , new AddParams ( isUnique : isUnique ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , IEcsProcess system , string layerName , int sortOrder )
{
return self . Add ( system , new AddParams ( layerName : layerName , sortOrder : sortOrder ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , IEcsProcess system , string layerName , bool isUnique )
{
return self . Add ( system , new AddParams ( layerName : layerName , isUnique : isUnique ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , IEcsProcess system , int sortOrder , bool isUnique )
{
return self . Add ( system , new AddParams ( sortOrder : sortOrder , isUnique : isUnique ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , IEcsProcess system , string layerName , int sortOrder , bool isUnique )
{
return self . Add ( system , new AddParams ( layerName : layerName , sortOrder : sortOrder , isUnique : isUnique ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-06 15:35:01 +08:00
public static EcsPipeline . Builder AddUnique ( this EcsPipeline . Builder self , IEcsProcess system )
{
return self . Add ( system , new AddParams ( isUnique : true ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-08-14 22:40:58 +08:00
public static EcsPipeline . Builder AddUnique ( this EcsPipeline . Builder self , IEcsProcess system , string layerName )
{
return self . Add ( system , new AddParams ( layerName : layerName , isUnique : true ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddUnique ( this EcsPipeline . Builder self , IEcsProcess system , int sortOrder )
{
return self . Add ( system , new AddParams ( sortOrder : sortOrder , isUnique : true ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddUnique ( this EcsPipeline . Builder self , IEcsProcess system , string layerName , int sortOrder )
{
return self . Add ( system , new AddParams ( layerName : layerName , sortOrder : sortOrder , isUnique : true ) ) ;
}
#endregion
#region AddModule IEcsModule
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddModule ( this EcsPipeline . Builder self , IEcsModule module )
{
return self . AddModule ( module , AddParams . Default ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddModule ( this EcsPipeline . Builder self , IEcsModule module , string layerName )
{
return self . AddModule ( module , new AddParams ( layerName : layerName ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddModule ( this EcsPipeline . Builder self , IEcsModule module , int sortOrder )
{
return self . AddModule ( module , new AddParams ( sortOrder : sortOrder ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddModule ( this EcsPipeline . Builder self , IEcsModule module , bool isUnique )
{
return self . AddModule ( module , new AddParams ( isUnique : isUnique ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddModule ( this EcsPipeline . Builder self , IEcsModule module , string layerName , int sortOrder )
{
return self . AddModule ( module , new AddParams ( layerName : layerName , sortOrder : sortOrder ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddModule ( this EcsPipeline . Builder self , IEcsModule module , string layerName , bool isUnique )
{
return self . AddModule ( module , new AddParams ( layerName : layerName , isUnique : isUnique ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddModule ( this EcsPipeline . Builder self , IEcsModule module , int sortOrder , bool isUnique )
{
return self . AddModule ( module , new AddParams ( sortOrder : sortOrder , isUnique : isUnique ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddModule ( this EcsPipeline . Builder self , IEcsModule module , string layerName , int sortOrder , bool isUnique )
{
return self . AddModule ( module , new AddParams ( layerName : layerName , sortOrder : sortOrder , isUnique : isUnique ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-06 15:35:01 +08:00
public static EcsPipeline . Builder AddModuleUnique ( this EcsPipeline . Builder self , IEcsModule module )
{
return self . AddModule ( module , new AddParams ( isUnique : true ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-08-14 22:40:58 +08:00
public static EcsPipeline . Builder AddModuleUnique ( this EcsPipeline . Builder self , IEcsModule module , string layerName )
{
return self . AddModule ( module , new AddParams ( layerName : layerName , isUnique : true ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddModuleUnique ( this EcsPipeline . Builder self , IEcsModule module , int sortOrder )
{
return self . AddModule ( module , new AddParams ( sortOrder : sortOrder , isUnique : true ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddModuleUnique ( this EcsPipeline . Builder self , IEcsModule module , string layerName , int sortOrder )
{
return self . AddModule ( module , new AddParams ( layerName : layerName , sortOrder : sortOrder , isUnique : true ) ) ;
}
#endregion
#region Add Raw
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , object raw )
{
return self . Add ( raw , AddParams . Default ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , object raw , string layerName )
{
return self . Add ( raw , new AddParams ( layerName : layerName ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , object raw , int sortOrder )
{
return self . Add ( raw , new AddParams ( sortOrder : sortOrder ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , object raw , bool isUnique )
{
return self . Add ( raw , new AddParams ( isUnique : isUnique ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , object raw , string layerName , int sortOrder )
{
return self . Add ( raw , new AddParams ( layerName : layerName , sortOrder : sortOrder ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , object raw , string layerName , bool isUnique )
{
return self . Add ( raw , new AddParams ( layerName : layerName , isUnique : isUnique ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , object raw , int sortOrder , bool isUnique )
{
return self . Add ( raw , new AddParams ( sortOrder : sortOrder , isUnique : isUnique ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder Add ( this EcsPipeline . Builder self , object raw , string layerName , int sortOrder , bool isUnique )
{
return self . Add ( raw , new AddParams ( layerName : layerName , sortOrder : sortOrder , isUnique : isUnique ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-06 15:35:01 +08:00
public static EcsPipeline . Builder AddUnique ( this EcsPipeline . Builder self , object raw )
{
return self . Add ( raw , new AddParams ( isUnique : true ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-08-14 22:40:58 +08:00
public static EcsPipeline . Builder AddUnique ( this EcsPipeline . Builder self , object raw , string layerName )
{
return self . Add ( raw , new AddParams ( layerName : layerName , isUnique : true ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddUnique ( this EcsPipeline . Builder self , object raw , int sortOrder )
{
return self . Add ( raw , new AddParams ( sortOrder : sortOrder , isUnique : true ) ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPipeline . Builder AddUnique ( this EcsPipeline . Builder self , object raw , string layerName , int sortOrder )
{
return self . Add ( raw , new AddParams ( layerName : layerName , sortOrder : sortOrder , isUnique : true ) ) ;
}
#endregion
}
2024-09-05 17:27:09 +08:00
#region AddParams
[Serializable]
[DataContract]
public struct AddParams : IEquatable < AddParams >
{
public static readonly AddParams Default = new AddParams ( ) ;
[DataMember] public string layerName ;
[DataMember] public int sortOrder ;
[DataMember] public bool isUnique ;
[DataMember] public AddParamsFlags flags ;
#region Properties
public bool IsOverwriteLayerName
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return flags . IsOverwriteLayerName ( ) ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set { flags = value ? flags | AddParamsFlags . OverwriteLayerName : flags & ~ AddParamsFlags . OverwriteLayerName ; }
}
public bool IsOverwriteSortOrder
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return flags . IsOverwriteSortOrder ( ) ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set { flags = value ? flags | AddParamsFlags . OverwriteSortOrder : flags & ~ AddParamsFlags . OverwriteSortOrder ; }
}
public bool IsOverwriteIsUnique
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return flags . IsOverwriteIsUnique ( ) ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set { flags = value ? flags | AddParamsFlags . OverwriteIsUnique : flags & ~ AddParamsFlags . OverwriteIsUnique ; }
}
#endregion
#region Constructors
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AddParams ( string layerName )
{
this . layerName = layerName ;
this . sortOrder = default ;
this . isUnique = default ;
flags = AddParamsFlags . OverwriteLayerName ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AddParams ( int sortOrder )
{
this . layerName = default ;
this . sortOrder = sortOrder ;
this . isUnique = default ;
flags = AddParamsFlags . OverwriteSortOrder ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AddParams ( bool isUnique )
{
this . layerName = default ;
this . sortOrder = default ;
this . isUnique = isUnique ;
flags = AddParamsFlags . OverwriteIsUnique ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AddParams ( string layerName , int sortOrder )
{
this . layerName = layerName ;
this . sortOrder = sortOrder ;
this . isUnique = default ;
flags = AddParamsFlags . OverwriteLayerName | AddParamsFlags . OverwriteSortOrder ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AddParams ( string layerName , bool isUnique )
{
this . layerName = layerName ;
this . sortOrder = default ;
this . isUnique = isUnique ;
flags = AddParamsFlags . OverwriteLayerName | AddParamsFlags . OverwriteIsUnique ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AddParams ( int sortOrder , bool isUnique )
{
this . layerName = default ;
this . sortOrder = sortOrder ;
this . isUnique = isUnique ;
flags = AddParamsFlags . OverwriteSortOrder | AddParamsFlags . OverwriteIsUnique ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AddParams ( string layerName , int sortOrder , bool isUnique )
{
this . layerName = layerName ;
this . sortOrder = sortOrder ;
this . isUnique = isUnique ;
2024-09-14 18:34:13 +08:00
flags = AddParamsFlags . None . SetOverwriteAll ( true ) ;
2024-09-05 17:27:09 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AddParams ( string layerName , int sortOrder , bool isUnique , AddParamsFlags overrideFlags )
{
this . layerName = layerName ;
this . sortOrder = sortOrder ;
this . isUnique = isUnique ;
this . flags = overrideFlags ;
}
#endregion
#region Overwrite
public AddParams Overwrite ( AddParams other )
{
AddParams result = this ;
if ( other . flags . IsOverwriteLayerName ( ) )
{
result . layerName = other . layerName ;
}
if ( other . flags . IsOverwriteSortOrder ( ) )
{
result . sortOrder = other . sortOrder ;
}
if ( other . flags . IsOverwriteIsUnique ( ) )
{
result . isUnique = other . isUnique ;
}
result . flags | = other . flags ;
return result ;
}
#endregion
#region Other
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals ( AddParams other )
{
return sortOrder = = other . sortOrder & &
layerName = = other . layerName & &
isUnique = = other . isUnique ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals ( object obj )
{
return obj is AddParams & & Equals ( ( AddParams ) obj ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode ( )
{
return HashCode . Combine ( sortOrder , layerName , isUnique ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override string ToString ( )
{
return ( flags . IsOverwriteLayerName ( ) ? $"{layerName}, " : "" ) +
( flags . IsOverwriteSortOrder ( ) ? $"{sortOrder}, " : "" ) +
( flags . IsOverwriteIsUnique ( ) ? $"{isUnique}, " : "" ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator AddParams ( string a ) { return new AddParams ( a ) ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator AddParams ( int a ) { return new AddParams ( a ) ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator AddParams ( bool a ) { return new AddParams ( a ) ; }
#endregion
}
[Flags]
public enum AddParamsFlags : byte
{
None = 0 ,
OverwriteLayerName = 1 < < 0 ,
OverwriteSortOrder = 1 < < 1 ,
OverwriteIsUnique = 1 < < 2 ,
/// <summary>
/// Ignore call IEcsModule.Import(Builder b)
/// </summary>
NoImport = 1 < < 7 ,
}
public static class AddParamsFlagsUtility
{
2024-09-14 18:34:13 +08:00
private const AddParamsFlags OverwriteAll = AddParamsFlags . OverwriteLayerName | AddParamsFlags . OverwriteSortOrder | AddParamsFlags . OverwriteIsUnique ;
private const AddParamsFlags All = OverwriteAll | AddParamsFlags . NoImport ;
2024-09-05 17:27:09 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-09-14 18:34:13 +08:00
public static AddParamsFlags Normalize ( this AddParamsFlags flags ) { return flags & All ; }
2024-09-11 10:36:44 +08:00
2024-09-14 18:34:13 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsOverwriteLayerName ( this AddParamsFlags flags ) { return ( flags & AddParamsFlags . OverwriteLayerName ) = = AddParamsFlags . OverwriteLayerName ; }
2024-09-05 17:27:09 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsOverwriteSortOrder ( this AddParamsFlags flags ) { return ( flags & AddParamsFlags . OverwriteSortOrder ) = = AddParamsFlags . OverwriteSortOrder ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsOverwriteIsUnique ( this AddParamsFlags flags ) { return ( flags & AddParamsFlags . OverwriteIsUnique ) = = AddParamsFlags . OverwriteIsUnique ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-09-14 18:34:13 +08:00
public static bool IsOverwriteAll ( this AddParamsFlags flags ) { return ( flags & OverwriteAll ) = = OverwriteAll ; }
2024-09-05 17:27:09 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsNoImport ( this AddParamsFlags flags ) { return ( flags & AddParamsFlags . NoImport ) = = AddParamsFlags . NoImport ; }
2024-09-11 10:36:44 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static AddParamsFlags SetOverwriteLayerName ( this AddParamsFlags flags , bool flag ) { return flag ? flags | AddParamsFlags . OverwriteLayerName : flags & ~ AddParamsFlags . OverwriteLayerName ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static AddParamsFlags SetOverwriteSortOrder ( this AddParamsFlags flags , bool flag ) { return flag ? flags | AddParamsFlags . OverwriteSortOrder : flags & ~ AddParamsFlags . OverwriteSortOrder ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static AddParamsFlags SetOverwriteIsUnique ( this AddParamsFlags flags , bool flag ) { return flag ? flags | AddParamsFlags . OverwriteIsUnique : flags & ~ AddParamsFlags . OverwriteIsUnique ; }
2024-09-14 18:34:13 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static AddParamsFlags SetOverwriteAll ( this AddParamsFlags flags , bool flag ) { return flag ? flags | OverwriteAll : flags & ~ OverwriteAll ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static AddParamsFlags SetNoImport ( this AddParamsFlags flags , bool flag ) { return flag ? flags | AddParamsFlags . NoImport : flags & ~ AddParamsFlags . NoImport ; }
2024-09-05 17:27:09 +08:00
}
#endregion
2024-06-24 22:06:02 +08:00
}