Browse Source

Update Svelto.ECS to version 3.1

pull/57/head
sebas77 3 years ago
parent
commit
56cb8b2236
100 changed files with 1379 additions and 546 deletions
  1. +1
    -1
      Svelto.Common
  2. +21
    -0
      Svelto.ECS/CHANGELOG.md
  3. +0
    -0
      Svelto.ECS/Core/AllowMultipleAttribute.cs
  4. +1
    -2
      Svelto.ECS/Core/CheckEntityUtilities.cs
  5. +0
    -0
      Svelto.ECS/Core/ComponentBuilder.CheckFields.cs
  6. +0
    -0
      Svelto.ECS/Core/ComponentBuilder.cs
  7. +0
    -0
      Svelto.ECS/Core/DBC.cs
  8. +0
    -0
      Svelto.ECS/Core/ECSException.cs
  9. +1
    -1
      Svelto.ECS/Core/EGID.cs
  10. +0
    -1
      Svelto.ECS/Core/EGIDMapper.cs
  11. +25
    -0
      Svelto.ECS/Core/EnginesGroup/IStepEngine.cs
  12. +3
    -25
      Svelto.ECS/Core/EnginesGroup/SortedEnginesGroup.cs
  13. +28
    -0
      Svelto.ECS/Core/EnginesGroup/UnsortedEnginesGroup.cs
  14. +1
    -2
      Svelto.ECS/Core/EnginesRoot.DoubleBufferedEntitiesToAdd.cs
  15. +57
    -49
      Svelto.ECS/Core/EnginesRoot.Engines.cs
  16. +3
    -4
      Svelto.ECS/Core/EnginesRoot.Entities.cs
  17. +9
    -9
      Svelto.ECS/Core/EnginesRoot.GenericEntityFactory.cs
  18. +14
    -15
      Svelto.ECS/Core/EnginesRoot.GenericEntityFunctions.cs
  19. +73
    -56
      Svelto.ECS/Core/EnginesRoot.Submission.cs
  20. +0
    -0
      Svelto.ECS/Core/EntitiesDB.FindGroups.cs
  21. +0
    -0
      Svelto.ECS/Core/EntitiesDB.cs
  22. +28
    -26
      Svelto.ECS/Core/EntityCollection.cs
  23. +0
    -0
      Svelto.ECS/Core/EntityDescriptor/DynamicEntityDescriptor.cs
  24. +13
    -0
      Svelto.ECS/Core/EntityDescriptor/ExtendibleEntityDescriptor.cs
  25. +0
    -0
      Svelto.ECS/Core/EntityDescriptor/GenericEntityDescriptor.cs
  26. +6
    -0
      Svelto.ECS/Core/EntityDescriptor/IDynamicEntityDescriptor.cs
  27. +7
    -0
      Svelto.ECS/Core/EntityDescriptor/IEntityDescriptor.cs
  28. +0
    -9
      Svelto.ECS/Core/EntityDescriptorTemplate.cs
  29. +0
    -0
      Svelto.ECS/Core/EntityFactory.cs
  30. +0
    -0
      Svelto.ECS/Core/EntityGroupNotFoundException.cs
  31. +0
    -0
      Svelto.ECS/Core/EntityInfoView.cs
  32. +3
    -4
      Svelto.ECS/Core/EntityInitializer.cs
  33. +0
    -0
      Svelto.ECS/Core/EntityNotFoundException.cs
  34. +16
    -0
      Svelto.ECS/Core/EntitySubmissionScheduler.cs
  35. +0
    -0
      Svelto.ECS/Core/EntitySubmitOperation.cs
  36. +0
    -0
      Svelto.ECS/Core/EntityViewUtility.cs
  37. +1
    -2
      Svelto.ECS/Core/Filters/EntitiesDB.GroupFilters.cs
  38. +0
    -0
      Svelto.ECS/Core/Filters/FilterGroup.cs
  39. +15
    -1
      Svelto.ECS/Core/Filters/FilteredIndices.cs
  40. +1
    -1
      Svelto.ECS/Core/Filters/GroupFilters.cs
  41. +2
    -2
      Svelto.ECS/Core/GlobalTypeID.cs
  42. +27
    -0
      Svelto.ECS/Core/Groups/ExclusiveBuildGroup.cs
  43. +0
    -1
      Svelto.ECS/Core/Groups/ExclusiveGroup.cs
  44. +0
    -25
      Svelto.ECS/Core/Groups/ExclusiveGroupStruct.cs
  45. +4
    -4
      Svelto.ECS/Core/Groups/GroupCompound.cs
  46. +0
    -0
      Svelto.ECS/Core/Groups/NamedExclusiveGroup.cs
  47. +0
    -0
      Svelto.ECS/Core/Hybrid/IEntityDescriptorHolder.cs
  48. +0
    -0
      Svelto.ECS/Core/Hybrid/IEntityViewComponent.cs
  49. +0
    -0
      Svelto.ECS/Core/Hybrid/IImplementor.cs
  50. +13
    -0
      Svelto.ECS/Core/Hybrid/ValueReference.cs
  51. +0
    -0
      Svelto.ECS/Core/IComponentBuilder.cs
  52. +0
    -0
      Svelto.ECS/Core/IDisposingEngine.cs
  53. +8
    -0
      Svelto.ECS/Core/IEngine.cs
  54. +7
    -0
      Svelto.ECS/Core/IEntityComponent.cs
  55. +6
    -6
      Svelto.ECS/Core/IEntityFactory.cs
  56. +34
    -0
      Svelto.ECS/Core/IEntityFunctions.cs
  57. +0
    -5
      Svelto.ECS/Core/INeedEGID.cs
  58. +0
    -0
      Svelto.ECS/Core/IQueryingEntitiesEngine.cs
  59. +0
    -0
      Svelto.ECS/Core/QueryGroups.cs
  60. +0
    -2
      Svelto.ECS/Core/SetEGIDWithoutBoxing.cs
  61. +47
    -0
      Svelto.ECS/Core/SimpleEntitiesSubmissionScheduler.cs
  62. +546
    -0
      Svelto.ECS/Core/SpecialEnumerators/DoubleIterationEnumerator.cs
  63. +48
    -0
      Svelto.ECS/Core/SpecialEnumerators/WaitForSubmissionEnumerator.cs
  64. +0
    -0
      Svelto.ECS/Core/Streams/Consumer.cs
  65. +0
    -0
      Svelto.ECS/Core/Streams/EnginesRoot.Streams.cs
  66. +1
    -2
      Svelto.ECS/Core/Streams/EntitiesDB.Streams.cs
  67. +0
    -0
      Svelto.ECS/Core/Streams/EntitiesStreams.cs
  68. +0
    -0
      Svelto.ECS/Core/Streams/EntityStream.cs
  69. +0
    -0
      Svelto.ECS/Core/Streams/GenericentityStreamConsumerFactory.cs
  70. +0
    -0
      Svelto.ECS/Core/Streams/ThreadSafeNativeEntityStream.cs
  71. +0
    -0
      Svelto.ECS/Core/TypeSafeDictionaryFactory.cs
  72. +10
    -8
      Svelto.ECS/DataStructures/TypeSafeDictionary.cs
  73. +0
    -1
      Svelto.ECS/DataStructures/Unmanaged/NativeBag.cs
  74. +5
    -1
      Svelto.ECS/DataStructures/Unmanaged/NativeDynamicArrayCast.cs
  75. +0
    -1
      Svelto.ECS/DataStructures/Unmanaged/SharedNativeInt.cs
  76. +3
    -1
      Svelto.ECS/Dispatcher/DispatchOnChange.cs
  77. +13
    -12
      Svelto.ECS/Dispatcher/DispatchOnSet.cs
  78. +0
    -21
      Svelto.ECS/EntitySubmissionScheduler.cs
  79. +16
    -18
      Svelto.ECS/Extensions/Svelto/AllGroupsEnumerable.cs
  80. +14
    -15
      Svelto.ECS/Extensions/Svelto/EntityCollectionExtension.cs
  81. +84
    -79
      Svelto.ECS/Extensions/Svelto/GroupsEnumerable.cs
  82. +18
    -0
      Svelto.ECS/Extensions/Unity/DOTS/Jobs/IJobifiedEngine.cs
  83. +2
    -16
      Svelto.ECS/Extensions/Unity/DOTS/Jobs/JobifiedEnginesGroup.cs
  84. +43
    -36
      Svelto.ECS/Extensions/Unity/DOTS/Native/EnginesRoot.NativeOperation.cs
  85. +6
    -6
      Svelto.ECS/Extensions/Unity/DOTS/Native/NativeEGIDMultiMapper.cs
  86. +6
    -6
      Svelto.ECS/Extensions/Unity/DOTS/Native/NativeEntityFactory.cs
  87. +2
    -2
      Svelto.ECS/Extensions/Unity/DOTS/Native/NativeEntityInitializer.cs
  88. +1
    -1
      Svelto.ECS/Extensions/Unity/DOTS/Native/NativeEntitySwap.cs
  89. +3
    -3
      Svelto.ECS/Extensions/Unity/DOTS/Native/UnityEntityDBExtensions.cs
  90. +16
    -3
      Svelto.ECS/Extensions/Unity/DOTS/UECS/IUECSSubmissionEngine.cs
  91. +21
    -7
      Svelto.ECS/Extensions/Unity/DOTS/UECS/SveltoOverUECSEnginesGroup.cs
  92. +32
    -11
      Svelto.ECS/Extensions/Unity/DOTS/UECS/SveltoUECSEntitiesSubmissionGroup.cs
  93. +3
    -3
      Svelto.ECS/Extensions/Unity/EntityDescriptorHolderHelper.cs
  94. +2
    -2
      Svelto.ECS/Extensions/Unity/SveltoGUIHelper.cs
  95. +5
    -1
      Svelto.ECS/Extensions/Unity/UnityEntitiesSubmissionScheduler.cs
  96. +0
    -32
      Svelto.ECS/IEntityFunctions.cs
  97. +1
    -1
      Svelto.ECS/Serialization/DefaultVersioningFactory.cs
  98. +2
    -2
      Svelto.ECS/Serialization/EnginesRoot.GenericEntitySerialization.cs
  99. +0
    -1
      Svelto.ECS/Serialization/EntitiesDB.SerializationDescriptorMap.cs
  100. +1
    -1
      Svelto.ECS/Serialization/IDeserializationFactory.cs

+ 1
- 1
Svelto.Common

@@ -1 +1 @@
Subproject commit ee4913b173b844afcce2ec017abcb0845764db40
Subproject commit d0e08231b4464226b04c81b6a9aaaf5250200e36

+ 21
- 0
Svelto.ECS/CHANGELOG.md View File

@@ -0,0 +1,21 @@
# Changelog
All notable changes to this project will be documented in this file. I created this file with Svelto.ECS version 3.1.

## [0.3.1]

### Changed

* rearrange folders structures for clarity
* added DoubleEntitiesEnumerator, as seen in MiniExample 4, to allow a double iteration of the same group skipping already checked tuples
* reengineered the behaviour of WaitForSubmissionEnumerator
* removed redudant ISimpleEntitySubmissionScheduler interface
* renamed BuildGroup in to ExclusiveBuildGroup
* renamed EntityComponentInitializer to EntityInitializer
* Entity Submission now can optionally be time slices (based on number of entities to submit per slice)
* working on the Unity extension Submission Engine, still wip
* added the possibility to hold a reference in a EntityViewComponent. This reference cannot be accesses as an object, but can be converted to the original object in OOP abstract layers
* renamed NativeEntityComponentInitializer to NativeEntityInitializer
*

### Fixed


Svelto.ECS/AllowMultipleAttribute.cs → Svelto.ECS/Core/AllowMultipleAttribute.cs View File


Svelto.ECS/CheckEntityUtilities.cs → Svelto.ECS/Core/CheckEntityUtilities.cs View File

@@ -3,7 +3,6 @@
#endif
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Svelto.DataStructures;

namespace Svelto.ECS
@@ -72,7 +71,7 @@ namespace Svelto.ECS
#if DONT_USE
[Conditional("CHECK_ALL")]
#endif
void RemoveGroupID(BuildGroup groupID) { _idChecker.Remove(groupID); }
void RemoveGroupID(ExclusiveBuildGroup groupID) { _idChecker.Remove(groupID); }

#if DONT_USE
[Conditional("CHECK_ALL")]

Svelto.ECS/ComponentBuilder.CheckFields.cs → Svelto.ECS/Core/ComponentBuilder.CheckFields.cs View File


Svelto.ECS/ComponentBuilder.cs → Svelto.ECS/Core/ComponentBuilder.cs View File


Svelto.ECS/DBC.cs → Svelto.ECS/Core/DBC.cs View File


Svelto.ECS/ECSException.cs → Svelto.ECS/Core/ECSException.cs View File


Svelto.ECS/EGID.cs → Svelto.ECS/Core/EGID.cs View File

@@ -31,7 +31,7 @@ namespace Svelto.ECS
_GID = MAKE_GLOBAL_ID(entityID, groupID);
}
public EGID(uint entityID, BuildGroup groupID) : this()
public EGID(uint entityID, ExclusiveBuildGroup groupID) : this()
{
_GID = MAKE_GLOBAL_ID(entityID, groupID.group);
}

Svelto.ECS/EGIDMapper.cs → Svelto.ECS/Core/EGIDMapper.cs View File

@@ -1,7 +1,6 @@
using System;
using System.Runtime.CompilerServices;
using Svelto.Common;
using Svelto.DataStructures;
using Svelto.ECS.Internal;

namespace Svelto.ECS

+ 25
- 0
Svelto.ECS/Core/EnginesGroup/IStepEngine.cs View File

@@ -0,0 +1,25 @@
namespace Svelto.ECS
{
public interface IStepEngine : IEngine
{
void Step();
string name { get; }
}
public interface IStepEngine<T> : IEngine
{
void Step(in T _param);
string name { get; }
}
//this must stay IStep Engine as it may be part of a group itself
public interface IStepGroupEngine : IStepEngine
{
}
public interface IStepGroupEngine<T> : IStepEngine<T>
{
}
}

Svelto.ECS/SortedEnginesGroup.cs → Svelto.ECS/Core/EnginesGroup/SortedEnginesGroup.cs View File

@@ -3,28 +3,6 @@ using Svelto.Common;

namespace Svelto.ECS
{
public interface IStepEngine : IEngine
{
void Step();
string name { get; }
}
public interface IStepEngine<T> : IEngine
{
void Step(ref T _param);
string name { get; }
}
public interface IStepGroupEngine : IStepEngine
{
}
public interface IStepGroupEngine<T> : IStepEngine<T>
{
}

public abstract class SortedEnginesGroup<Interface, SequenceOrder> : IStepGroupEngine
where SequenceOrder : struct, ISequenceOrder where Interface : IStepEngine
{
@@ -47,7 +25,7 @@ namespace Svelto.ECS
}
}

public string name => _name;
public string name => _name;
readonly string _name;
readonly Sequence<Interface, SequenceOrder> _instancedSequence;
@@ -62,7 +40,7 @@ namespace Svelto.ECS
_instancedSequence = new Sequence<Interface, SequenceOrder>(engines);
}

public void Step(ref Parameter param)
public void Step(in Parameter param)
{
var sequenceItems = _instancedSequence.items;
using (var profiler = new PlatformProfiler(_name))
@@ -70,7 +48,7 @@ namespace Svelto.ECS
for (var index = 0; index < sequenceItems.count; index++)
{
var engine = sequenceItems[index];
using (profiler.Sample(engine.name)) engine.Step(ref param);
using (profiler.Sample(engine.name)) engine.Step(param);
}
}
}

Svelto.ECS/UnsortedEnginesGroup.cs → Svelto.ECS/Core/EnginesGroup/UnsortedEnginesGroup.cs View File

@@ -30,4 +30,32 @@ namespace Svelto.ECS
readonly string _name;
readonly FasterList<Interface> _instancedSequence;
}
public abstract class UnsortedEnginesGroup<Interface, Parameter> : IStepGroupEngine<Parameter>
where Interface : IStepEngine<Parameter>
{
protected UnsortedEnginesGroup(FasterList<Interface> engines)
{
_name = "UnsortedEnginesGroup - "+this.GetType().Name;
_instancedSequence = engines;
}

public void Step(in Parameter param)
{
var sequenceItems = _instancedSequence;
using (var profiler = new PlatformProfiler(_name))
{
for (var index = 0; index < sequenceItems.count; index++)
{
var engine = sequenceItems[index];
using (profiler.Sample(engine.name)) engine.Step(param);
}
}
}

public string name => _name;
readonly string _name;
readonly FasterList<Interface> _instancedSequence;
}
}

Svelto.ECS/EnginesRoot.DoubleBufferedEntitiesToAdd.cs → Svelto.ECS/Core/EnginesRoot.DoubleBufferedEntitiesToAdd.cs View File

@@ -1,5 +1,4 @@
using System;
using Svelto.DataStructures;
using Svelto.DataStructures;
using Svelto.ECS.Internal;

namespace Svelto.ECS

Svelto.ECS/EnginesRoot.Engines.cs → Svelto.ECS/Core/EnginesRoot.Engines.cs View File

@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Svelto.Common;
using Svelto.DataStructures;
@@ -9,26 +10,38 @@ namespace Svelto.ECS
{
public sealed partial class EnginesRoot
{
public readonly struct EntitiesSubmitter
public struct EntitiesSubmitter
{
public EntitiesSubmitter(EnginesRoot enginesRoot)
public EntitiesSubmitter(EnginesRoot enginesRoot) : this()
{
_weakReference = new Svelto.DataStructures.WeakReference<EnginesRoot>(enginesRoot);
}

public bool IsUnused => _weakReference.IsValid == false;

public void Invoke()
public IEnumerator Invoke(uint maxNumberOfOperationsPerFrame)
{
if (_weakReference.IsValid)
_weakReference.Target.SubmitEntityComponents();
var entitiesSubmissionScheduler = _weakReference.Target._scheduler;
if (_weakReference.IsValid && entitiesSubmissionScheduler.paused == false)
{
var submitEntityComponents =
_weakReference.Target.SubmitEntityComponents(maxNumberOfOperationsPerFrame);
DBC.ECS.Check.Require(entitiesSubmissionScheduler.isRunning == false
, "A submission started while the previous one was still flushing");
entitiesSubmissionScheduler.isRunning = true;
while (submitEntityComponents.MoveNext() == true)
yield return null;

entitiesSubmissionScheduler.isRunning = false;
++entitiesSubmissionScheduler.iteration;
}
}

readonly Svelto.DataStructures.WeakReference<EnginesRoot> _weakReference;
}

readonly EntitiesSubmissionScheduler _scheduler;
public IEntitiesSubmissionScheduler scheduler => _scheduler;
readonly EntitiesSubmissionScheduler _scheduler;
public EntitiesSubmissionScheduler scheduler => _scheduler;

/// <summary>
/// Engines root contextualize your engines and entities. You don't need to limit yourself to one EngineRoot
@@ -40,15 +53,16 @@ namespace Svelto.ECS
/// </summary>
public EnginesRoot(EntitiesSubmissionScheduler entitiesComponentScheduler)
{
_entitiesOperations = new ThreadSafeDictionary<ulong, EntitySubmitOperation>();
serializationDescriptorMap = new SerializationDescriptorMap();
_reactiveEnginesAddRemove = new FasterDictionary<RefWrapperType, FasterList<IReactEngine>>();
_reactiveEnginesSwap = new FasterDictionary<RefWrapperType, FasterList<IReactEngine>>();
_reactiveEnginesSubmission = new FasterList<IReactOnSubmission>();
_enginesSet = new FasterList<IEngine>();
_enginesTypeSet = new HashSet<Type>();
_disposableEngines = new FasterList<IDisposable>();
_transientEntitiesOperations = new FasterList<EntitySubmitOperation>();
_entitiesOperations = new FasterDictionary<ulong, EntitySubmitOperation>();
serializationDescriptorMap = new SerializationDescriptorMap();
_reactiveEnginesAddRemove = new FasterDictionary<RefWrapperType, FasterList<IReactEngine>>();
_reactiveEnginesAddRemoveOnDispose = new FasterDictionary<RefWrapperType, FasterList<IReactEngine>>();
_reactiveEnginesSwap = new FasterDictionary<RefWrapperType, FasterList<IReactEngine>>();
_reactiveEnginesSubmission = new FasterList<IReactOnSubmission>();
_enginesSet = new FasterList<IEngine>();
_enginesTypeSet = new HashSet<Type>();
_disposableEngines = new FasterList<IDisposable>();
_transientEntitiesOperations = new FasterList<EntitySubmitOperation>();

_groupEntityComponentsDB =
new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>();
@@ -104,15 +118,13 @@ namespace Svelto.ECS
}
}

foreach (FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>.
KeyValuePairFast groups in _groupEntityComponentsDB)
foreach (var groups in _groupEntityComponentsDB)
{
foreach (FasterDictionary<RefWrapperType, ITypeSafeDictionary>.KeyValuePairFast entityList in groups
.Value)
foreach (var entityList in groups.Value)
try
{
entityList.Value.ExecuteEnginesRemoveCallbacks(_reactiveEnginesAddRemove, profiler
, new ExclusiveGroupStruct(groups.Key));
entityList.Value.ExecuteEnginesRemoveCallbacks(_reactiveEnginesAddRemoveOnDispose, profiler
, new ExclusiveGroupStruct(groups.Key));
}
catch (Exception e)
{
@@ -120,18 +132,15 @@ namespace Svelto.ECS
}
}

foreach (FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>.
KeyValuePairFast groups in _groupEntityComponentsDB)
foreach (var groups in _groupEntityComponentsDB)
{
foreach (FasterDictionary<RefWrapperType, ITypeSafeDictionary>.KeyValuePairFast entityList in groups
.Value)
foreach (var entityList in groups.Value)
entityList.Value.Dispose();
}

foreach (FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, GroupFilters>>.
KeyValuePairFast type in _groupFilters)
foreach (FasterDictionary<ExclusiveGroupStruct, GroupFilters>.KeyValuePairFast group in type.Value)
group.Value.Dispose();
foreach (var type in _groupFilters)
foreach (var group in type.Value)
group.Value.Dispose();

_groupFilters.Clear();

@@ -148,6 +157,7 @@ namespace Svelto.ECS
_enginesTypeSet.Clear();
_reactiveEnginesSwap.Clear();
_reactiveEnginesAddRemove.Clear();
_reactiveEnginesAddRemoveOnDispose.Clear();
_reactiveEnginesSubmission.Clear();

_entitiesOperations.Clear();
@@ -183,6 +193,9 @@ namespace Svelto.ECS
if (engine is IReactOnAddAndRemove viewEngine)
CheckReactEngineComponents(viewEngine, _reactiveEnginesAddRemove);

if (engine is IReactOnDispose viewEngineDispose)
CheckReactEngineComponents(viewEngineDispose, _reactiveEnginesAddRemoveOnDispose);

if (engine is IReactOnSwap viewEngineSwap)
CheckReactEngineComponents(viewEngineSwap, _reactiveEnginesSwap);

@@ -219,12 +232,12 @@ namespace Svelto.ECS
{
var genericArguments = interf.GetGenericArgumentsEx();

AddEngine(engine, genericArguments, engines);
AddEngineToList(engine, genericArguments, engines);
}
}
}

static void AddEngine<T>
static void AddEngineToList<T>
(T engine, Type[] entityComponentTypes, FasterDictionary<RefWrapperType, FasterList<IReactEngine>> engines)
where T : class, IReactEngine
{
@@ -232,29 +245,24 @@ namespace Svelto.ECS
{
var type = entityComponentTypes[i];

AddEngine(engine, engines, type);
}
}
if (engines.TryGetValue(new RefWrapperType(type), out var list) == false)
{
list = new FasterList<IReactEngine>();

static void AddEngine<T>(T engine, FasterDictionary<RefWrapperType, FasterList<IReactEngine>> engines, Type type)
where T : class, IReactEngine
{
if (engines.TryGetValue(new RefWrapperType(type), out var list) == false)
{
list = new FasterList<IReactEngine>();
engines.Add(new RefWrapperType(type), list);
}

engines.Add(new RefWrapperType(type), list);
list.Add(engine);
}

list.Add(engine);
}

readonly FasterDictionary<RefWrapperType, FasterList<IReactEngine>> _reactiveEnginesAddRemove;
readonly FasterDictionary<RefWrapperType, FasterList<IReactEngine>> _reactiveEnginesAddRemoveOnDispose;
readonly FasterDictionary<RefWrapperType, FasterList<IReactEngine>> _reactiveEnginesSwap;
readonly FasterList<IReactOnSubmission> _reactiveEnginesSubmission;
readonly FasterList<IDisposable> _disposableEngines;
readonly FasterList<IEngine> _enginesSet;
readonly HashSet<Type> _enginesTypeSet;
internal bool _isDisposing;
readonly FasterList<IReactOnSubmission> _reactiveEnginesSubmission;
readonly FasterList<IDisposable> _disposableEngines;
readonly FasterList<IEngine> _enginesSet;
readonly HashSet<Type> _enginesTypeSet;
internal bool _isDisposing;
}
}

Svelto.ECS/EnginesRoot.Entities.cs → Svelto.ECS/Core/EnginesRoot.Entities.cs View File

@@ -29,7 +29,7 @@ namespace Svelto.ECS

///--------------------------------------------
[MethodImpl(MethodImplOptions.AggressiveInlining)]
EntityComponentInitializer BuildEntity
EntityInitializer BuildEntity
(EGID entityID, IComponentBuilder[] componentsToBuild, Type descriptorType,
IEnumerable<object> implementors = null)
{
@@ -39,7 +39,7 @@ namespace Svelto.ECS
var dic = EntityFactory.BuildGroupedEntities(entityID, _groupedEntityToAdd, componentsToBuild
, implementors, descriptorType);

return new EntityComponentInitializer(entityID, dic);
return new EntityInitializer(entityID, dic);
}

///--------------------------------------------
@@ -285,8 +285,7 @@ namespace Svelto.ECS
{
if (_groupEntityComponentsDB.TryGetValue(groupID, out var dictionariesOfEntities))
{
foreach (FasterDictionary<RefWrapperType, ITypeSafeDictionary>.KeyValuePairFast dictionaryOfEntities
in dictionariesOfEntities)
foreach (var dictionaryOfEntities in dictionariesOfEntities)
{
dictionaryOfEntities.Value.ExecuteEnginesRemoveCallbacks(_reactiveEnginesAddRemove, profiler
, new ExclusiveGroupStruct(groupID));

Svelto.ECS/EnginesRoot.GenericEntityFactory.cs → Svelto.ECS/Core/EnginesRoot.GenericEntityFactory.cs View File

@@ -13,8 +13,8 @@ namespace Svelto.ECS
_enginesRoot = new Svelto.DataStructures.WeakReference<EnginesRoot>(weakReference);
}

public EntityComponentInitializer BuildEntity<T>
(uint entityID, BuildGroup groupStructId, IEnumerable<object> implementors = null)
public EntityInitializer BuildEntity<T>
(uint entityID, ExclusiveBuildGroup groupStructId, IEnumerable<object> implementors = null)
where T : IEntityDescriptor, new()
{
return _enginesRoot.Target.BuildEntity(new EGID(entityID, groupStructId)
@@ -22,26 +22,26 @@ namespace Svelto.ECS
, TypeCache<T>.type, implementors);
}

public EntityComponentInitializer BuildEntity<T>(EGID egid, IEnumerable<object> implementors = null)
public EntityInitializer BuildEntity<T>(EGID egid, IEnumerable<object> implementors = null)
where T : IEntityDescriptor, new()
{
return _enginesRoot.Target.BuildEntity(
egid, EntityDescriptorTemplate<T>.descriptor.componentsToBuild, TypeCache<T>.type, implementors);
}

public EntityComponentInitializer BuildEntity<T>
public EntityInitializer BuildEntity<T>
(EGID egid, T entityDescriptor, IEnumerable<object> implementors) where T : IEntityDescriptor
{
return _enginesRoot.Target.BuildEntity(egid, entityDescriptor.componentsToBuild, TypeCache<T>.type, implementors);
}
#if UNITY_NATIVE
public NativeEntityFactory ToNative<T>(string memberName) where T : IEntityDescriptor, new()
public NativeEntityFactory ToNative<T>(string callerName) where T : IEntityDescriptor, new()
{
return _enginesRoot.Target.ProvideNativeEntityFactoryQueue<T>(memberName);
return _enginesRoot.Target.ProvideNativeEntityFactoryQueue<T>(callerName);
}
#endif
public EntityComponentInitializer BuildEntity<T>
(uint entityID, BuildGroup groupStructId, T descriptorEntity, IEnumerable<object> implementors)
public EntityInitializer BuildEntity<T>
(uint entityID, ExclusiveBuildGroup groupStructId, T descriptorEntity, IEnumerable<object> implementors)
where T : IEntityDescriptor
{
return _enginesRoot.Target.BuildEntity(new EGID(entityID, groupStructId)
@@ -54,7 +54,7 @@ namespace Svelto.ECS
_enginesRoot.Target.Preallocate<T>(groupStructId, size);
}
public EntityComponentInitializer BuildEntity(EGID egid, IComponentBuilder[] componentsToBuild, Type type, IEnumerable<object> implementors = null)
public EntityInitializer BuildEntity(EGID egid, IComponentBuilder[] componentsToBuild, Type type, IEnumerable<object> implementors = null)
{
return _enginesRoot.Target.BuildEntity(egid, componentsToBuild, type, implementors);
}

Svelto.ECS/EnginesRoot.GenericEntityFunctions.cs → Svelto.ECS/Core/EnginesRoot.GenericEntityFunctions.cs View File

@@ -1,5 +1,4 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.CompilerServices;
using Svelto.Common;
using Svelto.DataStructures;
using Svelto.ECS.Internal;
@@ -20,18 +19,18 @@ namespace Svelto.ECS
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RemoveEntity<T>(uint entityID, BuildGroup groupID) where T :
public void RemoveEntity<T>(uint entityID, ExclusiveBuildGroup groupID, [CallerMemberName] string memberName = "") where T :
IEntityDescriptor, new()
{
RemoveEntity<T>(new EGID(entityID, groupID));
RemoveEntity<T>(new EGID(entityID, groupID), memberName);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RemoveEntity<T>(EGID entityEGID) where T : IEntityDescriptor, new()
public void RemoveEntity<T>(EGID entityEGID, [CallerMemberName] string memberName = "") where T : IEntityDescriptor, new()
{
DBC.ECS.Check.Require(entityEGID.groupID != 0, "invalid group detected");
var descriptorComponentsToBuild = EntityDescriptorTemplate<T>.descriptor.componentsToBuild;
_enginesRoot.Target.CheckRemoveEntityID(entityEGID, TypeCache<T>.type);
_enginesRoot.Target.CheckRemoveEntityID(entityEGID, TypeCache<T>.type, memberName);

_enginesRoot.Target.QueueEntitySubmitOperation<T>(
new EntitySubmitOperation(EntitySubmitOperationType.Remove, entityEGID, entityEGID,
@@ -39,7 +38,7 @@ namespace Svelto.ECS
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RemoveEntitiesFromGroup(BuildGroup groupID)
public void RemoveEntitiesFromGroup(ExclusiveBuildGroup groupID)
{
DBC.ECS.Check.Require(groupID != 0, "invalid group detected");
_enginesRoot.Target.RemoveGroupID(groupID);
@@ -73,7 +72,7 @@ namespace Svelto.ECS
// }

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SwapEntitiesInGroup<T>(BuildGroup fromGroupID, BuildGroup toGroupID)
public void SwapEntitiesInGroup<T>(ExclusiveBuildGroup fromGroupID, ExclusiveBuildGroup toGroupID)
where T : IEntityDescriptor, new()
{
if (_enginesRoot.Target._groupEntityComponentsDB.TryGetValue(
@@ -98,23 +97,23 @@ namespace Svelto.ECS
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SwapEntityGroup<T>(uint entityID, BuildGroup fromGroupID,
BuildGroup toGroupID)
public void SwapEntityGroup<T>(uint entityID, ExclusiveBuildGroup fromGroupID,
ExclusiveBuildGroup toGroupID)
where T : IEntityDescriptor, new()
{
SwapEntityGroup<T>(new EGID(entityID, fromGroupID), toGroupID);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SwapEntityGroup<T>(EGID fromID, BuildGroup toGroupID)
public void SwapEntityGroup<T>(EGID fromID, ExclusiveBuildGroup toGroupID)
where T : IEntityDescriptor, new()
{
SwapEntityGroup<T>(fromID, new EGID(fromID.entityID, (uint) toGroupID));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SwapEntityGroup<T>(EGID fromID, BuildGroup toGroupID
, BuildGroup mustBeFromGroup)
public void SwapEntityGroup<T>(EGID fromID, ExclusiveBuildGroup toGroupID
, ExclusiveBuildGroup mustBeFromGroup)
where T : IEntityDescriptor, new()
{
if (fromID.groupID != mustBeFromGroup)
@@ -125,7 +124,7 @@ namespace Svelto.ECS

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SwapEntityGroup<T>(EGID fromID, EGID toID
, BuildGroup mustBeFromGroup)
, ExclusiveBuildGroup mustBeFromGroup)
where T : IEntityDescriptor, new()
{
if (fromID.groupID != mustBeFromGroup)
@@ -196,7 +195,7 @@ namespace Svelto.ECS
}
else
#endif
_entitiesOperations.Set((ulong) entitySubmitOperation.fromID, entitySubmitOperation);
_entitiesOperations[(ulong) entitySubmitOperation.fromID] = entitySubmitOperation;
}
}
}

Svelto.ECS/EnginesRoot.Submission.cs → Svelto.ECS/Core/EnginesRoot.Submission.cs View File

@@ -1,4 +1,4 @@
using System;
using System.Collections;
using Svelto.Common;
using Svelto.DataStructures;
using Svelto.ECS.Internal;
@@ -9,16 +9,18 @@ namespace Svelto.ECS
{
readonly FasterList<EntitySubmitOperation> _transientEntitiesOperations;

void SubmitEntityComponents()
IEnumerator SubmitEntityComponents(uint maxNumberOfOperations)
{
using (var profiler = new PlatformProfiler("Svelto.ECS - Entities Submission"))
{
int iterations = 0;
do
{
SingleSubmission(profiler);
var submitEntityComponents = SingleSubmission(profiler, maxNumberOfOperations);
while (submitEntityComponents.MoveNext() == true)
yield return null;
} while ((_groupedEntityToAdd.currentEntitiesCreatedPerGroup.count > 0 ||
_entitiesOperations.Count > 0) && ++iterations < 5);
_entitiesOperations.count > 0) && ++iterations < 5);

#if DEBUG && !PROFILE_SVELTO
if (iterations == 5)
@@ -32,7 +34,8 @@ namespace Svelto.ECS
/// Something to do when I will optimize the callbacks
/// </summary>
/// <param name="profiler"></param>
void SingleSubmission(in PlatformProfiler profiler)
/// <param name="maxNumberOfOperations"></param>
IEnumerator SingleSubmission(PlatformProfiler profiler, uint maxNumberOfOperations)
{
#if UNITY_NATIVE
NativeOperationSubmission(profiler);
@@ -40,8 +43,9 @@ namespace Svelto.ECS
ClearChecks();

bool entitiesAreSubmitted = false;
uint numberOfOperations = 0;
if (_entitiesOperations.Count > 0)
if (_entitiesOperations.count > 0)
{
using (profiler.Sample("Remove and Swap operations"))
{
@@ -88,6 +92,16 @@ namespace Svelto.ECS

throw;
}

++numberOfOperations;

if ((uint)numberOfOperations >= (uint)maxNumberOfOperations)
{
yield return null;
numberOfOperations = 0;
}
}
}

@@ -102,11 +116,61 @@ namespace Svelto.ECS
{
try
{
AddEntityComponentsToTheDBAndSuitableEngines(profiler);
using (profiler.Sample("Add entities to database"))
{
//each group is indexed by entity view type. for each type there is a dictionary indexed by entityID
foreach (var groupToSubmit in _groupedEntityToAdd.otherEntitiesCreatedPerGroup)
{
var groupID = groupToSubmit.Key;
var groupDB = GetOrCreateGroup(groupID, profiler);

//add the entityComponents in the group
foreach (var entityComponentsToSubmit in _groupedEntityToAdd.other[groupID])
{
var type = entityComponentsToSubmit.Key;
var targetTypeSafeDictionary = entityComponentsToSubmit.Value;
var wrapper = new RefWrapperType(type);

ITypeSafeDictionary dbDic = GetOrCreateTypeSafeDictionary(groupID, groupDB, wrapper,
targetTypeSafeDictionary);

//Fill the DB with the entity components generate this frame.
dbDic.AddEntitiesFromDictionary(targetTypeSafeDictionary, groupID);
}
}
}

//then submit everything in the engines, so that the DB is up to date with all the entity components
//created by the entity built
using (profiler.Sample("Add entities to engines"))
{
foreach (var groupToSubmit in _groupedEntityToAdd.otherEntitiesCreatedPerGroup)
{
var groupID = groupToSubmit.Key;
var groupDB = _groupEntityComponentsDB[groupID];

foreach (var entityComponentsToSubmit in _groupedEntityToAdd.other[groupID])
{
var realDic = groupDB[new RefWrapperType(entityComponentsToSubmit.Key)];

entityComponentsToSubmit.Value.ExecuteEnginesAddOrSwapCallbacks(_reactiveEnginesAddRemove, realDic,
null, new ExclusiveGroupStruct(groupID), in profiler);
++numberOfOperations;

if (numberOfOperations >= maxNumberOfOperations)
{
yield return null;
numberOfOperations = 0;
}
}
}
}
}
finally
{
using (profiler.Sample("clear 6operates double buffering"))
using (profiler.Sample("clear double buffering"))
{
//other can be cleared now, but let's avoid deleting the dictionary every time
_groupedEntityToAdd.ClearOther();
@@ -125,54 +189,7 @@ namespace Svelto.ECS
}
}

void AddEntityComponentsToTheDBAndSuitableEngines(in PlatformProfiler profiler)
{
using (profiler.Sample("Add entities to database"))
{
//each group is indexed by entity view type. for each type there is a dictionary indexed by entityID
foreach (var groupOfEntitiesToSubmit in _groupedEntityToAdd.otherEntitiesCreatedPerGroup)
{
var groupID = groupOfEntitiesToSubmit.Key;
var groupDB = GetOrCreateGroup(groupID, profiler);

//add the entityComponents in the group
foreach (var entityComponentsToSubmit in _groupedEntityToAdd.other[groupID])
{
var type = entityComponentsToSubmit.Key;
var targetTypeSafeDictionary = entityComponentsToSubmit.Value;
var wrapper = new RefWrapperType(type);

ITypeSafeDictionary dbDic = GetOrCreateTypeSafeDictionary(groupID, groupDB, wrapper,
targetTypeSafeDictionary);

//Fill the DB with the entity components generate this frame.
dbDic.AddEntitiesFromDictionary(targetTypeSafeDictionary, groupID);
}
}
}

//then submit everything in the engines, so that the DB is up to date with all the entity components
//created by the entity built
using (profiler.Sample("Add entities to engines"))
{
foreach (var groupToSubmit in _groupedEntityToAdd.otherEntitiesCreatedPerGroup)
{
var groupID = groupToSubmit.Key;
var groupDB = _groupEntityComponentsDB[groupID];

foreach (var entityComponentsToSubmit in _groupedEntityToAdd.other[groupID])
{
var realDic = groupDB[new RefWrapperType(entityComponentsToSubmit.Key)];

entityComponentsToSubmit.Value.ExecuteEnginesAddOrSwapCallbacks(_reactiveEnginesAddRemove, realDic,
null, new ExclusiveGroupStruct(groupToSubmit.Key), in profiler);
}
}
}
}

readonly DoubleBufferedEntitiesToAdd _groupedEntityToAdd;
readonly ThreadSafeDictionary<ulong, EntitySubmitOperation> _entitiesOperations;
readonly FasterDictionary<ulong, EntitySubmitOperation> _entitiesOperations;
}
}

Svelto.ECS/EntitiesDB.FindGroups.cs → Svelto.ECS/Core/EntitiesDB.FindGroups.cs View File


Svelto.ECS/EntitiesDB.cs → Svelto.ECS/Core/EntitiesDB.cs View File


Svelto.ECS/EntityCollection.cs → Svelto.ECS/Core/EntityCollection.cs View File

@@ -6,16 +6,17 @@ namespace Svelto.ECS
{
public readonly ref struct EntityCollection<T> where T : struct, IEntityComponent
{
static readonly bool IsUnmanaged = TypeSafeDictionary<T>.IsUnmanaged;
public EntityCollection(IBuffer<T> buffer, uint count):this()
static readonly bool IsUnmanaged = TypeSafeDictionary<T>.IsUnmanaged;
public EntityCollection(IBuffer<T> buffer, uint count) : this()
{
DBC.ECS.Check.Require(count == 0 || buffer.isValid, "Buffer is found in impossible state");
if (IsUnmanaged)
_nativedBuffer = (NB<T>) buffer;
else
_managedBuffer = (MB<T>) buffer;
_count = count;
_count = count;
}

public uint count => _count;
@@ -26,7 +27,8 @@ namespace Svelto.ECS
readonly uint _count;
}

public readonly ref struct EntityCollection<T1, T2> where T1 : struct, IEntityComponent where T2 : struct, IEntityComponent
public readonly ref struct EntityCollection<T1, T2>
where T1 : struct, IEntityComponent where T2 : struct, IEntityComponent
{
internal EntityCollection(in EntityCollection<T1> array1, in EntityCollection<T2> array2)
{
@@ -89,14 +91,14 @@ namespace Svelto.ECS
readonly EntityCollection<T3> _array3;
}

public readonly ref struct EntityCollection<T1, T2, T3, T4>
where T1 : struct, IEntityComponent
where T2 : struct, IEntityComponent
where T3 : struct, IEntityComponent
where T4 : struct, IEntityComponent
public readonly ref struct EntityCollection<T1, T2, T3, T4> where T1 : struct, IEntityComponent
where T2 : struct, IEntityComponent
where T3 : struct, IEntityComponent
where T4 : struct, IEntityComponent
{
internal EntityCollection
(in EntityCollection<T1> array1, in EntityCollection<T2> array2, in EntityCollection<T3> array3, in EntityCollection<T4> array4)
(in EntityCollection<T1> array1, in EntityCollection<T2> array2, in EntityCollection<T3> array3
, in EntityCollection<T4> array4)
{
_array1 = array1;
_array2 = array2;
@@ -104,25 +106,25 @@ namespace Svelto.ECS
_array4 = array4;
}

internal EntityCollection<T1> Item1
internal EntityCollection<T1> buffer1
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _array1;
}

internal EntityCollection<T2> Item2
internal EntityCollection<T2> buffer2
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _array2;
}

internal EntityCollection<T3> Item3
internal EntityCollection<T3> buffer3
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _array3;
}
internal EntityCollection<T4> Item4
internal EntityCollection<T4> buffer4
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _array4;
@@ -142,7 +144,7 @@ namespace Svelto.ECS
public readonly BufferT2 buffer2;
public readonly BufferT3 buffer3;
public readonly BufferT4 buffer4;
public readonly int count;
public readonly int count;

public BT(BufferT1 bufferT1, BufferT2 bufferT2, BufferT3 bufferT3, BufferT4 bufferT4, uint count) : this()
{
@@ -159,7 +161,7 @@ namespace Svelto.ECS
public readonly BufferT1 buffer1;
public readonly BufferT2 buffer2;
public readonly BufferT3 buffer3;
public readonly int count;
public readonly int count;

public BT(BufferT1 bufferT1, BufferT2 bufferT2, BufferT3 bufferT3, uint count) : this()
{
@@ -174,27 +176,27 @@ namespace Svelto.ECS
bufferT1 = buffer1;
bufferT2 = buffer2;
bufferT3 = buffer3;
count = this.count;
count = this.count;
}
}

public readonly struct BT<BufferT1>
{
public readonly BufferT1 buffer;
public readonly int count;
public readonly int count;

public BT(BufferT1 bufferT1, uint count) : this()
{
this.buffer = bufferT1;
this.count = (int) count;
}
public void Deconstruct(out BufferT1 bufferT1, out int count)
{
bufferT1 = buffer;
count = this.count;
}
public static implicit operator BufferT1(BT<BufferT1> t) => t.buffer;
}

@@ -202,7 +204,7 @@ namespace Svelto.ECS
{
public readonly BufferT1 buffer1;
public readonly BufferT2 buffer2;
public readonly int count;
public readonly int count;

public BT(BufferT1 bufferT1, BufferT2 bufferT2, uint count) : this()
{
@@ -210,7 +212,7 @@ namespace Svelto.ECS
this.buffer2 = bufferT2;
this.count = (int) count;
}
public void Deconstruct(out BufferT1 bufferT1, out BufferT2 bufferT2, out int count)
{
bufferT1 = buffer1;
@@ -218,4 +220,4 @@ namespace Svelto.ECS
count = this.count;
}
}
}
}

Svelto.ECS/DynamicEntityDescriptor.cs → Svelto.ECS/Core/EntityDescriptor/DynamicEntityDescriptor.cs View File


Svelto.ECS/ExtendibleEntityDescriptor.cs → Svelto.ECS/Core/EntityDescriptor/ExtendibleEntityDescriptor.cs View File

@@ -6,6 +6,19 @@ namespace Svelto.ECS
/// <summary>
/// Inherit from an ExtendibleEntityDescriptor to extend a base entity descriptor that can be used
/// to swap and remove specialized entities from abstract engines
///
/// Usage Example:
///
/// class SpecialisedDescriptor : ExtendibleEntityDescriptor<BaseDescriptor>
/// {
/// public SpecialisedDescriptor() : base (new IComponentBuilder[]
/// {
/// new ComponentBuilder<ObjectParentComponent>() //add more components to the base descriptor
/// })
/// {
/// ExtendWith<ContractDescriptor>(); //add extra components from descriptors that act as contract
/// }
/// }
/// </summary>
/// <typeparam name="TType"></typeparam>
public class ExtendibleEntityDescriptor<TType> : IDynamicEntityDescriptor where TType : IEntityDescriptor, new()

Svelto.ECS/GenericEntityDescriptor.cs → Svelto.ECS/Core/EntityDescriptor/GenericEntityDescriptor.cs View File


+ 6
- 0
Svelto.ECS/Core/EntityDescriptor/IDynamicEntityDescriptor.cs View File

@@ -0,0 +1,6 @@
namespace Svelto.ECS
{
public interface IDynamicEntityDescriptor: IEntityDescriptor
{
}
}

+ 7
- 0
Svelto.ECS/Core/EntityDescriptor/IEntityDescriptor.cs View File

@@ -0,0 +1,7 @@
namespace Svelto.ECS
{
public interface IEntityDescriptor
{
IComponentBuilder[] componentsToBuild { get; }
}
}

Svelto.ECS/EntityDescriptorTemplate.cs → Svelto.ECS/Core/EntityDescriptorTemplate.cs View File

@@ -2,15 +2,6 @@ using System;

namespace Svelto.ECS
{
public interface IEntityDescriptor
{
IComponentBuilder[] componentsToBuild { get; }
}
public interface IDynamicEntityDescriptor: IEntityDescriptor
{
}

static class EntityDescriptorTemplate<TType> where TType : IEntityDescriptor, new()
{
static EntityDescriptorTemplate()

Svelto.ECS/EntityFactory.cs → Svelto.ECS/Core/EntityFactory.cs View File


Svelto.ECS/EntityGroupNotFoundException.cs → Svelto.ECS/Core/EntityGroupNotFoundException.cs View File


Svelto.ECS/EntityInfoView.cs → Svelto.ECS/Core/EntityInfoView.cs View File


Svelto.ECS/EntityComponentInitializer.cs → Svelto.ECS/Core/EntityInitializer.cs View File

@@ -1,12 +1,11 @@
using System;
using Svelto.DataStructures;
using Svelto.DataStructures;
using Svelto.ECS.Internal;

namespace Svelto.ECS
{
public readonly ref struct EntityComponentInitializer
public readonly ref struct EntityInitializer
{
public EntityComponentInitializer(EGID id, FasterDictionary<RefWrapperType, ITypeSafeDictionary> group)
public EntityInitializer(EGID id, FasterDictionary<RefWrapperType, ITypeSafeDictionary> group)
{
_group = group;
_ID = id;

Svelto.ECS/EntityNotFoundException.cs → Svelto.ECS/Core/EntityNotFoundException.cs View File


+ 16
- 0
Svelto.ECS/Core/EntitySubmissionScheduler.cs View File

@@ -0,0 +1,16 @@
using System.Collections;

namespace Svelto.ECS.Schedulers
{
public abstract class EntitiesSubmissionScheduler
{
protected internal abstract EnginesRoot.EntitiesSubmitter onTick { set; }

public abstract void Dispose();

public abstract bool paused { get; set; }
public uint iteration { get; protected internal set; }
internal bool isRunning;
}
}

Svelto.ECS/EntitySubmitOperation.cs → Svelto.ECS/Core/EntitySubmitOperation.cs View File


Svelto.ECS/EntityViewUtility.cs → Svelto.ECS/Core/EntityViewUtility.cs View File


Svelto.ECS/Filters/EntitiesDB.GroupFilters.cs → Svelto.ECS/Core/Filters/EntitiesDB.GroupFilters.cs View File

@@ -1,4 +1,3 @@
using System;
using Svelto.DataStructures;

namespace Svelto.ECS
@@ -99,7 +98,7 @@ namespace Svelto.ECS
#endif
return ref _filters[TypeRefWrapper<T>.wrapper][groupID].GetFilter(filterId);
}
public bool TryGetFilterForGroup<T>(int filterId, ExclusiveGroupStruct groupID, out FilterGroup groupFilter)
where T : struct, IEntityComponent
{

Svelto.ECS/Filters/FilterGroup.cs → Svelto.ECS/Core/Filters/FilterGroup.cs View File


Svelto.ECS/Filters/FilteredIndices.cs → Svelto.ECS/Core/Filters/FilteredIndices.cs View File

@@ -8,14 +8,28 @@ namespace Svelto.ECS
public FilteredIndices(NativeDynamicArrayCast<uint> denseListOfIndicesToEntityComponentArray)
{
_denseListOfIndicesToEntityComponentArray = denseListOfIndicesToEntityComponentArray;
_count = _denseListOfIndicesToEntityComponentArray.count;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Count() => _denseListOfIndicesToEntityComponentArray.Count();
public int Count() => _count;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public uint Get(uint index) => _denseListOfIndicesToEntityComponentArray[index];

public uint this[uint index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _denseListOfIndicesToEntityComponentArray[index];
}

public uint this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _denseListOfIndicesToEntityComponentArray[index];
}

readonly NativeDynamicArrayCast<uint> _denseListOfIndicesToEntityComponentArray;
readonly int _count;
}
}

Svelto.ECS/Filters/GroupFilters.cs → Svelto.ECS/Core/Filters/GroupFilters.cs View File

@@ -40,7 +40,7 @@ namespace Svelto.ECS
return filters.TryGetValue(filterIndex, out filter);
}

public SveltoDictionary<int, FilterGroup, NativeStrategy<FasterDictionaryNode<int>>, NativeStrategy<FilterGroup>
public SveltoDictionary<int, FilterGroup, NativeStrategy<SveltoDictionaryNode<int>>, NativeStrategy<FilterGroup>
, NativeStrategy<int>>.SveltoDictionaryKeyValueEnumerator GetEnumerator()
{
return filters.GetEnumerator();

Svelto.ECS/GlobalTypeID.cs → Svelto.ECS/Core/GlobalTypeID.cs View File

@@ -16,7 +16,7 @@ namespace Svelto.ECS

interface IFiller
{
void FillFromByteArray(EntityComponentInitializer init, NativeBag buffer);
void FillFromByteArray(EntityInitializer init, NativeBag buffer);
}

class Filler<T> : IFiller where T : struct, IEntityComponent
@@ -27,7 +27,7 @@ namespace Svelto.ECS
}

//it's an internal interface
public void FillFromByteArray(EntityComponentInitializer init, NativeBag buffer)
public void FillFromByteArray(EntityInitializer init, NativeBag buffer)
{
var component = buffer.Dequeue<T>();


+ 27
- 0
Svelto.ECS/Core/Groups/ExclusiveBuildGroup.cs View File

@@ -0,0 +1,27 @@
namespace Svelto.ECS
{
public readonly struct ExclusiveBuildGroup
{
internal ExclusiveBuildGroup(ExclusiveGroupStruct group)
{
this.group = group;
}

public static implicit operator ExclusiveBuildGroup(ExclusiveGroupStruct group)
{
return new ExclusiveBuildGroup(group);
}

public static implicit operator ExclusiveBuildGroup(ExclusiveGroup group)
{
return new ExclusiveBuildGroup(group);
}
public static implicit operator uint(ExclusiveBuildGroup groupStruct)
{
return groupStruct.group;
}

internal ExclusiveGroupStruct @group { get; }
}
}

Svelto.ECS/ExclusiveGroup.cs → Svelto.ECS/Core/Groups/ExclusiveGroup.cs View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

#pragma warning disable 660,661


Svelto.ECS/ExclusiveGroupStruct.cs → Svelto.ECS/Core/Groups/ExclusiveGroupStruct.cs View File

@@ -4,31 +4,6 @@ using System.Runtime.InteropServices;

namespace Svelto.ECS
{
public readonly struct BuildGroup
{
internal BuildGroup(ExclusiveGroupStruct group)
{
this.group = group;
}

public static implicit operator BuildGroup(ExclusiveGroupStruct group)
{
return new BuildGroup(group);
}

public static implicit operator BuildGroup(ExclusiveGroup group)
{
return new BuildGroup(group);
}
public static implicit operator uint(BuildGroup groupStruct)
{
return groupStruct.group;
}

internal ExclusiveGroupStruct @group { get; }
}
[StructLayout(LayoutKind.Explicit, Size = 4)]
public struct ExclusiveGroupStruct : IEquatable<ExclusiveGroupStruct>, IComparable<ExclusiveGroupStruct>,
IEqualityComparer<ExclusiveGroupStruct>

Svelto.ECS/GroupCompound.cs → Svelto.ECS/Core/Groups/GroupCompound.cs View File

@@ -20,7 +20,7 @@ namespace Svelto.ECS
static readonly FasterList<ExclusiveGroupStruct> _Groups;
public static FasterReadOnlyList<ExclusiveGroupStruct> Groups => new FasterReadOnlyList<ExclusiveGroupStruct>(_Groups);
public static BuildGroup BuildGroup => new BuildGroup(_Groups[0]);
public static ExclusiveBuildGroup BuildGroup => new ExclusiveBuildGroup(_Groups[0]);
static GroupCompound()
{
@@ -100,7 +100,7 @@ namespace Svelto.ECS
public static FasterReadOnlyList<ExclusiveGroupStruct> Groups =>
new FasterReadOnlyList<ExclusiveGroupStruct>(_Groups);
public static BuildGroup BuildGroup => new BuildGroup(_Groups[0]);
public static ExclusiveBuildGroup BuildGroup => new ExclusiveBuildGroup(_Groups[0]);
public static void Add(ExclusiveGroupStruct group)
{
@@ -152,7 +152,7 @@ namespace Svelto.ECS
public static FasterReadOnlyList<ExclusiveGroupStruct> Groups =>
new FasterReadOnlyList<ExclusiveGroupStruct>(_Groups);
public static BuildGroup BuildGroup => new BuildGroup(_Groups[0]);
public static ExclusiveBuildGroup BuildGroup => new ExclusiveBuildGroup(_Groups[0]);
public static void Add(ExclusiveGroupStruct group)
{
@@ -200,7 +200,7 @@ namespace Svelto.ECS
public static FasterReadOnlyList<ExclusiveGroupStruct> Groups =>
new FasterReadOnlyList<ExclusiveGroupStruct>(_Groups);
public static BuildGroup BuildGroup => new BuildGroup(_Groups[0]);
public static ExclusiveBuildGroup BuildGroup => new ExclusiveBuildGroup(_Groups[0]);
static GroupTag()
{

Svelto.ECS/NamedExclusiveGroup.cs → Svelto.ECS/Core/Groups/NamedExclusiveGroup.cs View File


Svelto.ECS/IEntityDescriptorHolder.cs → Svelto.ECS/Core/Hybrid/IEntityDescriptorHolder.cs View File


Svelto.ECS/Hybrid/IEntityViewComponent.cs → Svelto.ECS/Core/Hybrid/IEntityViewComponent.cs View File


Svelto.ECS/Hybrid/IImplementor.cs → Svelto.ECS/Core/Hybrid/IImplementor.cs View File


+ 13
- 0
Svelto.ECS/Core/Hybrid/ValueReference.cs View File

@@ -0,0 +1,13 @@
using System.Runtime.InteropServices;

namespace Svelto.ECS.Hybrid
{
public struct ValueReference<T> where T:class, IImplementor
{
public ValueReference(T obj) { _pointer = GCHandle.Alloc(obj, GCHandleType.Normal); }

public static explicit operator T(ValueReference<T> t) => (T) t._pointer.Target;

GCHandle _pointer;
}
}

Svelto.ECS/IComponentBuilder.cs → Svelto.ECS/Core/IComponentBuilder.cs View File


Svelto.ECS/IDisposingEngine.cs → Svelto.ECS/Core/IDisposingEngine.cs View File


Svelto.ECS/IEngine.cs → Svelto.ECS/Core/IEngine.cs View File

@@ -7,6 +7,9 @@ namespace Svelto.ECS.Internal
public interface IReactOnAddAndRemove : IReactEngine
{}
public interface IReactOnDispose : IReactEngine
{}

public interface IReactOnSwap : IReactEngine
{}
@@ -23,6 +26,11 @@ namespace Svelto.ECS
void Remove(ref T entityComponent, EGID egid);
}
public interface IReactOnDispose<T> : IReactOnDispose where T : IEntityComponent
{
void Remove(ref T entityComponent, EGID egid);
}
public interface IReactOnSwap<T> : IReactOnSwap where T : IEntityComponent
{
void MovedTo(ref T entityComponent, ExclusiveGroupStruct previousGroup, EGID egid);

+ 7
- 0
Svelto.ECS/Core/IEntityComponent.cs View File

@@ -0,0 +1,7 @@
namespace Svelto.ECS
{
///<summary>Entity Components MUST implement IEntityComponent</summary>
public interface IEntityComponent
{
}
}

Svelto.ECS/IEntityFactory.cs → Svelto.ECS/Core/IEntityFactory.cs View File

@@ -43,25 +43,25 @@ namespace Svelto.ECS
/// <param name="groupStructId"></param>
/// <param name="ed"></param>
/// <param name="implementors"></param>
EntityComponentInitializer BuildEntity<T>(uint entityID, BuildGroup groupStructId,
EntityInitializer BuildEntity<T>(uint entityID, ExclusiveBuildGroup groupStructId,
IEnumerable<object> implementors = null)
where T : IEntityDescriptor, new();

EntityComponentInitializer BuildEntity<T>(EGID egid, IEnumerable<object> implementors = null)
EntityInitializer BuildEntity<T>(EGID egid, IEnumerable<object> implementors = null)
where T : IEntityDescriptor, new();

EntityComponentInitializer BuildEntity<T>(uint entityID, BuildGroup groupStructId,
EntityInitializer BuildEntity<T>(uint entityID, ExclusiveBuildGroup groupStructId,
T descriptorEntity, IEnumerable<object> implementors = null)
where T : IEntityDescriptor;

EntityComponentInitializer BuildEntity<T>(EGID egid, T entityDescriptor, IEnumerable<object> implementors = null)
EntityInitializer BuildEntity<T>(EGID egid, T entityDescriptor, IEnumerable<object> implementors = null)
where T : IEntityDescriptor;

EntityComponentInitializer BuildEntity
EntityInitializer BuildEntity
(EGID egid, IComponentBuilder[] componentsToBuild, Type type, IEnumerable<object> implementors = null);

#if UNITY_NATIVE
NativeEntityFactory ToNative<T>(string memberName) where T : IEntityDescriptor, new();
NativeEntityFactory ToNative<T>(string callerName) where T : IEntityDescriptor, new();
#endif
}
}

+ 34
- 0
Svelto.ECS/Core/IEntityFunctions.cs View File

@@ -0,0 +1,34 @@
using System.Runtime.CompilerServices;

namespace Svelto.ECS
{
public interface IEntityFunctions
{
//being entity ID globally not unique, the group must be specified when
//an entity is removed. Not specifying the group will attempt to remove
//the entity from the special standard group.
void RemoveEntity<T>(uint entityID, ExclusiveBuildGroup groupID, [CallerMemberName] string memberName = "") where T : IEntityDescriptor, new();
void RemoveEntity<T>(EGID entityegid, [CallerMemberName] string memberName = "") where T : IEntityDescriptor, new();
void RemoveEntitiesFromGroup(ExclusiveBuildGroup groupID);

void SwapEntitiesInGroup<T>(ExclusiveBuildGroup fromGroupID, ExclusiveBuildGroup toGroupID) where T : IEntityDescriptor, new();

void SwapEntityGroup<T>(uint entityID, ExclusiveBuildGroup fromGroupID, ExclusiveBuildGroup toGroupID)
where T : IEntityDescriptor, new();

void SwapEntityGroup<T>(EGID fromID, ExclusiveBuildGroup toGroupID) where T : IEntityDescriptor, new();

void SwapEntityGroup<T>(EGID fromID, ExclusiveBuildGroup toGroupID, ExclusiveBuildGroup mustBeFromGroup)
where T : IEntityDescriptor, new();

void SwapEntityGroup<T>(EGID fromID, EGID toId) where T : IEntityDescriptor, new();

void SwapEntityGroup<T>(EGID fromID, EGID toId, ExclusiveBuildGroup mustBeFromGroup)
where T : IEntityDescriptor, new();
#if UNITY_NATIVE
NativeEntityRemove ToNativeRemove<T>(string memberName) where T : IEntityDescriptor, new();
NativeEntitySwap ToNativeSwap<T>(string memberName) where T : IEntityDescriptor, new();
#endif
}
}

Svelto.ECS/IEntityComponent.cs → Svelto.ECS/Core/INeedEGID.cs View File

@@ -1,10 +1,5 @@
namespace Svelto.ECS
{
///<summary>Entity Components MUST implement IEntityComponent</summary>
public interface IEntityComponent
{
}

/// <summary>
/// use INeedEGID on an IEntityComponent only if you need the EGID. consider using EGIDComponent instead
/// </summary>

Svelto.ECS/IQueryingEntitiesEngine.cs → Svelto.ECS/Core/IQueryingEntitiesEngine.cs View File


Svelto.ECS/QueryGroups.cs → Svelto.ECS/Core/QueryGroups.cs View File


Svelto.ECS/SetEGIDWithoutBoxing.cs → Svelto.ECS/Core/SetEGIDWithoutBoxing.cs View File

@@ -1,5 +1,3 @@
using System.Runtime.CompilerServices;

namespace Svelto.ECS.Internal
{
delegate void SetEGIDWithoutBoxingActionCast<T>(ref T target, EGID egid) where T : struct, IEntityComponent;

+ 47
- 0
Svelto.ECS/Core/SimpleEntitiesSubmissionScheduler.cs View File

@@ -0,0 +1,47 @@
using System;
using System.Collections;

namespace Svelto.ECS.Schedulers
{
public sealed class SimpleEntitiesSubmissionScheduler : EntitiesSubmissionScheduler
{
public SimpleEntitiesSubmissionScheduler(uint maxNumberOfOperationsPerFrame = UInt32.MaxValue)
{
_maxNumberOfOperationsPerFrame = maxNumberOfOperationsPerFrame;
}
public IEnumerator SubmitEntitiesAsync()
{
if (paused == false)
{
var submitEntities = _onTick.Invoke(_maxNumberOfOperationsPerFrame);
while (submitEntities.MoveNext())
yield return null;
}
}

public void SubmitEntities()
{
var enumerator = SubmitEntitiesAsync();

while (enumerator.MoveNext());
}

public override bool paused { get; set; }
public override void Dispose() { }

protected internal override EnginesRoot.EntitiesSubmitter onTick
{
set
{
DBC.ECS.Check.Require(_onTick.IsUnused, "a scheduler can be exclusively used by one enginesRoot only");
_onTick = value;
}
}

EnginesRoot.EntitiesSubmitter _onTick;
readonly uint _maxNumberOfOperationsPerFrame;
}
}

+ 546
- 0
Svelto.ECS/Core/SpecialEnumerators/DoubleIterationEnumerator.cs View File

@@ -0,0 +1,546 @@
using System;

namespace Svelto.ECS
{
public readonly ref struct DoubleEntitiesEnumerator<T1> where T1 : struct, IEntityComponent
{
public DoubleEntitiesEnumerator(GroupsEnumerable<T1> groupsEnumerable) { _groupsEnumerable = groupsEnumerable; }

public EntityGroupsIterator GetEnumerator() { return new EntityGroupsIterator(_groupsEnumerable); }

readonly GroupsEnumerable<T1> _groupsEnumerable;

public ref struct EntityGroupsIterator
{
public EntityGroupsIterator(GroupsEnumerable<T1> groupsEnumerable) : this()
{
_groupsEnumerableA = groupsEnumerable.GetEnumerator();
_groupsEnumerableA.MoveNext();
_groupsEnumerableB = _groupsEnumerableA;
_indexA = 0;
_indexB = 0;
}

public bool MoveNext()
{
//once GroupEnumerables complete, they reset. If they reset and moveNext doesn't happen, they are invalid
while (_groupsEnumerableA.isValid)
{
var (buffersA, _) = _groupsEnumerableA.Current;
var (buffersB, _) = _groupsEnumerableB.Current;

//current index A must iterate as long as is less than the current A group count
while (_indexA < buffersA.count)
{
//current index B must iterate as long as is less than the current B group count
if (++_indexB < buffersB.count)
{
return true;
}

//if B iteration is over, move to the next group
if (_groupsEnumerableB.MoveNext() == false)
{
//if there is no valid next groups, we reset B and we need to move to the next A element
_groupsEnumerableB = _groupsEnumerableA;
(buffersB, _) = _groupsEnumerableB.Current;
++_indexA; //next A element
_indexB = _indexA;
}
else
//otherwise the current A will be checked against the new B group. IndexB must be reset
//to work on the new group
{
_indexB = -1;
}
}

//the current group A iteration is done, so we move to the next A group
if (_groupsEnumerableA.MoveNext() == true)
{
//there is a new group, we reset the iteration
_indexA = 0;
_indexB = 0;
_groupsEnumerableB = _groupsEnumerableA;
}
else
return false;
}

return false;
}

public void Reset() { throw new Exception(); }

public ValueRef Current
{
get
{
var valueRef = new ValueRef(_groupsEnumerableA.Current, _indexA, _groupsEnumerableB.Current
, _indexB);
return valueRef;
}
}

public void Dispose() { }

GroupsEnumerable<T1>.GroupsIterator _groupsEnumerableA;
GroupsEnumerable<T1>.GroupsIterator _groupsEnumerableB;
int _indexA;
int _indexB;
}

public ref struct ValueRef
{
public readonly GroupsEnumerable<T1>.RefCurrent _current;
public readonly int _indexA;
public readonly GroupsEnumerable<T1>.RefCurrent _refCurrent;
public readonly int _indexB;

public ValueRef
(GroupsEnumerable<T1>.RefCurrent current, int indexA, GroupsEnumerable<T1>.RefCurrent refCurrent
, int indexB)
{
_current = current;
_indexA = indexA;
_refCurrent = refCurrent;
_indexB = indexB;
}

public void Deconstruct
(out EntityCollection<T1> buffers, out int indexA, out EntityCollection<T1> refCurrent, out int indexB)
{
buffers = _current._buffers;
indexA = _indexA;
refCurrent = _refCurrent._buffers;
indexB = _indexB;
}

public void Deconstruct
(out EntityCollection<T1> buffers, out int indexA, out ExclusiveGroupStruct groupA
, out EntityCollection<T1> refCurrent, out int indexB, out ExclusiveGroupStruct groupB)
{
buffers = _current._buffers;
indexA = _indexA;
refCurrent = _refCurrent._buffers;
indexB = _indexB;
groupA = _current._group;
groupB = _refCurrent._group;
}
}
}

public readonly ref struct DoubleIterationEnumerator<T1, T2> where T1 : struct, IEntityComponent
where T2 : struct, IEntityComponent
{
public DoubleIterationEnumerator(GroupsEnumerable<T1, T2> groupsEnumerable)
{
_groupsEnumerable = groupsEnumerable;
}

public EntityGroupsIterator GetEnumerator() { return new EntityGroupsIterator(_groupsEnumerable); }

readonly GroupsEnumerable<T1, T2> _groupsEnumerable;

public ref struct EntityGroupsIterator
{
public EntityGroupsIterator(GroupsEnumerable<T1, T2> groupsEnumerable) : this()
{
_groupsEnumerableA = groupsEnumerable.GetEnumerator();
_groupsEnumerableA.MoveNext();
_groupsEnumerableB = _groupsEnumerableA;
_indexA = 0;
_indexB = 0;
}

public bool MoveNext()
{
//once GroupEnumerables complete, they reset. If they reset and moveNext doesn't happen, they are invalid
while (_groupsEnumerableA.isValid)
{
var (buffersA, _) = _groupsEnumerableA.Current;
var (buffersB, _) = _groupsEnumerableB.Current;

//current index A must iterate as long as is less than the current A group count
while (_indexA < buffersA.count)
{
//current index B must iterate as long as is less than the current B group count
if (++_indexB < buffersB.count)
{
return true;
}

//if B iteration is over, move to the next group
if (_groupsEnumerableB.MoveNext() == false)
{
//if there is no valid next groups, we reset B and we need to move to the next A element
_groupsEnumerableB = _groupsEnumerableA;
(buffersB, _) = _groupsEnumerableB.Current;
++_indexA; //next A element
_indexB = _indexA;
}
else
//otherwise the current A will be checked against the new B group. IndexB must be reset
//to work on the new group
{
_indexB = -1;
}
}

//the current group A iteration is done, so we move to the next A group
if (_groupsEnumerableA.MoveNext() == true)
{
//there is a new group, we reset the iteration
_indexA = 0;
_indexB = 0;
_groupsEnumerableB = _groupsEnumerableA;
}
else
return false;
}

return false;
}

public void Reset() { throw new Exception(); }

public ValueRef Current
{
get
{
var valueRef = new ValueRef(_groupsEnumerableA.Current, _indexA, _groupsEnumerableB.Current
, _indexB);
return valueRef;
}
}

public void Dispose() { }

GroupsEnumerable<T1, T2>.GroupsIterator _groupsEnumerableA;
GroupsEnumerable<T1, T2>.GroupsIterator _groupsEnumerableB;
int _indexA;
int _indexB;
}

public ref struct ValueRef
{
public readonly GroupsEnumerable<T1, T2>.RefCurrent _current;
public readonly int _indexA;
public readonly GroupsEnumerable<T1, T2>.RefCurrent _refCurrent;
public readonly int _indexB;

public ValueRef
(GroupsEnumerable<T1, T2>.RefCurrent current, int indexA, GroupsEnumerable<T1, T2>.RefCurrent refCurrent
, int indexB)
{
_current = current;
_indexA = indexA;
_refCurrent = refCurrent;
_indexB = indexB;
}

public void Deconstruct(out EntityCollection<T1, T2> buffers, out int indexA,
out EntityCollection<T1, T2> refCurrent, out int indexB)
{
buffers = _current._buffers;
indexA = _indexA;
refCurrent = _refCurrent._buffers;
indexB = _indexB;
}

public void Deconstruct
(out EntityCollection<T1, T2> buffers, out int indexA, out ExclusiveGroupStruct groupA
, out EntityCollection<T1, T2> refCurrent, out int indexB, out ExclusiveGroupStruct groupB)
{
buffers = _current._buffers;
indexA = _indexA;
refCurrent = _refCurrent._buffers;
indexB = _indexB;
groupA = _current._group;
groupB = _refCurrent._group;
}
}
}

/// <summary>
/// Special Enumerator to iterate a group of entities against themselves with complexity n*(n+1)/2 (skips already tested couples)
/// </summary>
/// <typeparam name="T1"></typeparam>
/// <typeparam name="T2"></typeparam>
/// <typeparam name="T3"></typeparam>
public readonly ref struct DoubleEntitiesEnumerator<T1, T2, T3> where T1 : struct, IEntityComponent
where T2 : struct, IEntityComponent
where T3 : struct, IEntityComponent
{
public DoubleEntitiesEnumerator(GroupsEnumerable<T1, T2, T3> groupsEnumerable)
{
_groupsEnumerable = groupsEnumerable;
}

public EntityGroupsIterator GetEnumerator() { return new EntityGroupsIterator(_groupsEnumerable); }

readonly GroupsEnumerable<T1, T2, T3> _groupsEnumerable;

public ref struct EntityGroupsIterator
{
public EntityGroupsIterator(GroupsEnumerable<T1, T2, T3> groupsEnumerable) : this()
{
_groupsEnumerableA = groupsEnumerable.GetEnumerator();
_groupsEnumerableA.MoveNext();
_groupsEnumerableB = _groupsEnumerableA;
_indexA = 0;
_indexB = 0;
}

public bool MoveNext()
{
//once GroupEnumerables complete, they reset. If they reset and moveNext doesn't happen, they are invalid
while (_groupsEnumerableA.isValid)
{
var (buffersA, _) = _groupsEnumerableA.Current;
var (buffersB, _) = _groupsEnumerableB.Current;

//current index A must iterate as long as is less than the current A group count
while (_indexA < buffersA.count)
{
//current index B must iterate as long as is less than the current B group count
if (++_indexB < buffersB.count)
{
return true;
}

//if B iteration is over, move to the next group
if (_groupsEnumerableB.MoveNext() == false)
{
//if there is no valid next groups, we reset B and we need to move to the next A element
_groupsEnumerableB = _groupsEnumerableA;
(buffersB, _) = _groupsEnumerableB.Current;
++_indexA; //next A element
_indexB = _indexA;
}
else
//otherwise the current A will be checked against the new B group. IndexB must be reset
//to work on the new group
{
_indexB = -1;
}
}

//the current group A iteration is done, so we move to the next A group
if (_groupsEnumerableA.MoveNext() == true)
{
//there is a new group, we reset the iteration
_indexA = 0;
_indexB = 0;
_groupsEnumerableB = _groupsEnumerableA;
}
else
return false;
}

return false;
}

public void Reset() { throw new Exception(); }

public ValueRef Current
{
get
{
var valueRef = new ValueRef(_groupsEnumerableA.Current, _indexA, _groupsEnumerableB.Current
, _indexB);
return valueRef;
}
}

public void Dispose() { }

GroupsEnumerable<T1, T2, T3>.GroupsIterator _groupsEnumerableA;
GroupsEnumerable<T1, T2, T3>.GroupsIterator _groupsEnumerableB;
int _indexA;
int _indexB;
}

public ref struct ValueRef
{
public readonly GroupsEnumerable<T1, T2, T3>.RefCurrent _current;
public readonly int _indexA;
public readonly GroupsEnumerable<T1, T2, T3>.RefCurrent _refCurrent;
public readonly int _indexB;

public ValueRef
(GroupsEnumerable<T1, T2, T3>.RefCurrent current, int indexA
, GroupsEnumerable<T1, T2, T3>.RefCurrent refCurrent, int indexB)
{
_current = current;
_indexA = indexA;
_refCurrent = refCurrent;
_indexB = indexB;
}

public void Deconstruct
(out EntityCollection<T1, T2, T3> buffers, out int indexA, out EntityCollection<T1, T2, T3> refCurrent
, out int indexB)
{
buffers = _current._buffers;
indexA = _indexA;
refCurrent = _refCurrent._buffers;
indexB = _indexB;
}

public void Deconstruct
(out EntityCollection<T1, T2, T3> buffers, out int indexA, out ExclusiveGroupStruct groupA
, out EntityCollection<T1, T2, T3> refCurrent, out int indexB, out ExclusiveGroupStruct groupB)
{
buffers = _current._buffers;
indexA = _indexA;
refCurrent = _refCurrent._buffers;
indexB = _indexB;
groupA = _current._group;
groupB = _refCurrent._group;
}
}
}

/// <summary>
/// Special Enumerator to iterate a group of entities against themselves with complexity n*(n+1)/2 (skips already tested couples)
/// </summary>
/// <typeparam name="T1"></typeparam>
/// <typeparam name="T2"></typeparam>
/// <typeparam name="T3"></typeparam>
/// <typeparam name="T4"></typeparam>
public readonly ref struct DoubleEntitiesEnumerator<T1, T2, T3, T4> where T1 : struct, IEntityComponent
where T2 : struct, IEntityComponent
where T3 : struct, IEntityComponent
where T4 : struct, IEntityComponent
{
public DoubleEntitiesEnumerator(GroupsEnumerable<T1, T2, T3, T4> groupsEnumerable)
{
_groupsEnumerable = groupsEnumerable;
}

public EntityGroupsIterator GetEnumerator() { return new EntityGroupsIterator(_groupsEnumerable); }

readonly GroupsEnumerable<T1, T2, T3, T4> _groupsEnumerable;

public ref struct EntityGroupsIterator
{
public EntityGroupsIterator(GroupsEnumerable<T1, T2, T3, T4> groupsEnumerable) : this()
{
_groupsEnumerableA = groupsEnumerable.GetEnumerator();
_groupsEnumerableA.MoveNext();
_groupsEnumerableB = _groupsEnumerableA;
_indexA = 0;
_indexB = 0;
}

public bool MoveNext()
{
//once GroupEnumerables complete, they reset. If they reset and moveNext doesn't happen, they are invalid
while (_groupsEnumerableA.isValid)
{
var (buffersA, _) = _groupsEnumerableA.Current;
var (buffersB, _) = _groupsEnumerableB.Current;

//current index A must iterate as long as is less than the current A group count
while (_indexA < buffersA.count)
{
//current index B must iterate as long as is less than the current B group count
if (++_indexB < buffersB.count)
{
return true;
}

//if B iteration is over, move to the next group
if (_groupsEnumerableB.MoveNext() == false)
{
//if there is no valid next groups, we reset B and we need to move to the next A element
_groupsEnumerableB = _groupsEnumerableA;
(buffersB, _) = _groupsEnumerableB.Current;
++_indexA; //next A element
_indexB = _indexA;
}
else
//otherwise the current A will be checked against the new B group. IndexB must be reset
//to work on the new group
{
_indexB = -1;
}
}

//the current group A iteration is done, so we move to the next A group
if (_groupsEnumerableA.MoveNext() == true)
{
//there is a new group, we reset the iteration
_indexA = 0;
_indexB = 0;
_groupsEnumerableB = _groupsEnumerableA;
}
else
return false;
}

return false;
}

public void Reset() { throw new Exception(); }

public ValueRef Current
{
get
{
var valueRef = new ValueRef(_groupsEnumerableA.Current, _indexA, _groupsEnumerableB.Current
, _indexB);
return valueRef;
}
}

public void Dispose() { }

GroupsEnumerable<T1, T2, T3, T4>.GroupsIterator _groupsEnumerableA;
GroupsEnumerable<T1, T2, T3, T4>.GroupsIterator _groupsEnumerableB;
int _indexA;
int _indexB;
}

public ref struct ValueRef
{
public readonly GroupsEnumerable<T1, T2, T3, T4>.RefCurrent _current;
public readonly int _indexA;
public readonly GroupsEnumerable<T1, T2, T3, T4>.RefCurrent _refCurrent;
public readonly int _indexB;

public ValueRef
(GroupsEnumerable<T1, T2, T3, T4>.RefCurrent current, int indexA
, GroupsEnumerable<T1, T2, T3, T4>.RefCurrent refCurrent, int indexB)
{
_current = current;
_indexA = indexA;
_refCurrent = refCurrent;
_indexB = indexB;
}

public void Deconstruct
(out EntityCollection<T1, T2, T3, T4> buffers, out int indexA, out EntityCollection<T1, T2, T3, T4> refCurrent
, out int indexB)
{
buffers = _current._buffers;
indexA = _indexA;
refCurrent = _refCurrent._buffers;
indexB = _indexB;
}

public void Deconstruct
(out EntityCollection<T1, T2, T3, T4> buffers, out int indexA, out ExclusiveGroupStruct groupA
, out EntityCollection<T1, T2, T3, T4> refCurrent, out int indexB, out ExclusiveGroupStruct groupB)
{
buffers = _current._buffers;
indexA = _indexA;
refCurrent = _refCurrent._buffers;
indexB = _indexB;
groupA = _current._group;
groupB = _refCurrent._group;
}
}
}
}

+ 48
- 0
Svelto.ECS/Core/SpecialEnumerators/WaitForSubmissionEnumerator.cs View File

@@ -0,0 +1,48 @@
using System;
using System.Collections;
using Svelto.ECS.Schedulers;

namespace Svelto.ECS
{
/// <summary>
/// Enumerator that yields until the next Entities Submission
/// </summary>
public struct WaitForSubmissionEnumerator : IEnumerator
{
public WaitForSubmissionEnumerator(EntitiesSubmissionScheduler scheduler):this()
{
_scheduler = scheduler;
}
public bool MoveNext()
{
switch (_state)
{
case 0:
_iteration = _scheduler.iteration;
_state = 1;
return true;
case 1:
if (_iteration != _scheduler.iteration)
{
_state = 0;
return false;
}
return true;
}

throw new Exception("something is wrong");
}

void IEnumerator.Reset()
{
throw new NotImplementedException();
}

public object Current { get; }

readonly EntitiesSubmissionScheduler _scheduler;
uint _state;
uint _iteration;
}
}

Svelto.ECS/Streams/Consumer.cs → Svelto.ECS/Core/Streams/Consumer.cs View File


Svelto.ECS/Streams/EnginesRoot.Streams.cs → Svelto.ECS/Core/Streams/EnginesRoot.Streams.cs View File


Svelto.ECS/Streams/EntitiesDB.Streams.cs → Svelto.ECS/Core/Streams/EntitiesDB.Streams.cs View File

@@ -1,5 +1,4 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.CompilerServices;

namespace Svelto.ECS
{

Svelto.ECS/Streams/EntitiesStreams.cs → Svelto.ECS/Core/Streams/EntitiesStreams.cs View File


Svelto.ECS/Streams/EntityStream.cs → Svelto.ECS/Core/Streams/EntityStream.cs View File


Svelto.ECS/Streams/GenericentityStreamConsumerFactory.cs → Svelto.ECS/Core/Streams/GenericentityStreamConsumerFactory.cs View File


Svelto.ECS/Streams/ThreadSafeNativeEntityStream.cs → Svelto.ECS/Core/Streams/ThreadSafeNativeEntityStream.cs View File


Svelto.ECS/TypeSafeDictionaryFactory.cs → Svelto.ECS/Core/TypeSafeDictionaryFactory.cs View File


+ 10
- 8
Svelto.ECS/DataStructures/TypeSafeDictionary.cs View File

@@ -15,21 +15,21 @@ namespace Svelto.ECS.Internal
internal static readonly bool IsUnmanaged =
_type.IsUnmanagedEx() && (typeof(IEntityViewComponent).IsAssignableFrom(_type) == false);

SveltoDictionary<uint, TValue, NativeStrategy<FasterDictionaryNode<uint>>, ManagedStrategy<TValue>,
SveltoDictionary<uint, TValue, NativeStrategy<SveltoDictionaryNode<uint>>, ManagedStrategy<TValue>,
ManagedStrategy<int>> implMgd;

//used directly by native methods
internal SveltoDictionary<uint, TValue, NativeStrategy<FasterDictionaryNode<uint>>, NativeStrategy<TValue>,
internal SveltoDictionary<uint, TValue, NativeStrategy<SveltoDictionaryNode<uint>>, NativeStrategy<TValue>,
NativeStrategy<int>> implUnmgd;

public TypeSafeDictionary(uint size)
{
if (IsUnmanaged)
implUnmgd = new SveltoDictionary<uint, TValue, NativeStrategy<FasterDictionaryNode<uint>>,
implUnmgd = new SveltoDictionary<uint, TValue, NativeStrategy<SveltoDictionaryNode<uint>>,
NativeStrategy<TValue>, NativeStrategy<int>>(size);
else
{
implMgd = new SveltoDictionary<uint, TValue, NativeStrategy<FasterDictionaryNode<uint>>,
implMgd = new SveltoDictionary<uint, TValue, NativeStrategy<SveltoDictionaryNode<uint>>,
ManagedStrategy<TValue>, ManagedStrategy<int>>(size);
}
}
@@ -106,8 +106,9 @@ namespace Svelto.ECS.Internal

//this can be optimized, should pass all the entities and not restart the process for each one
foreach (var value in implUnmgd)
ExecuteEnginesAddOrSwapCallbacksOnSingleEntity(entityComponentEnginesDB, ref typeSafeDictionary[value.Key]
, fromGroup, in profiler, new EGID(value.Key, toGroup));
ExecuteEnginesAddOrSwapCallbacksOnSingleEntity(entityComponentEnginesDB
, ref typeSafeDictionary[value.Key], fromGroup
, in profiler, new EGID(value.Key, toGroup));
}
else
{
@@ -115,8 +116,9 @@ namespace Svelto.ECS.Internal

//this can be optimized, should pass all the entities and not restart the process for each one
foreach (var value in implMgd)
ExecuteEnginesAddOrSwapCallbacksOnSingleEntity(entityComponentEnginesDB, ref typeSafeDictionary[value.Key]
, fromGroup, in profiler, new EGID(value.Key, toGroup));
ExecuteEnginesAddOrSwapCallbacksOnSingleEntity(entityComponentEnginesDB
, ref typeSafeDictionary[value.Key], fromGroup
, in profiler, new EGID(value.Key, toGroup));
}
}



+ 0
- 1
Svelto.ECS/DataStructures/Unmanaged/NativeBag.cs View File

@@ -9,7 +9,6 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
using Svelto.Common;

namespace Svelto.ECS.DataStructures


+ 5
- 1
Svelto.ECS/DataStructures/Unmanaged/NativeDynamicArrayCast.cs View File

@@ -9,7 +9,11 @@ namespace Svelto.ECS.DataStructures
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Count() => _array.Count<T>();

public int count => _array.Count<T>();
public int count
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _array.Count<T>();
}

public ref T this[int index]
{


+ 0
- 1
Svelto.ECS/DataStructures/Unmanaged/SharedNativeInt.cs View File

@@ -1,5 +1,4 @@
using System;
using System.Runtime.InteropServices;
using System.Threading;
using Svelto.Common;



+ 3
- 1
Svelto.ECS/Dispatcher/DispatchOnChange.cs View File

@@ -8,7 +8,9 @@ namespace Svelto.ECS
{
_value = initialValue;
}

public DispatchOnChange(EGID senderID, Action<EGID, T> callback) : base(senderID, callback) {}

public new T value
{
set


+ 13
- 12
Svelto.ECS/Dispatcher/DispatchOnSet.cs View File

@@ -4,11 +4,12 @@ namespace Svelto.ECS
{
public class DispatchOnSet<T>
{
public DispatchOnSet(EGID senderID)
{
_senderID = senderID;
public DispatchOnSet(EGID senderID, Action<EGID, T> callback):this(senderID)
{
NotifyOnValueSet(callback);
}
public DispatchOnSet(EGID senderID) { _senderID = senderID; }

public T value
{
set
@@ -19,29 +20,29 @@ namespace Svelto.ECS
_subscriber(_senderID, value);
}
}
public void NotifyOnValueSet(Action<EGID, T> action)
{
#if DEBUG && !PROFILE_SVELTO
DBC.ECS.Check.Require(_subscriber == null, $"{this.GetType().Name}: listener already registered");
DBC.ECS.Check.Require(_subscriber == null, $"{this.GetType().Name}: listener already registered");
#endif
_subscriber = action;
_paused = false;
_paused = false;
}

public void StopNotify()
{
_subscriber = null;
_paused = true;
_paused = true;
}

public void PauseNotify() { _paused = true; }
public void PauseNotify() { _paused = true; }
public void ResumeNotify() { _paused = false; }

protected T _value;
readonly EGID _senderID;
protected T _value;
readonly EGID _senderID;

Action<EGID, T> _subscriber;
bool _paused;
}
}
}

+ 0
- 21
Svelto.ECS/EntitySubmissionScheduler.cs View File

@@ -1,21 +0,0 @@
using System;

namespace Svelto.ECS.Schedulers
{
public interface IEntitiesSubmissionScheduler: IDisposable
{
bool paused { get; set; }
}
public abstract class EntitiesSubmissionScheduler: IEntitiesSubmissionScheduler
{
protected internal abstract EnginesRoot.EntitiesSubmitter onTick { set; }
public abstract void Dispose();
public abstract bool paused { get; set; }
}
public abstract class ISimpleEntitiesSubmissionScheduler: EntitiesSubmissionScheduler
{
public abstract void SubmitEntities();
}
}

+ 16
- 18
Svelto.ECS/Extensions/Svelto/AllGroupsEnumerable.cs View File

@@ -19,15 +19,12 @@ namespace Svelto.ECS
public void Deconstruct(out EntityCollection<T1> collection, out ExclusiveGroupStruct group)
{
collection = this.collection;
group = this.@group;
group = this.@group;
}
}
public AllGroupsEnumerable(EntitiesDB db)
{
_db = db;
}

public AllGroupsEnumerable(EntitiesDB db) { _db = db; }

public ref struct GroupsIterator
{
public GroupsIterator(EntitiesDB db) : this()
@@ -40,13 +37,14 @@ namespace Svelto.ECS
//attention, the while is necessary to skip empty groups
while (_db.MoveNext() == true)
{
FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>.KeyValuePairFast group = _db.Current;
var group = _db.Current;
ITypeSafeDictionary<T1> typeSafeDictionary = @group.Value as ITypeSafeDictionary<T1>;
if (typeSafeDictionary.count == 0) continue;

if (typeSafeDictionary.count == 0)
continue;

_array.collection = new EntityCollection<T1>(typeSafeDictionary.GetValues(out var count), count);
_array.@group = new ExclusiveGroupStruct(group.Key);
_array.@group = new ExclusiveGroupStruct(group.Key);

return true;
}
@@ -56,15 +54,15 @@ namespace Svelto.ECS

public GroupCollection Current => _array;

FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>.FasterDictionaryKeyValueEnumerator _db;
SveltoDictionary<ExclusiveGroupStruct, ITypeSafeDictionary,
ManagedStrategy<SveltoDictionaryNode<ExclusiveGroupStruct>>, ManagedStrategy<ITypeSafeDictionary>,
ManagedStrategy<int>>.SveltoDictionaryKeyValueEnumerator _db;

GroupCollection _array;
}

public GroupsIterator GetEnumerator()
{
return new GroupsIterator(_db);
}
public GroupsIterator GetEnumerator() { return new GroupsIterator(_db); }

readonly EntitiesDB _db;
readonly EntitiesDB _db;
}
}
}

+ 14
- 15
Svelto.ECS/Extensions/Svelto/EntityCollectionExtension.cs View File

@@ -1,4 +1,3 @@
using System;
using System.Runtime.CompilerServices;
using Svelto.DataStructures;
using Svelto.ECS.Hybrid;
@@ -46,10 +45,10 @@ namespace Svelto.ECS
where T3 : unmanaged, IEntityComponent
where T4 : unmanaged, IEntityComponent
{
buffer1 = ec.Item1._nativedBuffer;
buffer2 = ec.Item2._nativedBuffer;
buffer3 = ec.Item3._nativedBuffer;
buffer4 = ec.Item4._nativedBuffer;
buffer1 = ec.buffer1._nativedBuffer;
buffer2 = ec.buffer2._nativedBuffer;
buffer3 = ec.buffer3._nativedBuffer;
buffer4 = ec.buffer4._nativedBuffer;
count = (int) ec.count;
}

@@ -188,10 +187,10 @@ namespace Svelto.ECS
where T3 : unmanaged, IEntityComponent
where T4 : struct, IEntityViewComponent
{
buffer1 = ec.Item1._nativedBuffer;
buffer2 = ec.Item2._nativedBuffer;
buffer3 = ec.Item3._nativedBuffer;
buffer4 = ec.Item4._managedBuffer;
buffer1 = ec.buffer1._nativedBuffer;
buffer2 = ec.buffer2._nativedBuffer;
buffer3 = ec.buffer3._nativedBuffer;
buffer4 = ec.buffer4._managedBuffer;
count = (int) ec.count;
}
}
@@ -229,8 +228,8 @@ namespace Svelto.ECS
where T3 : unmanaged, IEntityComponent
where T4 : unmanaged, IEntityComponent
{
return new BT<NB<T1>, NB<T2>, NB<T3>, NB<T4>>(ec.Item1._nativedBuffer, ec.Item2._nativedBuffer
, ec.Item3._nativedBuffer, ec.Item4._nativedBuffer, ec.count);
return new BT<NB<T1>, NB<T2>, NB<T3>, NB<T4>>(ec.buffer1._nativedBuffer, ec.buffer2._nativedBuffer
, ec.buffer3._nativedBuffer, ec.buffer4._nativedBuffer, ec.count);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -241,10 +240,10 @@ namespace Svelto.ECS
where T3 : struct, IEntityViewComponent
where T4 : struct, IEntityViewComponent
{
buffer1 = ec.Item1._nativedBuffer;
buffer2 = ec.Item2._nativedBuffer;
buffer3 = ec.Item3._managedBuffer;
buffer4 = ec.Item4._managedBuffer;
buffer1 = ec.buffer1._nativedBuffer;
buffer2 = ec.buffer2._nativedBuffer;
buffer3 = ec.buffer3._managedBuffer;
buffer4 = ec.buffer4._managedBuffer;
count = (int) ec.count;
}
}

+ 84
- 79
Svelto.ECS/Extensions/Svelto/GroupsEnumerable.cs View File

@@ -17,9 +17,6 @@ namespace Svelto.ECS
where T3 : struct, IEntityComponent
where T4 : struct, IEntityComponent
{
readonly EntitiesDB _db;
readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;

public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups)
{
_db = db;
@@ -52,7 +49,8 @@ namespace Svelto.ECS

var array = entityCollection1;
var array2 = entityCollection2;
_buffers = new EntityCollection<T1, T2, T3, T4>(array.buffer1, array.buffer2, array.buffer3, array2);
_buffers = new EntityCollection<T1, T2, T3, T4>(array.buffer1, array.buffer2, array.buffer3
, array2);
break;
}

@@ -66,7 +64,8 @@ namespace Svelto.ECS

public void Reset() { _indexGroup = -1; }

public RefCurrent<T1, T2, T3, T4> Current => new RefCurrent<T1, T2, T3, T4>(_buffers, _groups[_indexGroup]);
public RefCurrent Current => new RefCurrent(_buffers, _groups[_indexGroup]);
public bool isValid => _indexGroup != -1;

readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;

@@ -76,44 +75,36 @@ namespace Svelto.ECS
}

public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); }
}

public ref struct RefCurrent<T1, T2, T3, T4> where T1 : struct, IEntityComponent
where T2 : struct, IEntityComponent
where T3 : struct, IEntityComponent
where T4 : struct, IEntityComponent
{
public RefCurrent(in EntityCollection<T1, T2, T3, T4> buffers, ExclusiveGroupStruct group)
{
_buffers = buffers;
_group = group;
}
readonly EntitiesDB _db;
readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;

public void Deconstruct(out EntityCollection<T1, T2, T3, T4> buffers, out ExclusiveGroupStruct group)
public ref struct RefCurrent
{
buffers = _buffers;
group = _group;
}
public RefCurrent(in EntityCollection<T1, T2, T3, T4> buffers, ExclusiveGroupStruct group)
{
_buffers = buffers;
_group = group;
}

public readonly EntityCollection<T1, T2, T3, T4> _buffers;
public readonly ExclusiveGroupStruct _group;
public void Deconstruct(out EntityCollection<T1, T2, T3, T4> buffers, out ExclusiveGroupStruct group)
{
buffers = _buffers;
group = _group;
}

public readonly EntityCollection<T1, T2, T3, T4> _buffers;
public readonly ExclusiveGroupStruct _group;
}
}

/// <summary>
/// ToDo source gen could return the implementation of IBuffer directly, but cannot be done manually
/// </summary>
/// <typeparam name="T1"></typeparam>
/// <typeparam name="T2"></typeparam>
/// <typeparam name="T3"></typeparam>
public readonly ref struct GroupsEnumerable<T1, T2, T3> where T1 : struct, IEntityComponent
where T2 : struct, IEntityComponent
where T3 : struct, IEntityComponent
{
readonly EntitiesDB _db;
readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;

public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups)
{
DBC.ECS.Check.Require(groups.count > 0, "can't initialise a query without valid groups");
_db = db;
_groups = groups;
}
@@ -150,7 +141,8 @@ namespace Svelto.ECS

public void Reset() { _indexGroup = -1; }

public RefCurrent<T1, T2, T3> Current => new RefCurrent<T1, T2, T3>(_buffers, _groups[_indexGroup]);
public RefCurrent Current => new RefCurrent(_buffers, _groups[_indexGroup]);
public bool isValid => _indexGroup != -1;

readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;

@@ -160,26 +152,27 @@ namespace Svelto.ECS
}

public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); }
}

public ref struct RefCurrent<T1, T2, T3> where T1 : struct, IEntityComponent
where T2 : struct, IEntityComponent
where T3 : struct, IEntityComponent
{
public RefCurrent(in EntityCollection<T1, T2, T3> buffers, ExclusiveGroupStruct group)
{
_buffers = buffers;
_group = group;
}
readonly EntitiesDB _db;
readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;

public void Deconstruct(out EntityCollection<T1, T2, T3> buffers, out ExclusiveGroupStruct group)
public ref struct RefCurrent
{
buffers = _buffers;
group = _group;
}
public RefCurrent(in EntityCollection<T1, T2, T3> buffers, ExclusiveGroupStruct group)
{
_buffers = buffers;
_group = group;
}

public void Deconstruct(out EntityCollection<T1, T2, T3> buffers, out ExclusiveGroupStruct group)
{
buffers = _buffers;
group = _group;
}

public readonly EntityCollection<T1, T2, T3> _buffers;
public readonly ExclusiveGroupStruct _group;
public readonly EntityCollection<T1, T2, T3> _buffers;
public readonly ExclusiveGroupStruct _group;
}
}

public readonly ref struct GroupsEnumerable<T1, T2>
@@ -223,7 +216,8 @@ namespace Svelto.ECS

public void Reset() { _indexGroup = -1; }

public RefCurrent<T1, T2> Current => new RefCurrent<T1, T2>(_buffers, _groups[_indexGroup]);
public RefCurrent Current => new RefCurrent(_buffers, _groups[_indexGroup]);
public bool isValid => _indexGroup != -1;

readonly EntitiesDB _db;
readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
@@ -236,24 +230,24 @@ namespace Svelto.ECS

readonly EntitiesDB _db;
readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
}

public ref struct RefCurrent<T1, T2> where T1 : struct, IEntityComponent where T2 : struct, IEntityComponent
{
public RefCurrent(in EntityCollection<T1, T2> buffers, ExclusiveGroupStruct group)
public ref struct RefCurrent
{
_buffers = buffers;
_group = group;
}
public RefCurrent(in EntityCollection<T1, T2> buffers, ExclusiveGroupStruct group)
{
_buffers = buffers;
_group = group;
}

public void Deconstruct(out EntityCollection<T1, T2> buffers, out ExclusiveGroupStruct group)
{
buffers = _buffers;
group = _group;
}
public void Deconstruct(out EntityCollection<T1, T2> buffers, out ExclusiveGroupStruct group)
{
buffers = _buffers;
group = _group;
}

public readonly EntityCollection<T1, T2> _buffers;
public readonly ExclusiveGroupStruct _group;
public readonly EntityCollection<T1, T2> _buffers;
public readonly ExclusiveGroupStruct _group;
}
}

public readonly ref struct GroupsEnumerable<T1> where T1 : struct, IEntityComponent
@@ -285,13 +279,19 @@ namespace Svelto.ECS
_buffer = entityCollection;
break;
}
var moveNext = _indexGroup < _groups.count;

return _indexGroup < _groups.count;
if (moveNext == false)
Reset();

return moveNext;
}

public void Reset() { _indexGroup = -1; }

public RefCurrent<T1> Current => new RefCurrent<T1>(_buffer, _groups[_indexGroup]);
public RefCurrent Current => new RefCurrent(_buffer, _groups[_indexGroup]);
public bool isValid => _indexGroup != -1;

readonly EntitiesDB _db;
readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
@@ -304,23 +304,28 @@ namespace Svelto.ECS

readonly EntitiesDB _db;
readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
}

public ref struct RefCurrent<T1> where T1 : struct, IEntityComponent
{
public RefCurrent(in EntityCollection<T1> buffers, ExclusiveGroupStruct group)
public readonly ref struct RefCurrent
{
_buffers = buffers;
_group = group;
}
public RefCurrent(in EntityCollection<T1> buffers, in ExclusiveGroupStruct group)
{
_buffers = buffers;
_group = group;
}

public void Deconstruct(out EntityCollection<T1> buffers, out ExclusiveGroupStruct group)
{
buffers = _buffers;
group = _group;
}
public void Deconstruct(out EntityCollection<T1> buffers, out ExclusiveGroupStruct group)
{
buffers = _buffers;
group = _group;
}
public void Deconstruct(out EntityCollection<T1> buffers)
{
buffers = _buffers;
}

public readonly EntityCollection<T1> _buffers;
public readonly ExclusiveGroupStruct _group;
public readonly EntityCollection<T1> _buffers;
public readonly ExclusiveGroupStruct _group;
}
}
}

+ 18
- 0
Svelto.ECS/Extensions/Unity/DOTS/Jobs/IJobifiedEngine.cs View File

@@ -0,0 +1,18 @@
using Unity.Jobs;

namespace Svelto.ECS.Extensions.Unity
{
public interface IJobifiedEngine<T> : IEngine
{
JobHandle Execute(JobHandle inputDeps, ref T _param);
string name { get; }
}

public interface IJobifiedEngine : IEngine
{
JobHandle Execute(JobHandle inputDeps);

string name { get; }
}
}

+ 2
- 16
Svelto.ECS/Extensions/Unity/DOTS/Jobs/JobifiedEnginesGroup.cs View File

@@ -5,20 +5,6 @@ using Unity.Jobs;

namespace Svelto.ECS.Extensions.Unity
{
public interface IJobifiedEngine : IEngine
{
JobHandle Execute(JobHandle inputDeps);
string name { get; }
}
public interface IJobifiedEngine<T> : IEngine
{
JobHandle Execute(JobHandle inputDeps, ref T _param);
string name { get; }
}
public interface IJobifiedGroupEngine<T> : IJobifiedEngine<T>
{ }
/// <summary>
@@ -58,7 +44,7 @@ namespace Svelto.ECS.Extensions.Unity
return combinedHandles;
}

protected internal void Add(Interface engine)
public void Add(Interface engine)
{
_engines.Add(engine);
}
@@ -66,7 +52,7 @@ namespace Svelto.ECS.Extensions.Unity
public string name => _name;

protected readonly FasterList<Interface> _engines;
readonly string _name;
readonly string _name;
}
public abstract class JobifiedEnginesGroup<Interface, Param>: IJobifiedGroupEngine<Param> where Interface : class, IJobifiedEngine<Param>


+ 43
- 36
Svelto.ECS/Extensions/Unity/DOTS/Native/EnginesRoot.NativeOperation.cs View File

@@ -9,30 +9,28 @@ namespace Svelto.ECS
public partial class EnginesRoot
{
//todo: I very likely don't need to create one for each native entity factory, the same can be reused
readonly AtomicNativeBags _addOperationQueue =
new AtomicNativeBags(Common.Allocator.Persistent);
readonly AtomicNativeBags _addOperationQueue = new AtomicNativeBags(Common.Allocator.Persistent);

readonly AtomicNativeBags _removeOperationQueue =
new AtomicNativeBags(Common.Allocator.Persistent);
readonly AtomicNativeBags _removeOperationQueue = new AtomicNativeBags(Common.Allocator.Persistent);

readonly AtomicNativeBags _swapOperationQueue =
new AtomicNativeBags(Common.Allocator.Persistent);
readonly AtomicNativeBags _swapOperationQueue = new AtomicNativeBags(Common.Allocator.Persistent);

NativeEntityRemove ProvideNativeEntityRemoveQueue<T>(string memberName) where T : IEntityDescriptor, new()
{
//todo: remove operation array and store entity descriptor hash in the return value
//todo I maybe able to provide a _nativeSwap.SwapEntity<entityDescriptor>
_nativeRemoveOperations.Add(
new NativeOperationRemove(EntityDescriptorTemplate<T>.descriptor.componentsToBuild, TypeCache<T>.type, memberName));
_nativeRemoveOperations.Add(new NativeOperationRemove(
EntityDescriptorTemplate<T>.descriptor.componentsToBuild, TypeCache<T>.type
, memberName));

return new NativeEntityRemove(_removeOperationQueue, _nativeRemoveOperations.count - 1);
}
NativeEntitySwap ProvideNativeEntitySwapQueue<T>(string memberName) where T : IEntityDescriptor, new()
{
//todo: remove operation array and store entity descriptor hash in the return value
_nativeSwapOperations.Add(
new NativeOperationSwap(EntityDescriptorTemplate<T>.descriptor.componentsToBuild, TypeCache<T>.type, memberName));
_nativeSwapOperations.Add(new NativeOperationSwap(EntityDescriptorTemplate<T>.descriptor.componentsToBuild
, TypeCache<T>.type, memberName));

return new NativeEntitySwap(_swapOperationQueue, _nativeSwapOperations.count - 1);
}
@@ -50,35 +48,41 @@ namespace Svelto.ECS
{
using (profiler.Sample("Native Remove/Swap Operations"))
{
for (int i = 0; i < _removeOperationQueue.count; i++)
var removeBuffersCount = _removeOperationQueue.count;
for (int i = 0; i < removeBuffersCount; i++)
{
ref var buffer = ref _removeOperationQueue.GetBuffer(i);

while (buffer.IsEmpty() == false)
{
var componentsIndex = buffer.Dequeue<uint>();
var entityEGID = buffer.Dequeue<EGID>();
var nativeRemoveOperation = _nativeRemoveOperations[componentsIndex];
CheckRemoveEntityID(entityEGID, nativeRemoveOperation.entityDescriptorType);
var componentsIndex = buffer.Dequeue<uint>();
var entityEGID = buffer.Dequeue<EGID>();
NativeOperationRemove nativeRemoveOperation = _nativeRemoveOperations[componentsIndex];
CheckRemoveEntityID(entityEGID, nativeRemoveOperation.entityDescriptorType
, nativeRemoveOperation.caller);
QueueEntitySubmitOperation(new EntitySubmitOperation(
EntitySubmitOperationType.Remove, entityEGID, entityEGID
, nativeRemoveOperation.components));
}
}

for (int i = 0; i < _swapOperationQueue.count; i++)
var swapBuffersCount = _swapOperationQueue.count;
for (int i = 0; i < swapBuffersCount; i++)
{
ref var buffer = ref _swapOperationQueue.GetBuffer(i);

while (buffer.IsEmpty() == false)
{
var componentsIndex = buffer.Dequeue<uint>();
var componentsIndex = buffer.Dequeue<uint>();
var entityEGID = buffer.Dequeue<DoubleEGID>();
var componentBuilders = _nativeSwapOperations[componentsIndex].components;

CheckRemoveEntityID(entityEGID.@from, _nativeSwapOperations[componentsIndex].entityDescriptorType, _nativeSwapOperations[componentsIndex].caller );
CheckAddEntityID(entityEGID.to, _nativeSwapOperations[componentsIndex].entityDescriptorType, _nativeSwapOperations[componentsIndex].caller);
CheckRemoveEntityID(entityEGID.@from
, _nativeSwapOperations[componentsIndex].entityDescriptorType
, _nativeSwapOperations[componentsIndex].caller);
CheckAddEntityID(entityEGID.to, _nativeSwapOperations[componentsIndex].entityDescriptorType
, _nativeSwapOperations[componentsIndex].caller);

QueueEntitySubmitOperation(new EntitySubmitOperation(
EntitySubmitOperationType.Swap, entityEGID.@from, entityEGID.to
@@ -86,21 +90,22 @@ namespace Svelto.ECS
}
}
}
using (profiler.Sample("Native Add Operations"))
{
for (int i = 0; i < _addOperationQueue.count; i++)
var addBuffersCount = _addOperationQueue.count;
for (int i = 0; i < addBuffersCount; i++)
{
ref var buffer = ref _addOperationQueue.GetBuffer(i);
while (buffer.IsEmpty() == false)
{
var componentsIndex = buffer.Dequeue<uint>();
var egid = buffer.Dequeue<EGID>();
var componentCounts = buffer.Dequeue<uint>();
EntityComponentInitializer init =
BuildEntity(egid, _nativeAddOperations[componentsIndex].components, _nativeAddOperations[componentsIndex].entityDescriptorType);
var init = BuildEntity(egid, _nativeAddOperations[componentsIndex].components
, _nativeAddOperations[componentsIndex].entityDescriptorType);

//only called if Init is called on the initialized (there is something to init)
while (componentCounts > 0)
@@ -146,22 +151,23 @@ namespace Svelto.ECS
readonly struct NativeOperationBuild
{
internal readonly IComponentBuilder[] components;
internal readonly Type entityDescriptorType;
internal readonly Type entityDescriptorType;

public NativeOperationBuild(IComponentBuilder[] descriptorComponentsToBuild, Type entityDescriptorType)
{
this.entityDescriptorType = entityDescriptorType;
components = descriptorComponentsToBuild;
components = descriptorComponentsToBuild;
}
}

readonly struct NativeOperationRemove
{
internal readonly IComponentBuilder[] components;
internal readonly Type entityDescriptorType;
internal readonly string caller;
public NativeOperationRemove(IComponentBuilder[] descriptorComponentsToRemove, Type entityDescriptorType, string caller)
internal readonly Type entityDescriptorType;
internal readonly string caller;

public NativeOperationRemove
(IComponentBuilder[] descriptorComponentsToRemove, Type entityDescriptorType, string caller)
{
this.caller = caller;
components = descriptorComponentsToRemove;
@@ -172,10 +178,11 @@ namespace Svelto.ECS
readonly struct NativeOperationSwap
{
internal readonly IComponentBuilder[] components;
internal readonly Type entityDescriptorType;
internal readonly string caller;
internal readonly Type entityDescriptorType;
internal readonly string caller;

public NativeOperationSwap(IComponentBuilder[] descriptorComponentsToSwap, Type entityDescriptorType, string caller)
public NativeOperationSwap
(IComponentBuilder[] descriptorComponentsToSwap, Type entityDescriptorType, string caller)
{
this.caller = caller;
components = descriptorComponentsToSwap;


+ 6
- 6
Svelto.ECS/Extensions/Unity/DOTS/Native/NativeEGIDMultiMapper.cs View File

@@ -7,24 +7,24 @@ namespace Svelto.ECS
public struct NativeEGIDMultiMapper<T>:IDisposable where T : unmanaged, IEntityComponent
{
SveltoDictionary<ExclusiveGroupStruct, SveltoDictionary<uint, T,
NativeStrategy<FasterDictionaryNode<uint>>,
NativeStrategy<SveltoDictionaryNode<uint>>,
NativeStrategy<T>,
NativeStrategy<int>>,
NativeStrategy<FasterDictionaryNode<ExclusiveGroupStruct>>,
NativeStrategy<SveltoDictionaryNode<ExclusiveGroupStruct>>,
NativeStrategy<SveltoDictionary<uint, T,
NativeStrategy<FasterDictionaryNode<uint>>,
NativeStrategy<SveltoDictionaryNode<uint>>,
NativeStrategy<T>,
NativeStrategy<int>>>,
NativeStrategy<int>> _dic;

public NativeEGIDMultiMapper
(SveltoDictionary<ExclusiveGroupStruct, SveltoDictionary<uint, T,
NativeStrategy<FasterDictionaryNode<uint>>,
NativeStrategy<SveltoDictionaryNode<uint>>,
NativeStrategy<T>,
NativeStrategy<int>>,
NativeStrategy<FasterDictionaryNode<ExclusiveGroupStruct>>,
NativeStrategy<SveltoDictionaryNode<ExclusiveGroupStruct>>,
NativeStrategy<SveltoDictionary<uint, T,
NativeStrategy<FasterDictionaryNode<uint>>,
NativeStrategy<SveltoDictionaryNode<uint>>,
NativeStrategy<T>,
NativeStrategy<int>>>,
NativeStrategy<int>> dictionary)


+ 6
- 6
Svelto.ECS/Extensions/Unity/DOTS/Native/NativeEntityFactory.cs View File

@@ -14,19 +14,19 @@ namespace Svelto.ECS
_addOperationQueue = addOperationQueue;
}

public NativeEntityComponentInitializer BuildEntity
(uint eindex, BuildGroup BuildGroup, int threadIndex)
public NativeEntityInitializer BuildEntity
(uint eindex, ExclusiveBuildGroup exclusiveBuildGroup, int threadIndex)
{
NativeBag unsafeBuffer = _addOperationQueue.GetBuffer(threadIndex + 1);

unsafeBuffer.Enqueue(_index);
unsafeBuffer.Enqueue(new EGID(eindex, BuildGroup));
unsafeBuffer.Enqueue(new EGID(eindex, exclusiveBuildGroup));
unsafeBuffer.ReserveEnqueue<uint>(out var index) = 0;

return new NativeEntityComponentInitializer(unsafeBuffer, index);
return new NativeEntityInitializer(unsafeBuffer, index);
}
public NativeEntityComponentInitializer BuildEntity(EGID egid, int threadIndex)
public NativeEntityInitializer BuildEntity(EGID egid, int threadIndex)
{
NativeBag unsafeBuffer = _addOperationQueue.GetBuffer(threadIndex + 1);

@@ -34,7 +34,7 @@ namespace Svelto.ECS
unsafeBuffer.Enqueue(new EGID(egid.entityID, egid.groupID));
unsafeBuffer.ReserveEnqueue<uint>(out var index) = 0;

return new NativeEntityComponentInitializer(unsafeBuffer, index);
return new NativeEntityInitializer(unsafeBuffer, index);
}
}
}

Svelto.ECS/Extensions/Unity/DOTS/Native/NativeEntityComponentInitializer.cs → Svelto.ECS/Extensions/Unity/DOTS/Native/NativeEntityInitializer.cs View File

@@ -2,12 +2,12 @@ using Svelto.ECS.DataStructures;

namespace Svelto.ECS
{
public readonly ref struct NativeEntityComponentInitializer
public readonly ref struct NativeEntityInitializer
{
readonly NativeBag _unsafeBuffer;
readonly UnsafeArrayIndex _index;

public NativeEntityComponentInitializer(in NativeBag unsafeBuffer, UnsafeArrayIndex index)
public NativeEntityInitializer(in NativeBag unsafeBuffer, UnsafeArrayIndex index)
{
_unsafeBuffer = unsafeBuffer;
_index = index;

+ 1
- 1
Svelto.ECS/Extensions/Unity/DOTS/Native/NativeEntitySwap.cs View File

@@ -22,7 +22,7 @@ namespace Svelto.ECS
}

public void SwapEntity(EGID from, BuildGroup to, int threadIndex)
public void SwapEntity(EGID from, ExclusiveBuildGroup to, int threadIndex)
{
var simpleNativeBag = _swapQueue.GetBuffer(threadIndex);
simpleNativeBag.Enqueue(_indexSwap);


+ 3
- 3
Svelto.ECS/Extensions/Unity/DOTS/Native/UnityEntityDBExtensions.cs View File

@@ -48,12 +48,12 @@ namespace Svelto.ECS
{
var dictionary =
new SveltoDictionary<ExclusiveGroupStruct, SveltoDictionary<uint, T,
NativeStrategy<FasterDictionaryNode<uint>>,
NativeStrategy<SveltoDictionaryNode<uint>>,
NativeStrategy<T>,
NativeStrategy<int>>,
NativeStrategy<FasterDictionaryNode<ExclusiveGroupStruct>>,
NativeStrategy<SveltoDictionaryNode<ExclusiveGroupStruct>>,
NativeStrategy<SveltoDictionary<uint, T,
NativeStrategy<FasterDictionaryNode<uint>>,
NativeStrategy<SveltoDictionaryNode<uint>>,
NativeStrategy<T>,
NativeStrategy<int>>>,
NativeStrategy<int>>


+ 16
- 3
Svelto.ECS/Extensions/Unity/DOTS/UECS/IUECSSubmissionEngine.cs View File

@@ -1,12 +1,25 @@
#if UNITY_ECS
using Svelto.Common;
using Unity.Entities;
using Unity.Jobs;

namespace Svelto.ECS.Extensions.Unity
{
public interface IUECSSubmissionEngine : IJobifiedEngine
public abstract class SubmissionEngine : SystemBase, IJobifiedEngine
{
EntityCommandBuffer ECB { get; set;}
EntityManager EM { get; set;}
public JobHandle Execute(JobHandle inputDeps)
{
Dependency = JobHandle.CombineDependencies(Dependency, inputDeps);
OnUpdate();
return Dependency;
}

public EntityCommandBuffer ECB { get; internal set; }
protected EntityManager EM => this.EntityManager;

public string name => TypeToString.Name(this);
}
}
#endif

+ 21
- 7
Svelto.ECS/Extensions/Unity/DOTS/UECS/SveltoOverUECSEnginesGroup.cs View File

@@ -6,19 +6,35 @@ using Unity.Jobs;

namespace Svelto.ECS.Extensions.Unity
{
/// <summary>
/// This is a high level class to abstract the complexity of creating a Svelto ECS application that interacts
/// with UECS. However this is designed to make it work almost out of the box, but it should be eventually
/// substituted by project customized code.
/// This is a JobifiedEngine and as such it expect to be ticked. Normally it must be executed in a
/// SortedEnginesGroup as step that happens after the Svelto jobified engines run. The flow should be:
/// Svelto Engines Run
/// This Engine runs, which causeS:
/// Jobs to be completed (it's a sync point)
/// Synchronizations engines to be executed (Svelto to UECS)
/// Submission of Entities to be executed
/// Svelto Add/Remove callbacks to be called
/// ISubmissionEngines to be executed
/// UECS engines to executed
/// Synchronizations engines to be executed (UECS To Svelto)
/// </summary>
[Sequenced(nameof(JobifiedSveltoEngines.SveltoOverUECS))]
public class SveltoOverUECSEnginesGroup: IJobifiedEngine
{
public SveltoOverUECSEnginesGroup(EnginesRoot enginesRoot)
{
DBC.ECS.Check.Require(enginesRoot.scheduler is ISimpleEntitiesSubmissionScheduler, "The Engines root must use a EntitiesSubmissionScheduler scheduler implementation");
DBC.ECS.Check.Require(enginesRoot.scheduler is SimpleEntitiesSubmissionScheduler, "The Engines root must use a EntitiesSubmissionScheduler scheduler implementation");

CreateUnityECSWorldForSvelto(enginesRoot.scheduler as ISimpleEntitiesSubmissionScheduler, enginesRoot);
CreateUnityECSWorldForSvelto(enginesRoot.scheduler as SimpleEntitiesSubmissionScheduler, enginesRoot);
}

public World world { get; private set; }

void CreateUnityECSWorldForSvelto(ISimpleEntitiesSubmissionScheduler scheduler, EnginesRoot enginesRoot)
void CreateUnityECSWorldForSvelto(SimpleEntitiesSubmissionScheduler scheduler, EnginesRoot enginesRoot)
{
world = new World("Svelto<>UECS world");

@@ -29,7 +45,6 @@ namespace Svelto.ECS.Extensions.Unity
//This is the UECS group that takes care of all the UECS systems that creates entities
//it also submits Svelto entities
_sveltoUecsEntitiesSubmissionGroup = new SveltoUECSEntitiesSubmissionGroup(scheduler, world);
enginesRoot.AddEngine(_sveltoUecsEntitiesSubmissionGroup);
//This is the group that handles the UECS sync systems that copy the svelto entities values to UECS entities
_syncSveltoToUecsGroup = new SyncSveltoToUECSGroup();
enginesRoot.AddEngine(_syncSveltoToUecsGroup);
@@ -45,7 +60,7 @@ namespace Svelto.ECS.Extensions.Unity
public JobHandle Execute(JobHandle inputDeps)
{
//this is a sync point, there won't be pending jobs after this
_sveltoUecsEntitiesSubmissionGroup.Execute(inputDeps);
_sveltoUecsEntitiesSubmissionGroup.SubmitEntities(inputDeps);

//Mixed explicit job dependency and internal automatic ECS dependency system
//Write in to UECS entities so the UECS dependencies react on the components touched
@@ -59,7 +74,7 @@ namespace Svelto.ECS.Extensions.Unity
return _syncUecsToSveltoGroup.Execute(handle);
}

public void AddUECSSubmissionEngine(IUECSSubmissionEngine spawnUnityEntityOnSveltoEntityEngine)
public void AddUECSSubmissionEngine(SubmissionEngine spawnUnityEntityOnSveltoEntityEngine)
{
_sveltoUecsEntitiesSubmissionGroup.Add(spawnUnityEntityOnSveltoEntityEngine);
_enginesRoot.AddEngine(spawnUnityEntityOnSveltoEntityEngine);
@@ -94,7 +109,6 @@ namespace Svelto.ECS.Extensions.Unity
SyncSveltoToUECSGroup _syncSveltoToUecsGroup;
SyncUECSToSveltoGroup _syncUecsToSveltoGroup;
EnginesRoot _enginesRoot;

}
}
#endif

+ 32
- 11
Svelto.ECS/Extensions/Unity/DOTS/UECS/SveltoUECSEntitiesSubmissionGroup.cs View File

@@ -1,4 +1,7 @@
#if UNITY_ECS
using System.Collections;
using Svelto.Common;
using Svelto.DataStructures;
using Svelto.ECS.Schedulers;
using Unity.Entities;
using Unity.Jobs;
@@ -15,22 +18,21 @@ namespace Svelto.ECS.Extensions.Unity
/// solve external dependencies. External dependencies are tracked, but only linked to the UECS components operations
/// With Dependency I cannot guarantee that an external container is used before previous jobs working on it are completed
/// </summary>
public class SveltoUECSEntitiesSubmissionGroup : JobifiedEnginesGroup<IUECSSubmissionEngine>
public sealed class SveltoUECSEntitiesSubmissionGroup
{
public SveltoUECSEntitiesSubmissionGroup
(ISimpleEntitiesSubmissionScheduler submissionScheduler, World UECSWorld)
public SveltoUECSEntitiesSubmissionGroup(SimpleEntitiesSubmissionScheduler submissionScheduler, World UECSWorld)
{
_submissionScheduler = submissionScheduler;
_ECBSystem = UECSWorld.CreateSystem<SubmissionEntitiesCommandBufferSystem>();
_engines = new FasterList<SubmissionEngine>();
}

public new void Execute(JobHandle jobHandle)
public void SubmitEntities(JobHandle jobHandle)
{
//Sync Point as we must be sure that jobs that create/swap/remove entities are done
jobHandle.Complete();

if (_submissionScheduler.paused)
return;
jobHandle.Complete();

//prepare the entity command buffer to be used by the registered engines
var entityCommandBuffer = _ECBSystem.CreateCommandBuffer();
@@ -38,21 +40,40 @@ namespace Svelto.ECS.Extensions.Unity
foreach (var system in _engines)
{
system.ECB = entityCommandBuffer;
system.EM = _ECBSystem.EntityManager;
}

//Submit Svelto Entities, calls Add/Remove/MoveTo that can be used by the IUECSSubmissionEngines
_submissionScheduler.SubmitEntities();

//execute submission engines and complete jobs
base.Execute(default).Complete();
//execute submission engines and complete jobs because of this I don't need to do _ECBSystem.AddJobHandleForProducer(Dependency);
using (var profiler = new PlatformProfiler("SveltoUECSEntitiesSubmissionGroup"))
{
for (var index = 0; index < _engines.count; index++)
{
ref var engine = ref _engines[index];
using (profiler.Sample(engine.name))
{
jobHandle = engine.Execute(jobHandle);
}
}
}

//Sync Point as we must be sure that jobs that create/swap/remove entities are done
jobHandle.Complete();

//flush command buffer
_ECBSystem.Update();
}
public void Add(SubmissionEngine engine)
{
_ECBSystem.World.AddSystem(engine);
_engines.Add(engine);
}

readonly ISimpleEntitiesSubmissionScheduler _submissionScheduler;
readonly SimpleEntitiesSubmissionScheduler _submissionScheduler;
readonly SubmissionEntitiesCommandBufferSystem _ECBSystem;
readonly FasterList<SubmissionEngine> _engines;

[DisableAutoCreation]
class SubmissionEntitiesCommandBufferSystem : EntityCommandBufferSystem { }


+ 3
- 3
Svelto.ECS/Extensions/Unity/EntityDescriptorHolderHelper.cs View File

@@ -1,4 +1,4 @@
#if UNITY_ECS
#if UNITY_5 || UNITY_5_3_OR_NEWER
using Svelto.ECS.Hybrid;
using UnityEngine;

@@ -6,7 +6,7 @@ namespace Svelto.ECS.Extensions.Unity
{
public static class EntityDescriptorHolderHelper
{
public static EntityComponentInitializer CreateEntity<T>(this Transform contextHolder, EGID ID,
public static EntityInitializer CreateEntity<T>(this Transform contextHolder, EGID ID,
IEntityFactory factory, out T holder)
where T : MonoBehaviour, IEntityDescriptorHolder
{
@@ -16,7 +16,7 @@ namespace Svelto.ECS.Extensions.Unity
return factory.BuildEntity(ID, holder.GetDescriptor(), implementors);
}
public static EntityComponentInitializer Create<T>(this Transform contextHolder, EGID ID,
public static EntityInitializer Create<T>(this Transform contextHolder, EGID ID,
IEntityFactory factory)
where T : MonoBehaviour, IEntityDescriptorHolder
{


+ 2
- 2
Svelto.ECS/Extensions/Unity/SveltoGUIHelper.cs View File

@@ -86,7 +86,7 @@ namespace Svelto.ECS.Extensions.Unity
return s;
}
public static EntityComponentInitializer Create<T>(EGID ID, Transform contextHolder, IEntityFactory factory,
public static EntityInitializer Create<T>(EGID ID, Transform contextHolder, IEntityFactory factory,
out T holder, bool searchImplementorsInChildren = false)
where T : MonoBehaviour, IEntityDescriptorHolder
{
@@ -100,7 +100,7 @@ namespace Svelto.ECS.Extensions.Unity
return factory.BuildEntity(ID, holder.GetDescriptor(), implementors);
}

public static EntityComponentInitializer Create<T>(EGID ID, Transform contextHolder,
public static EntityInitializer Create<T>(EGID ID, Transform contextHolder,
IEntityFactory factory, bool searchImplementorsInChildren = false)
where T : MonoBehaviour, IEntityDescriptorHolder
{


+ 5
- 1
Svelto.ECS/Extensions/Unity/UnityEntitiesSubmissionScheduler.cs View File

@@ -1,4 +1,5 @@
#if UNITY_5 || UNITY_5_3_OR_NEWER
using System;
using Object = UnityEngine.Object;
using System.Collections;
using UnityEngine;
@@ -57,7 +58,10 @@ namespace Svelto.ECS.Schedulers.Unity
void SubmitEntities()
{
if (paused == false)
_onTick.Invoke();
{
var enumerator = _onTick.Invoke(UInt32.MaxValue);
while (enumerator.MoveNext()) ;
}
}

protected internal override EnginesRoot.EntitiesSubmitter onTick


+ 0
- 32
Svelto.ECS/IEntityFunctions.cs View File

@@ -1,32 +0,0 @@
namespace Svelto.ECS
{
public interface IEntityFunctions
{
//being entity ID globally not unique, the group must be specified when
//an entity is removed. Not specifying the group will attempt to remove
//the entity from the special standard group.
void RemoveEntity<T>(uint entityID, BuildGroup groupID) where T : IEntityDescriptor, new();
void RemoveEntity<T>(EGID entityegid) where T : IEntityDescriptor, new();
void RemoveEntitiesFromGroup(BuildGroup groupID);

void SwapEntitiesInGroup<T>(BuildGroup fromGroupID, BuildGroup toGroupID) where T : IEntityDescriptor, new();

void SwapEntityGroup<T>(uint entityID, BuildGroup fromGroupID, BuildGroup toGroupID)
where T : IEntityDescriptor, new();

void SwapEntityGroup<T>(EGID fromID, BuildGroup toGroupID) where T : IEntityDescriptor, new();

void SwapEntityGroup<T>(EGID fromID, BuildGroup toGroupID, BuildGroup mustBeFromGroup)
where T : IEntityDescriptor, new();

void SwapEntityGroup<T>(EGID fromID, EGID toId) where T : IEntityDescriptor, new();

void SwapEntityGroup<T>(EGID fromID, EGID toId, BuildGroup mustBeFromGroup)
where T : IEntityDescriptor, new();
#if UNITY_NATIVE
NativeEntityRemove ToNativeRemove<T>(string memberName) where T : IEntityDescriptor, new();
NativeEntitySwap ToNativeSwap<T>(string memberName) where T : IEntityDescriptor, new();
#endif
}
}

+ 1
- 1
Svelto.ECS/Serialization/DefaultVersioningFactory.cs View File

@@ -14,7 +14,7 @@ namespace Svelto.ECS.Serialization
_implementors = implementors;
}

public EntityComponentInitializer BuildDeserializedEntity
public EntityInitializer BuildDeserializedEntity
(EGID egid, ISerializationData serializationData, ISerializableEntityDescriptor entityDescriptor
, int serializationType, IEntitySerialization entitySerialization, IEntityFactory factory
, bool enginesRootIsDeserializationOnly)


+ 2
- 2
Svelto.ECS/Serialization/EnginesRoot.GenericEntitySerialization.cs View File

@@ -33,7 +33,7 @@ namespace Svelto.ECS
}
}

public EntityComponentInitializer DeserializeNewEntity
public EntityInitializer DeserializeNewEntity
(EGID egid, ISerializationData serializationData, int serializationType)
{
//todo: SerializableEntityHeader may be needed to be customizable
@@ -67,7 +67,7 @@ namespace Svelto.ECS

public void DeserializeEntityComponents
(ISerializationData serializationData, ISerializableEntityDescriptor entityDescriptor
, ref EntityComponentInitializer initializer, int serializationType)
, ref EntityInitializer initializer, int serializationType)
{
foreach (var serializableEntityBuilder in entityDescriptor.entitiesToSerialize)
{


+ 0
- 1
Svelto.ECS/Serialization/EntitiesDB.SerializationDescriptorMap.cs View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Svelto.Common;
using Svelto.ECS.Serialization;


+ 1
- 1
Svelto.ECS/Serialization/IDeserializationFactory.cs View File

@@ -2,7 +2,7 @@ namespace Svelto.ECS.Serialization
{
public interface IDeserializationFactory
{
EntityComponentInitializer BuildDeserializedEntity
EntityInitializer BuildDeserializedEntity
(EGID egid, ISerializationData serializationData, ISerializableEntityDescriptor entityDescriptor
, int serializationType, IEntitySerialization entitySerialization, IEntityFactory factory
, bool enginesRootIsDeserializationOnly);


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save