@@ -1,10 +1,10 @@ | |||
# Svelto.ECS Changelog | |||
All notable changes to this project will be documented in this file. Changes are listed in random order of importance. | |||
## [3.4.5] - 04-2023 | |||
* improved code after internal data refactoring and fixed some bugs | |||
* Added static DynamicEntityDescriptor method to create a new DynamicEntityDescriptor without passing an array of components | |||
* factory method to build entities without entity descriptor is now internal | |||
## [3.4.6] - 05-2023 | |||
* SveltoOnDOTS bug fixes/improvements | |||
* Comments and code cleanup | |||
## [3.4.4] - 04-2023 | |||
@@ -20,6 +20,11 @@ namespace Svelto.ECS | |||
get => _id.Data; | |||
} | |||
/// <summary> | |||
/// c# Static constructors are guaranteed to be thread safe | |||
/// The runtime guarantees that a static constructor is only called once. So even if a type is called by multiple threads at the same time, | |||
/// the static constructor is always executed one time. To get a better understanding how this works, it helps to know what purpose it serves. | |||
/// </summary> | |||
static ComponentTypeID() | |||
{ | |||
Init(); | |||
@@ -1,18 +1,19 @@ | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Runtime.CompilerServices; | |||
using Svelto.DataStructures; | |||
namespace Svelto.ECS | |||
{ | |||
public static class ComponentTypeMap | |||
static class ComponentTypeMap | |||
{ | |||
static readonly FasterDictionary<RefWrapper<Type>, ComponentID> _componentTypeMap = new FasterDictionary<RefWrapper<Type>, ComponentID>(); | |||
static readonly FasterDictionary<ComponentID, Type> _reverseComponentTypeMap = new FasterDictionary<ComponentID, Type>(); | |||
static readonly ConcurrentDictionary<Type, ComponentID> _componentTypeMap = new ConcurrentDictionary<Type, ComponentID>(); | |||
static readonly ConcurrentDictionary<ComponentID, Type> _reverseComponentTypeMap = new ConcurrentDictionary<ComponentID, Type>(); | |||
public static void Add(Type type, ComponentID idData) | |||
{ | |||
_componentTypeMap.Add(type, idData); | |||
_reverseComponentTypeMap.Add(idData, type); | |||
_componentTypeMap.TryAdd(type, idData); | |||
_reverseComponentTypeMap.TryAdd(idData, type); | |||
} | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
@@ -16,8 +16,8 @@ namespace Svelto.ECS | |||
{ | |||
static EnginesRoot() | |||
{ | |||
EntityDescriptorsWarmup.Init(); | |||
GroupHashMap.Init(); | |||
EntityDescriptorsWarmup.WarmUp(); | |||
GroupHashMap.WarmUp(); | |||
//SharedDictonary.Init(); | |||
SerializationDescriptorMap.Init(); | |||
@@ -45,7 +45,7 @@ namespace Svelto.ECS | |||
public DynamicEntityDescriptor(IComponentBuilder[] extraEntityBuilders) | |||
{ | |||
this = CreateDynamicEntityDescriptor(); | |||
this = DynamicEntityDescriptor<TType>.CreateDynamicEntityDescriptor(); | |||
var extraEntitiesLength = extraEntityBuilders.Length; | |||
@@ -54,7 +54,7 @@ namespace Svelto.ECS | |||
public DynamicEntityDescriptor(FasterList<IComponentBuilder> extraEntityBuilders) | |||
{ | |||
this = CreateDynamicEntityDescriptor(); | |||
this = DynamicEntityDescriptor<TType>.CreateDynamicEntityDescriptor(); | |||
var extraEntities = extraEntityBuilders.ToArrayFast(out _); | |||
var extraEntitiesLength = extraEntityBuilders.count; | |||
@@ -173,10 +173,10 @@ namespace Svelto.ECS | |||
public bool TryGetEGID(EntityReference reference, out EGID egid) | |||
{ | |||
egid = default; | |||
#if DEBUG && !PROFILE_SVELTO | |||
if (reference == EntityReference.Invalid) | |||
return false; | |||
#endif | |||
// Make sure we are querying for the current version of the locator. | |||
// Otherwise the locator is pointing to a removed entity. | |||
ref var entityReferenceMapElement = ref _entityReferenceMap[reference.index]; | |||
@@ -5,13 +5,13 @@ using Svelto.ECS.Internal; | |||
namespace Svelto.ECS | |||
{ | |||
public static class EntityDescriptorsWarmup | |||
static class EntityDescriptorsWarmup | |||
{ | |||
/// <summary> | |||
/// c# Static constructors are guaranteed to be thread safe | |||
/// Warmup all EntityDescriptors and ComponentTypeID classes to avoid huge overheads when they are first used | |||
/// </summary> | |||
internal static void Init() | |||
internal static void WarmUp() | |||
{ | |||
List<Assembly> assemblies = AssemblyUtility.GetCompatibleAssemblies(); | |||
foreach (Assembly assembly in assemblies) | |||
@@ -30,10 +30,7 @@ namespace Svelto.ECS | |||
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(warmup.TypeHandle); | |||
} | |||
catch (Exception e) | |||
{ | |||
continue; | |||
} | |||
catch { } | |||
} | |||
} | |||
@@ -51,10 +48,7 @@ namespace Svelto.ECS | |||
//this warms up the component builder. There could be different implementation of components builders for the same component type in theory | |||
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(componentType.TypeHandle); | |||
} | |||
catch (Exception e) | |||
{ | |||
continue; | |||
} | |||
catch { } | |||
} | |||
} | |||
} | |||
@@ -27,7 +27,10 @@ namespace Svelto.ECS | |||
{ | |||
static GroupCompound() | |||
{ | |||
//avoid race conditions if compounds are using on multiple thread | |||
//avoid race conditions if compounds are using on multiple thread. This shouldn't be necessary though since c# static constructors are guaranteed to be thread safe! | |||
/// c# Static constructors are guaranteed to be thread safe | |||
/// The runtime guarantees that a static constructor is only called once. So even if a type is called by multiple threads at the same time, | |||
/// the static constructor is always executed one time. To get a better understanding how this works, it helps to know what purpose it serves. | |||
if (Interlocked.CompareExchange(ref isInitializing, 1, 0) == 0 && | |||
GroupCompoundInitializer.skipStaticCompoundConstructorsWith4Tags.Value == false) | |||
{ | |||
@@ -10,8 +10,12 @@ namespace Svelto.ECS | |||
{ | |||
/// <summary> | |||
/// c# Static constructors are guaranteed to be thread safe | |||
/// The runtime guarantees that a static constructor is only called once. So even if a type is called by multiple threads at the same time, | |||
/// the static constructor is always executed one time. To get a better understanding how this works, it helps to know what purpose it serves. | |||
/// | |||
/// Warmup the group hash map. This will call all the static constructors of the group types | |||
/// </summary> | |||
internal static void Init() | |||
internal static void WarmUp() | |||
{ | |||
List<Assembly> assemblies = AssemblyUtility.GetCompatibleAssemblies(); | |||
foreach (Assembly assembly in assemblies) | |||
@@ -26,8 +30,8 @@ namespace Svelto.ECS | |||
{ | |||
CheckForGroupCompounds(type); | |||
if (type != null && type.IsClass && type.IsSealed && | |||
type.IsAbstract) //IsClass and IsSealed and IsAbstract means only static classes | |||
//Search inside static types | |||
if (type != null && type.IsClass && type.IsSealed && type.IsAbstract) //IsClass and IsSealed and IsAbstract means only static classes | |||
{ | |||
var subClasses = type.GetNestedTypes(); | |||
@@ -40,8 +44,8 @@ namespace Svelto.ECS | |||
foreach (var field in fields) | |||
{ | |||
if (field.IsStatic | |||
&& (typeOfExclusiveGroup.IsAssignableFrom(field.FieldType) | |||
if (field.IsStatic | |||
&& (typeOfExclusiveGroup.IsAssignableFrom(field.FieldType) | |||
|| typeOfExclusiveGroupStruct.IsAssignableFrom(field.FieldType) | |||
|| typeOfExclusiveBuildGroup.IsAssignableFrom(field.FieldType))) | |||
{ | |||
@@ -52,7 +56,8 @@ namespace Svelto.ECS | |||
var group = (ExclusiveGroup)field.GetValue(null); | |||
groupIDAndBitMask = ((ExclusiveGroupStruct)@group).ToIDAndBitmask(); | |||
} | |||
else if (typeOfExclusiveGroupStruct.IsAssignableFrom(field.FieldType)) | |||
else | |||
if (typeOfExclusiveGroupStruct.IsAssignableFrom(field.FieldType)) | |||
{ | |||
var group = (ExclusiveGroupStruct)field.GetValue(null); | |||
groupIDAndBitMask = @group.ToIDAndBitmask(); | |||
@@ -94,7 +99,7 @@ namespace Svelto.ECS | |||
{ | |||
if (typeof(ITouchedByReflection).IsAssignableFrom(type)) | |||
{ | |||
//this wil call the static constructor, but only once. Static constructors won't be called | |||
//this calls the static constructor, but only once. Static constructors won't be called | |||
//more than once with this | |||
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.BaseType.TypeHandle); | |||
} | |||
@@ -107,7 +112,7 @@ namespace Svelto.ECS | |||
/// <param name="exclusiveGroupStruct"></param> | |||
/// <param name="name"></param> | |||
/// <exception cref="ECSException"></exception> | |||
public static void RegisterGroup(ExclusiveGroupStruct exclusiveGroupStruct, string name) | |||
internal static void RegisterGroup(ExclusiveGroupStruct exclusiveGroupStruct, string name) | |||
{ | |||
//Group already registered by another field referencing the same group, can happen because | |||
//the group poked is a group compound which static constructor is already been called at this point | |||
@@ -125,7 +130,7 @@ namespace Svelto.ECS | |||
_hashByGroups.Add(exclusiveGroupStruct, nameHash); | |||
} | |||
internal static uint GetHashFromGroup(ExclusiveGroupStruct groupStruct) | |||
public static uint GetHashFromGroup(ExclusiveGroupStruct groupStruct) | |||
{ | |||
#if DEBUG && !PROFILE_SVELTO | |||
if (_hashByGroups.ContainsKey(groupStruct) == false) | |||
@@ -135,7 +140,7 @@ namespace Svelto.ECS | |||
return _hashByGroups[groupStruct]; | |||
} | |||
internal static ExclusiveGroupStruct GetGroupFromHash(uint groupHash) | |||
public static ExclusiveGroupStruct GetGroupFromHash(uint groupHash) | |||
{ | |||
#if DEBUG && !PROFILE_SVELTO | |||
if (_groupsByHash.ContainsKey(groupHash) == false) | |||
@@ -20,14 +20,14 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
public EntityArchetype CreateArchetype(params ComponentType[] types) | |||
{ | |||
return _EManager.CreateArchetype(types); | |||
return EManager.CreateArchetype(types); | |||
} | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void SetComponent<T>(Entity e, in T component) | |||
where T : unmanaged, IComponentData | |||
{ | |||
_EManager.SetComponentData(e, component); | |||
EManager.SetComponentData(e, component); | |||
} | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
@@ -37,23 +37,23 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
#if UNITY_ECS_100 | |||
_EManager.SetSharedComponent(e, component); | |||
#else | |||
_EManager.SetSharedComponentData(e, component); | |||
EManager.SetSharedComponentData(e, component); | |||
#endif | |||
} | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public Entity CreateDOTSEntityOnSvelto(Entity prefabEntity, EGID egid) | |||
{ | |||
Entity dotsEntity = _EManager.Instantiate(prefabEntity); | |||
Entity dotsEntity = EManager.Instantiate(prefabEntity); | |||
//SharedComponentData can be used to group the DOTS ECS entities exactly like the Svelto ones | |||
#if UNITY_ECS_100 | |||
_EManager.AddSharedComponent(dotsEntity, new DOTSSveltoGroupID(egid.groupID)); | |||
#else | |||
_EManager.AddSharedComponentData(dotsEntity, new DOTSSveltoGroupID(egid.groupID)); | |||
EManager.AddSharedComponentData(dotsEntity, new DOTSSveltoGroupID(egid.groupID)); | |||
#endif | |||
_EManager.AddComponent<DOTSSveltoEGID>(dotsEntity); | |||
_EManager.SetComponentData(dotsEntity, new DOTSSveltoEGID(egid)); | |||
EManager.AddComponent<DOTSSveltoEGID>(dotsEntity); | |||
EManager.SetComponentData(dotsEntity, new DOTSSveltoEGID(egid)); | |||
return dotsEntity; | |||
} | |||
@@ -68,16 +68,16 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public Entity CreateDOTSEntityOnSvelto(EntityArchetype archetype, EGID egid) | |||
{ | |||
Entity dotsEntity = _EManager.CreateEntity(archetype); | |||
Entity dotsEntity = EManager.CreateEntity(archetype); | |||
//SharedComponentData can be used to group the DOTS ECS entities exactly like the Svelto ones | |||
#if UNITY_ECS_100 | |||
_EManager.AddSharedComponent(dotsEntity, new DOTSSveltoGroupID(egid.groupID)); | |||
#else | |||
_EManager.AddSharedComponentData(dotsEntity, new DOTSSveltoGroupID(egid.groupID)); | |||
EManager.AddSharedComponentData(dotsEntity, new DOTSSveltoGroupID(egid.groupID)); | |||
#endif | |||
_EManager.AddComponent<DOTSSveltoEGID>(dotsEntity); | |||
_EManager.SetComponentData(dotsEntity, new DOTSSveltoEGID(egid)); | |||
EManager.AddComponent<DOTSSveltoEGID>(dotsEntity); | |||
EManager.SetComponentData(dotsEntity, new DOTSSveltoEGID(egid)); | |||
return dotsEntity; | |||
} | |||
@@ -92,34 +92,34 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public Entity CreateDOTSEntity(EntityArchetype archetype) | |||
{ | |||
return _EManager.CreateEntity(archetype); | |||
return EManager.CreateEntity(archetype); | |||
} | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void DestroyEntity(Entity e) | |||
{ | |||
_EManager.DestroyEntity(e); | |||
EManager.DestroyEntity(e); | |||
} | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void RemoveComponent<T>(Entity dotsEntity) | |||
{ | |||
_EManager.RemoveComponent<T>(dotsEntity); | |||
EManager.RemoveComponent<T>(dotsEntity); | |||
} | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void AddComponent<T>(Entity dotsEntity) | |||
where T : unmanaged, IComponentData | |||
{ | |||
_EManager.AddComponent<T>(dotsEntity); | |||
EManager.AddComponent<T>(dotsEntity); | |||
} | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void AddComponent<T>(Entity dotsEntity, in T component) | |||
where T : unmanaged, IComponentData | |||
{ | |||
_EManager.AddComponent<T>(dotsEntity); | |||
_EManager.SetComponentData(dotsEntity, component); | |||
EManager.AddComponent<T>(dotsEntity); | |||
EManager.SetComponentData(dotsEntity, component); | |||
} | |||
public T GetComponent<T>(Entity dotsEntity) where T : unmanaged, IComponentData | |||
@@ -127,7 +127,7 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
#if UNITY_ECS_100 | |||
return _EManager.GetComponentData<T>(dotsEntity); | |||
#else | |||
return _EManager.GetComponentData<T>(dotsEntity); | |||
return EManager.GetComponentData<T>(dotsEntity); | |||
#endif | |||
} | |||
@@ -138,7 +138,7 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
#if UNITY_ECS_100 | |||
_EManager.AddSharedComponent(dotsEntity, component); | |||
#else | |||
_EManager.AddSharedComponentData(dotsEntity, component); | |||
EManager.AddSharedComponentData(dotsEntity, component); | |||
#endif | |||
} | |||
@@ -146,7 +146,7 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
public void AddBuffer<T>(Entity dotsEntity) | |||
where T : unmanaged, IBufferElementData | |||
{ | |||
_EManager.AddBuffer<T>(dotsEntity); | |||
EManager.AddBuffer<T>(dotsEntity); | |||
} | |||
#if !(DEBUG && !PROFILE_SVELTO) | |||
@@ -154,7 +154,7 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
#endif | |||
public void SetDebugName(Entity dotsEntity, string name) | |||
{ | |||
_EManager.SetName(dotsEntity, name); | |||
EManager.SetName(dotsEntity, name); | |||
} | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
@@ -166,7 +166,7 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
#else | |||
for (int i = 0; i < nativeArray.Length; i++) | |||
{ | |||
_EManager.SetSharedComponentData(nativeArray[i], SCD); | |||
EManager.SetSharedComponentData(nativeArray[i], SCD); | |||
} | |||
#endif | |||
} | |||
@@ -174,7 +174,7 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void AddComponentBatched<T>(NativeArray<Entity> DOTSEntities) | |||
{ | |||
_EManager.AddComponent<T>(DOTSEntities); | |||
EManager.AddComponent<T>(DOTSEntities); | |||
} | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
@@ -186,14 +186,14 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
_jobHandle->Complete(); | |||
var count = (int)(range.rangeEnd - range.rangeStart); | |||
var nativeArray = _EManager.Instantiate(prefab, count, _EManager.World.UpdateAllocator.ToAllocator); | |||
var nativeArray = EManager.Instantiate(prefab, count, EManager.World.UpdateAllocator.ToAllocator); | |||
#if UNITY_ECS_100 | |||
_EManager.AddSharedComponent(nativeArray, new DOTSSveltoGroupID(groupID)); | |||
#else | |||
for (int i = 0; i < nativeArray.Length; i++) | |||
{ | |||
_EManager.AddSharedComponentData(nativeArray[i], new DOTSSveltoGroupID(groupID)); | |||
EManager.AddSharedComponentData(nativeArray[i], new DOTSSveltoGroupID(groupID)); | |||
} | |||
#endif | |||
//Set Svelto DOTSEntityComponent dotsEntity field to the DOTS entity | |||
@@ -220,14 +220,14 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
var count = (int)(range.rangeEnd - range.rangeStart); | |||
//DOTS entities track Svelto entities through this component | |||
_EManager.AddComponent<DOTSSveltoEGID>(nativeArray); | |||
EManager.AddComponent<DOTSSveltoEGID>(nativeArray); | |||
//set the DOTSSveltoEGID values | |||
var setDOTSSveltoEGIDJob = new SetDOTSSveltoEGID | |||
{ | |||
sveltoStartIndex = range.rangeStart, | |||
createdEntities = nativeArray, | |||
entityManager = _EManager, | |||
entityManager = EManager, | |||
ids = sveltoIds, | |||
groupID = groupID | |||
}; | |||
@@ -249,7 +249,7 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void DestroyEntitiesBatched(NativeArray<Entity> nativeArray) | |||
{ | |||
_EManager.DestroyEntity(nativeArray); | |||
EManager.DestroyEntity(nativeArray); | |||
} | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
@@ -298,6 +298,17 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
}); | |||
} | |||
} | |||
EntityManager EManager | |||
{ | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
get | |||
{ | |||
DBC.ECS.Check.Require(_EManager != default, "EManager not initialized, did you forget to add the engine as submission engine?"); | |||
return _EManager; | |||
} | |||
} | |||
readonly EntityManager _EManager; | |||
[NativeDisableUnsafePtrRestriction] readonly unsafe JobHandle* _jobHandle; | |||
@@ -29,7 +29,7 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
public SveltoOnDOTSEntitiesSubmissionGroup(SimpleEntitiesSubmissionScheduler submissionScheduler) | |||
{ | |||
_submissionScheduler = submissionScheduler; | |||
_submissionEngines = new FasterList<ISveltoOnDOTSStructuralEngine>(); | |||
_structuralEngines = new FasterList<ISveltoOnDOTSStructuralEngine>(); | |||
} | |||
public EntitiesDB entitiesDB { get; set; } | |||
@@ -56,7 +56,7 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
//Submit Svelto Entities, calls Add/Remove/MoveTo that can be used by the DOTS ECSSubmissionEngines | |||
_submissionScheduler.SubmitEntities(); | |||
foreach (var engine in _submissionEngines) | |||
foreach (var engine in _structuralEngines) | |||
engine.OnPostSubmission(); | |||
_dotsOperationsForSvelto.Complete(); | |||
@@ -65,8 +65,8 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
public void Add(ISveltoOnDOTSStructuralEngine engine) | |||
{ | |||
_submissionEngines.Add(engine); | |||
if (World != null) | |||
_structuralEngines.Add(engine); | |||
if (_isReady == true) | |||
{ | |||
engine.DOTSOperations = _dotsOperationsForSvelto; | |||
engine.OnOperationsReady(); | |||
@@ -79,9 +79,10 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
{ | |||
_jobHandle = (JobHandle*) MemoryUtilities.NativeAlloc((uint)MemoryUtilities.SizeOf<JobHandle>(), Allocator.Persistent); | |||
_dotsOperationsForSvelto = new DOTSOperationsForSvelto(World.EntityManager, _jobHandle); | |||
_isReady = true; | |||
//initialise engines field while world was null | |||
foreach (var engine in _submissionEngines) | |||
foreach (var engine in _structuralEngines) | |||
{ | |||
engine.DOTSOperations = _dotsOperationsForSvelto; | |||
engine.OnOperationsReady(); | |||
@@ -104,9 +105,10 @@ namespace Svelto.ECS.SveltoOnDOTS | |||
throw new NotSupportedException("if this is called something broke the original design"); | |||
} | |||
readonly FasterList<ISveltoOnDOTSStructuralEngine> _submissionEngines; | |||
readonly FasterList<ISveltoOnDOTSStructuralEngine> _structuralEngines; | |||
readonly SimpleEntitiesSubmissionScheduler _submissionScheduler; | |||
DOTSOperationsForSvelto _dotsOperationsForSvelto; | |||
bool _isReady; | |||
unsafe JobHandle* _jobHandle; | |||
} | |||
} |
@@ -85,6 +85,8 @@ While other frameworks typically limit user freedom to avoid exposing flaws in t | |||
**GroupCompounds** build on this idea by allowing users to change the "state"/"set"/"group" according to tags that serve effectively as adjective or state identifiers. | |||
Entities can change state moving between sets swapping them in groups explcitly, rather than changing archetype. | |||
## Why using Svelto.ECS with Unity? | |||
Svelto.ECS doens't use a traditional archetype model like DOTS ECS does. The novel hybrid approach based on groups instead than archetypes has been designed to allow the user to take the right decision when it comes to states management. Svelto.ECS doesn't allow archetypes to change dynamically, the user cannot add or remove components after the entity is created. Handling entities states with components can quickly lead to very intensive structural changes operations, so groups have been introduced to avoid the wild explosion of states permutations and let the user see explicitly the cost of their decisions. | |||
@@ -11,7 +11,7 @@ | |||
"url": "https://github.com/sebas77/Svelto.ECS.git" | |||
}, | |||
"dependencies": { | |||
"com.sebaslab.svelto.common": "3.4.2" | |||
"com.sebaslab.svelto.common": "3.4.3" | |||
}, | |||
"keywords": [ | |||
"svelto", | |||
@@ -19,7 +19,7 @@ | |||
"svelto.ecs" | |||
], | |||
"name": "com.sebaslab.svelto.ecs", | |||
"version": "3.4.5", | |||
"version": "3.4.6", | |||
"type": "library", | |||
"unity": "2020.3" | |||
} |