Browse Source

some new experimental features: The new EntitiesStream and Groups searchable by name. Svelto.ECS is now c# 7 only. The awkward QueryEntitiesAndIndex has been replaced by QueryEntity

tags/2.8
sebas77 5 years ago
parent
commit
b5052c96a2
25 changed files with 414 additions and 177 deletions
  1. +1
    -1
      Svelto.Common
  2. +11
    -11
      Svelto.ECS/CheckEntityUtilities.cs
  3. +0
    -0
      Svelto.ECS/Common/Components/ECSRect.cs
  4. +0
    -0
      Svelto.ECS/Common/Components/ECSVector2.cs
  5. +7
    -0
      Svelto.ECS/Common/EntityStructs/PositionEntityStruct.cs
  6. +7
    -0
      Svelto.ECS/Common/EntityStructs/RotationEntityStruct.cs
  7. +2
    -1
      Svelto.ECS/Dispatcher/DispatchOnChange.cs
  8. +20
    -8
      Svelto.ECS/Dispatcher/DispatchOnSet.cs
  9. +3
    -3
      Svelto.ECS/EGIDMapper.cs
  10. +2
    -2
      Svelto.ECS/EnginesRoot.DoubleBufferedEntityViews.cs
  11. +1
    -0
      Svelto.ECS/EnginesRoot.Engines.cs
  12. +20
    -13
      Svelto.ECS/EnginesRoot.Entities.cs
  13. +5
    -6
      Svelto.ECS/EnginesRoot.Submission.cs
  14. +76
    -32
      Svelto.ECS/EntitiesDB.cs
  15. +1
    -0
      Svelto.ECS/EntityBuilder.cs
  16. +93
    -0
      Svelto.ECS/EntityStream.cs
  17. +0
    -12
      Svelto.ECS/EntityView.cs
  18. +19
    -1
      Svelto.ECS/ExclusiveGroups.cs
  19. +33
    -36
      Svelto.ECS/ExecuteOnEntitiesDB.cs
  20. +8
    -1
      Svelto.ECS/Extensions/Unity/GenericEntityDescriptorHolder.cs
  21. +12
    -6
      Svelto.ECS/Extensions/Unity/SveltoEntityFactoryForUnity.cs
  22. +39
    -43
      Svelto.ECS/IEntitiesDB.cs
  23. +2
    -0
      Svelto.ECS/IEntityDescriptorHolder.cs
  24. +1
    -1
      Svelto.ECS/IEntityViewStruct.cs
  25. +51
    -0
      Svelto.ECS/IObsoleteInterfaceDb.cs

+ 1
- 1
Svelto.Common

@@ -1 +1 @@
Subproject commit bc533fa00a89fc37dcd635909c138cf7953c3376
Subproject commit b6ff2a5f1357be35efdd86ae5ea5d1d6be4f68b8

+ 11
- 11
Svelto.ECS/CheckEntityUtilities.cs View File

@@ -16,14 +16,14 @@ namespace Svelto.ECS
void CheckRemoveEntityID(EGID entityID, IEntityDescriptor descriptorEntity)
{

Dictionary<Type, ITypeSafeDictionary> @group;
Dictionary<Type, ITypeSafeDictionary> group;
var descriptorEntitiesToBuild = descriptorEntity.entitiesToBuild;
if (_groupEntityDB.TryGetValue(entityID.groupID, out @group) == true)
if (_groupEntityDB.TryGetValue(entityID.groupID, out group))
{
for (int i = 0; i < descriptorEntitiesToBuild.Length; i++)
{
CheckRemoveEntityID(entityID, descriptorEntitiesToBuild[i].GetEntityType(), @group, descriptorEntity.ToString());
CheckRemoveEntityID(entityID, descriptorEntitiesToBuild[i].GetEntityType(), group, descriptorEntity.ToString());
}
}
else
@@ -38,10 +38,10 @@ namespace Svelto.ECS
#if DISABLE_CHECKS
[Conditional("_CHECKS_DISABLED")]
#endif
void CheckRemoveEntityID(EGID entityID, Type entityType, Dictionary<Type, ITypeSafeDictionary> @group, string name)
void CheckRemoveEntityID(EGID entityID, Type entityType, Dictionary<Type, ITypeSafeDictionary> group, string name)
{
ITypeSafeDictionary entities;
if (@group.TryGetValue(entityType, out entities) == true)
if (group.TryGetValue(entityType, out entities))
{
if (entities.Has(entityID.entityID) == false)
{
@@ -69,15 +69,15 @@ namespace Svelto.ECS
#endif
void CheckAddEntityID<T>(EGID entityID, T descriptorEntity) where T:IEntityDescriptor
{
Dictionary<Type, ITypeSafeDictionary> @group;
Dictionary<Type, ITypeSafeDictionary> group;
var descriptorEntitiesToBuild = descriptorEntity.entitiesToBuild;
//these are the entities added in this frame
if (_groupEntityDB.TryGetValue(entityID.groupID, out @group) == true)
if (_groupEntityDB.TryGetValue(entityID.groupID, out group))
{
for (int i = 0; i < descriptorEntitiesToBuild.Length; i++)
{
CheckAddEntityID(entityID, descriptorEntitiesToBuild[i].GetEntityType(), @group, descriptorEntity.ToString());
CheckAddEntityID(entityID, descriptorEntitiesToBuild[i].GetEntityType(), group, descriptorEntity.ToString());
}
}
}
@@ -85,12 +85,12 @@ namespace Svelto.ECS
#if DISABLE_CHECKS
[Conditional("_CHECKS_DISABLED")]
#endif
static void CheckAddEntityID(EGID entityID, Type entityType, Dictionary<Type, ITypeSafeDictionary> @group, string name)
static void CheckAddEntityID(EGID entityID, Type entityType, Dictionary<Type, ITypeSafeDictionary> group, string name)
{
ITypeSafeDictionary entities;
if (@group.TryGetValue(entityType, out entities))
if (group.TryGetValue(entityType, out entities))
{
if (entities.Has(entityID.entityID) == true)
if (entities.Has(entityID.entityID))
{
Console.LogError("Entity ".FastConcat(name, " with used ID is about to be built: ")
.FastConcat(entityType.ToString())


Svelto.ECS/ECSComponents/ECSRect.cs → Svelto.ECS/Common/Components/ECSRect.cs View File


Svelto.ECS/ECSComponents/ECSVector2.cs → Svelto.ECS/Common/Components/ECSVector2.cs View File


+ 7
- 0
Svelto.ECS/Common/EntityStructs/PositionEntityStruct.cs View File

@@ -0,0 +1,7 @@
namespace Svelto.ECS.EntityStructs
{
public struct PositionEntityStruct : IEntityStruct
{
public EGID ID { get; set; }
}
}

+ 7
- 0
Svelto.ECS/Common/EntityStructs/RotationEntityStruct.cs View File

@@ -0,0 +1,7 @@
namespace Svelto.ECS.EntityStructs
{
public struct RotationEntityStruct : IEntityStruct
{
public EGID ID { get; set; }
}
}

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

@@ -7,7 +7,8 @@ namespace Svelto.ECS
public DispatchOnChange(int senderID) : base(senderID)
{ }
public DispatchOnChange() {}
public DispatchOnChange()
{}

public new T value
{


+ 20
- 8
Svelto.ECS/Dispatcher/DispatchOnSet.cs View File

@@ -1,18 +1,30 @@
using System;
using Svelto.WeakEvents;

namespace Svelto.ECS
{
public class DispatchOnSet<T> where T:struct
{
static ExclusiveGroup OBSOLETE_GROUP = new ExclusiveGroup();
public DispatchOnSet(int senderID)
{
_senderID = senderID;
_subscribers = new WeakEvent<int, T>();
Console.LogWarningDebug("This method is obsolete and shouldn't be used anymore");
_senderID = new EGID(senderID, OBSOLETE_GROUP);
_subscribers = new WeakEvent<EGID, T>();
}

public DispatchOnSet(EGID senderID)
{
_subscribers = new WeakEvent<EGID, T>();
_senderID = senderID;
}
public DispatchOnSet()
{
_subscribers = new WeakEvent<int, T>();
_subscribers = new WeakEvent<EGID, T>();
}
public T value
@@ -30,19 +42,19 @@ namespace Svelto.ECS
}
}
public void NotifyOnValueSet(System.Action<int, T> action)
public void NotifyOnValueSet(Action<EGID, T> action)
{
_subscribers += action;
}

public void StopNotify(System.Action<int, T> action)
public void StopNotify(Action<EGID, T> action)
{
_subscribers -= action;
}

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

WeakEvent<int, T> _subscribers;
WeakEvent<EGID, T> _subscribers;
}
}

+ 3
- 3
Svelto.ECS/EGIDMapper.cs View File

@@ -6,11 +6,11 @@ namespace Svelto.ECS
{
internal TypeSafeDictionary<T> map;

public T[] entities(EGID id, out uint index)
public ref T entity(EGID id)
{
int count;
index = map.FindElementIndex(id.entityID);
return map.GetValuesArray(out count);
var index = map.FindElementIndex(id.entityID);
return ref map.GetValuesArray(out count)[index];
}
}
}

+ 2
- 2
Svelto.ECS/EnginesRoot.DoubleBufferedEntityViews.cs View File

@@ -14,8 +14,8 @@ namespace Svelto.ECS

internal DoubleBufferedEntitiesToAdd()
{
this.other = _entityViewsToAddBufferA;
this.current = _entityViewsToAddBufferB;
other = _entityViewsToAddBufferA;
current = _entityViewsToAddBufferB;
}

internal T other;


+ 1
- 0
Svelto.ECS/EnginesRoot.Engines.cs View File

@@ -34,6 +34,7 @@ namespace Svelto.ECS
_groupedEntityToAdd = new DoubleBufferedEntitiesToAdd<FasterDictionary<int, Dictionary<Type, ITypeSafeDictionary>>>();

_entitiesDB = new EntitiesDB(_groupEntityDB, _groupsPerEntity);
_entityStreams = new EntityStreams(_entitiesDB);

_scheduler = entityViewScheduler;
_scheduler.onTick = new WeakAction(SubmitEntityViews);


+ 20
- 13
Svelto.ECS/EnginesRoot.Entities.cs View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using Svelto.Common;
using Svelto.DataStructures.Experimental;
using Svelto.Common;
using Svelto.DataStructures.Experimental;
using Svelto.ECS.Internal;

namespace Svelto.ECS
@@ -53,7 +53,12 @@ namespace Svelto.ECS
}

///--------------------------------------------

///
public EntityStreams GenerateEntityStream()
{
return _entityStreams;
}
public IEntityFactory GenerateEntityFactory()
{
return new GenericEntityFactory(new DataStructures.WeakReference<EnginesRoot>(this));
@@ -94,14 +99,14 @@ namespace Svelto.ECS
var count = entityViewsToBuild.Length;
//reserve space in the database
Dictionary<Type, ITypeSafeDictionary> @group;
Dictionary<Type, ITypeSafeDictionary> group;
if (_groupEntityDB.TryGetValue(groupID, out group) == false)
group = _groupEntityDB[groupID] = new Dictionary<Type, ITypeSafeDictionary>();

//reserve space in building buffer
Dictionary<Type, ITypeSafeDictionary> @groupBuffer;
if (_groupedEntityToAdd.current.TryGetValue(groupID, out @groupBuffer) == false)
@groupBuffer = _groupedEntityToAdd.current[groupID] = new Dictionary<Type, ITypeSafeDictionary>();
Dictionary<Type, ITypeSafeDictionary> groupBuffer;
if (_groupedEntityToAdd.current.TryGetValue(groupID, out groupBuffer) == false)
groupBuffer = _groupedEntityToAdd.current[groupID] = new Dictionary<Type, ITypeSafeDictionary>();

for (var index = 0; index < count; index++)
{
@@ -114,8 +119,8 @@ namespace Svelto.ECS
else
dbList.AddCapacity(size);
if (@groupBuffer.TryGetValue(entityViewType, out dbList) == false)
@groupBuffer[entityViewType] = entityViewBuilder.Preallocate(ref dbList, size);
if (groupBuffer.TryGetValue(entityViewType, out dbList) == false)
groupBuffer[entityViewType] = entityViewBuilder.Preallocate(ref dbList, size);
else
dbList.AddCapacity(size);
}
@@ -138,14 +143,14 @@ namespace Svelto.ECS
.FastConcat(entityGID.groupID));

ITypeSafeDictionary entityInfoViewDic;
EntityInfoView entityInfoView = default(EntityInfoView);
EntityInfoView entityInfoView = default;

//Check if there is an EntityInfoView linked to this entity, if so it's a DynamicEntityDescriptor!
bool correctEntityDescriptorFound = true;
if (fromGroup.TryGetValue(_entityInfoView, out entityInfoViewDic) == true
if (fromGroup.TryGetValue(_entityInfoView, out entityInfoViewDic)
&& (entityInfoViewDic as TypeSafeDictionary<EntityInfoView>).TryGetValue
(entityGID.entityID, out entityInfoView) == true &&
(correctEntityDescriptorFound = entityInfoView.type == originalDescriptorType) == true)
(entityGID.entityID, out entityInfoView) &&
(correctEntityDescriptorFound = entityInfoView.type == originalDescriptorType))
{
var entitiesToMove = entityInfoView.entitiesToBuild;

@@ -254,6 +259,8 @@ namespace Svelto.ECS

MoveEntity(builders, fromEntityID, originalEntityDescriptor, toEntityID, toGroup);
}

readonly EntityStreams _entityStreams;
readonly Type _entityInfoView = typeof(EntityInfoView);
const string INVALID_DYNAMIC_DESCRIPTOR_ERROR = "Found an entity requesting an invalid dynamic descriptor, this " +


+ 5
- 6
Svelto.ECS/EnginesRoot.Submission.cs View File

@@ -25,6 +25,7 @@ namespace Svelto.ECS
_transientEntitiesOperations.FastClear();
_transientEntitiesOperations.AddRange(_entitiesOperations);
_entitiesOperations.FastClear();
var entitiesOperations = _transientEntitiesOperations.ToArrayFast();
for (var i = 0; i < _transientEntitiesOperations.Count; i++)
{
@@ -37,8 +38,7 @@ namespace Svelto.ECS
entitiesOperations[i].entityDescriptor,
new EGID(entitiesOperations[i].ID,
entitiesOperations[i].fromGroupID),
new EGID(
entitiesOperations[i].toID,
new EGID(entitiesOperations[i].toID,
entitiesOperations[i].toGroupID));
break;
case EntitySubmitOperationType.Remove:
@@ -164,12 +164,11 @@ namespace Svelto.ECS
}
}

readonly FasterList<EntitySubmitOperation> _entitiesOperations;
readonly DoubleBufferedEntitiesToAdd<FasterDictionary<int, Dictionary<Type, ITypeSafeDictionary>>>
_groupedEntityToAdd;

readonly IEntitySubmissionScheduler _scheduler;
readonly FasterList<EntitySubmitOperation> _transientEntitiesOperations;
readonly IEntitySubmissionScheduler _scheduler;
readonly FasterList<EntitySubmitOperation> _transientEntitiesOperations;
readonly FasterList<EntitySubmitOperation> _entitiesOperations;
}
}

+ 76
- 32
Svelto.ECS/EntitiesDB.cs View File

@@ -3,7 +3,6 @@
#endif

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using Svelto.DataStructures;
@@ -20,37 +19,74 @@ namespace Svelto.ECS.Internal
_groupedGroups = groupedGroups;
}

public ReadOnlyCollectionStruct<T> QueryEntityViews<T>(int @group) where T:class, IEntityStruct
public ReadOnlyCollectionStruct<T> QueryEntityViews<T>(int group) where T:class, IEntityStruct
{
TypeSafeDictionary<T> typeSafeDictionary;
if (QueryEntitySafeDictionary(@group, out typeSafeDictionary) == false) return
new ReadOnlyCollectionStruct<T>(RetrieveEmptyEntityViewArray<T>(), 0);
if (QueryEntitySafeDictionary(group, out TypeSafeDictionary<T> typeSafeDictionary) == false)
return new ReadOnlyCollectionStruct<T>(RetrieveEmptyEntityViewArray<T>(), 0);

return typeSafeDictionary.Values;
}

public ReadOnlyCollectionStruct<T> QueryEntityViews<T>(ExclusiveGroup.ExclusiveGroupStruct @group) where T : class, IEntityStruct
public ReadOnlyCollectionStruct<T> QueryEntityViews<T>(ExclusiveGroup.ExclusiveGroupStruct group) where T : class, IEntityStruct
{
return QueryEntityViews<T>((int) group);
}

public T QueryEntityView<T>(int id, ExclusiveGroup.ExclusiveGroupStruct @group) where T : class, IEntityStruct
public T QueryEntityView<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group) where T : class, IEntityStruct
{
return QueryEntityView<T>(new EGID(id, (int) @group));
return QueryEntityView<T>(new EGID(id, (int) group));
}
public ref T QueryEntity<T>(EGID entityGID) where T : IEntityStruct
{
T[] array;
if ((array = QueryEntitiesAndIndexInternal<T>(entityGID, out var index)) != null)
return ref array[index];
throw new EntityNotFoundException(entityGID.entityID, entityGID.groupID, typeof(T));
}
public ref T QueryEntity<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group) where T : IEntityStruct
{
return ref QueryEntity<T>(new EGID(id, group));
}

public T[] QueryEntities<T>(int @group, out int count) where T : IEntityStruct
public ref T QueryEntity<T>(int id, int group) where T : IEntityStruct
{
return ref QueryEntity<T>(new EGID(id, group));
}

public T[] QueryEntities<T>(int group, out int count) where T : IEntityStruct
{
TypeSafeDictionary<T> typeSafeDictionary;
count = 0;
if (QueryEntitySafeDictionary(@group, out typeSafeDictionary) == false) return RetrieveEmptyEntityViewArray<T>();
if (QueryEntitySafeDictionary(group, out TypeSafeDictionary<T> typeSafeDictionary) == false)
return RetrieveEmptyEntityViewArray<T>();

return typeSafeDictionary.GetValuesArray(out count);
}

public T[] QueryEntities<T>(ExclusiveGroup.ExclusiveGroupStruct groupStruct, out int targetsCount) where T : IEntityStruct
public T[] QueryEntities<T>(ExclusiveGroup.ExclusiveGroupStruct groupStruct, out int count) where T : IEntityStruct
{
return QueryEntities<T>((int) groupStruct, out count);
}

public (T1[], T2[]) QueryEntities<T1, T2>(int @group, out int count) where T1 : IEntityStruct where T2 : IEntityStruct
{
return QueryEntities<T>((int) groupStruct, out targetsCount);
var T1entities = QueryEntities<T1>(group, out var countCheck);
var T2entities = QueryEntities<T2>(group, out count);
if (count != countCheck)
throw new ECSException("Entity views count do not match in group. Entity 1: ".
FastConcat(typeof(T1).ToString()).FastConcat(
"Entity 2: ".FastConcat(typeof(T2).ToString())));

return (T1entities, T2entities);
}

public (T1[], T2[]) QueryEntities<T1, T2>(ExclusiveGroup.ExclusiveGroupStruct groupStruct, out int count) where T1 : IEntityStruct where T2 : IEntityStruct
{
return QueryEntities<T1, T2>((int) groupStruct, out count);
}

public EGIDMapper<T> QueryMappedEntities<T>(int groupID) where T : IEntityStruct
@@ -91,24 +127,24 @@ namespace Svelto.ECS.Internal
return false;
}

public T[] QueryEntitiesAndIndex<T>(int id, ExclusiveGroup.ExclusiveGroupStruct @group, out uint index) where T : IEntityStruct
public T[] QueryEntitiesAndIndex<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group, out uint index) where T : IEntityStruct
{
return QueryEntitiesAndIndex<T>(new EGID(id, group), out index);
}

public bool TryQueryEntitiesAndIndex<T>(int id, ExclusiveGroup.ExclusiveGroupStruct @group, out uint index, out T[] array) where T : IEntityStruct
public bool TryQueryEntitiesAndIndex<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group, out uint index, out T[] array) where T : IEntityStruct
{
return TryQueryEntitiesAndIndex<T>(new EGID(id, group), out index, out array);
return TryQueryEntitiesAndIndex(new EGID(id, group), out index, out array);
}

public T[] QueryEntitiesAndIndex<T>(int id, int @group, out uint index) where T : IEntityStruct
public T[] QueryEntitiesAndIndex<T>(int id, int group, out uint index) where T : IEntityStruct
{
return QueryEntitiesAndIndex<T>(new EGID(id, group), out index);
}

public bool TryQueryEntitiesAndIndex<T>(int id, int @group, out uint index, out T[] array) where T : IEntityStruct
public bool TryQueryEntitiesAndIndex<T>(int id, int group, out uint index, out T[] array) where T : IEntityStruct
{
return TryQueryEntitiesAndIndex<T>(new EGID(id, group), out index, out array);
return TryQueryEntitiesAndIndex(new EGID(id, group), out index, out array);
}

public T QueryEntityView<T>(EGID entityGID) where T : class, IEntityStruct
@@ -137,10 +173,10 @@ namespace Svelto.ECS.Internal
//search for the group
public bool Exists(ExclusiveGroup.ExclusiveGroupStruct gid)
{
return _groupEntityViewsDB.ContainsKey(@gid);
return _groupEntityViewsDB.ContainsKey(gid);
}

public bool HasAny<T>(int @group) where T : IEntityStruct
public bool HasAny<T>(int group) where T : IEntityStruct
{
int count;
QueryEntities<T>(group, out count);
@@ -152,9 +188,18 @@ namespace Svelto.ECS.Internal
return HasAny<T>((int) groupStruct);
}

public IEnumerator IterateUntilEntityExists<T>(ExclusiveGroup @group) where T : IEntityStruct
public int Count<T>(ExclusiveGroup.ExclusiveGroupStruct groupStruct) where T : IEntityStruct
{
int count;
QueryEntities<T>(groupStruct, out count);
return count;
}

public int Count<T>(int groupStruct) where T : IEntityStruct
{
while (HasAny<T>(group) == false) yield return null;
int count;
QueryEntities<T>(groupStruct, out count);
return count;
}

public bool TryQueryEntityView<T>(EGID entityegid, out T entityView) where T : class, IEntityStruct
@@ -162,9 +207,9 @@ namespace Svelto.ECS.Internal
return TryQueryEntityViewInGroupInternal(entityegid, out entityView);
}
public bool TryQueryEntityView<T>(int id, ExclusiveGroup.ExclusiveGroupStruct @group, out T entityView) where T : class, IEntityStruct
public bool TryQueryEntityView<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group, out T entityView) where T : class, IEntityStruct
{
return TryQueryEntityViewInGroupInternal(new EGID(id, (int) @group), out entityView);
return TryQueryEntityViewInGroupInternal(new EGID(id, (int) group), out entityView);
}
bool TryQueryEntityViewInGroupInternal<T>(EGID entityGID, out T entityView) where T:class, IEntityStruct
@@ -173,7 +218,7 @@ namespace Svelto.ECS.Internal
TypeSafeDictionary<T> safeDictionary;
if (QueryEntitySafeDictionary(entityGID.groupID, out safeDictionary) == false) return false;

return safeDictionary.TryGetValue(entityGID.entityID, out entityView) != false;
return safeDictionary.TryGetValue(entityGID.entityID, out entityView);
}

T[] QueryEntitiesAndIndexInternal<T>(EGID entityGID, out uint index) where T : IEntityStruct
@@ -190,13 +235,13 @@ namespace Svelto.ECS.Internal
return safeDictionary.GetValuesArray(out count);
}
bool QueryEntitySafeDictionary<T>(int @group, out TypeSafeDictionary<T> typeSafeDictionary) where T : IEntityStruct
bool QueryEntitySafeDictionary<T>(int group, out TypeSafeDictionary<T> typeSafeDictionary) where T : IEntityStruct
{
Dictionary<Type, ITypeSafeDictionary> entitiesInGroupPerType;
typeSafeDictionary = null;

//search for the group
if (_groupEntityViewsDB.TryGetValue(@group, out entitiesInGroupPerType) == false)
if (_groupEntityViewsDB.TryGetValue(group, out entitiesInGroupPerType) == false)
return false;

//search for the indexed entities in the group
@@ -229,10 +274,9 @@ namespace Svelto.ECS.Internal
return FasterList<T>.DefaultList.ToArrayFast();
}
//grouped set of entity views, this is the standard way to handle entity views
//entity views are grouped per group, then indexable per type, then indexable per EGID.
//however the TypeSafeDictionary can return an array of values directly, that can be
//iterated over, so that is possible to iterate over all the entity views of
//grouped set of entity views, this is the standard way to handle entity views entity views are grouped per
//group, then indexable per type, then indexable per EGID. however the TypeSafeDictionary can return an array of
//values directly, that can be iterated over, so that is possible to iterate over all the entity views of
//a specific type inside a specific group.
readonly FasterDictionary<int, Dictionary<Type, ITypeSafeDictionary>> _groupEntityViewsDB;
//needed to be able to iterate over all the entities of the same type regardless the group


+ 1
- 0
Svelto.ECS/EntityBuilder.cs View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Svelto.DataStructures;
using Svelto.ECS.Hybrid;
using Svelto.ECS.Internal;
using Svelto.Utilities;



+ 93
- 0
Svelto.ECS/EntityStream.cs View File

@@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using Svelto.DataStructures;
using Svelto.ECS.Internal;

namespace Svelto.ECS
{
/// <summary>
/// Do not use this class in place of a normal polling.
/// I eventually realised than in ECS no form of communication other than polling entity components can exist.
/// Using groups, you can have always an optimal set of entity components to poll, so EntityStreams must be used
/// only if:
/// - you want to polling engine to be able to track all the entity changes happening in between polls and not
/// just the current state
/// - you want a thread-safe way to read entity states, which includes all the state changes and not the last
/// one only
/// - you want to communicate between EnginesRoots
/// </summary>
public class EntityStreams
{
public EntityStreams(IEntitiesDB entitiesDb)
{
_entitiesDB = entitiesDb;
}

public EntityStream<T>.Consumer GenerateConsumer<T>(int capacity) where T : unmanaged, IEntityStruct
{
if (_streams.ContainsKey(typeof(T)) == false) _streams[typeof(T)] = new EntityStream<T>();
return (_streams[typeof(T)] as EntityStream<T>).GenerateConsumer(capacity);
}

public void PublishEntity<T>(EGID id) where T : unmanaged, IEntityStruct
{
if (_streams.TryGetValue(typeof(T), out var typeSafeStream))
(typeSafeStream as EntityStream<T>).PublishEntity(ref _entitiesDB.QueryEntity<T>(id));
else
Console.LogWarning("No Consumers are waiting for this entity to change "
.FastConcat(typeof(T).ToString()));
}
Dictionary<Type, ITypeSafeStream> _streams = new Dictionary<Type, ITypeSafeStream>();
IEntitiesDB _entitiesDB;
}

interface ITypeSafeStream
{}

public class EntityStream<T>:ITypeSafeStream where T:unmanaged, IEntityStruct
{
public class Consumer
{
public Consumer(int capacity)
{
_ringBuffer = new RingBuffer<T>(capacity);
_capacity = capacity;
}

public int Count => _ringBuffer.Count;

public void Enqueue(ref T entity)
{
if (_ringBuffer.Count >= _capacity)
throw new Exception("EntityStream capacity has been saturated");
_ringBuffer.Enqueue(ref entity);
}

readonly RingBuffer<T> _ringBuffer;
int _capacity;

public ref T Dequeue()
{
return ref _ringBuffer.Dequeue();
}
}
public void PublishEntity(ref T entity)
{
for (int i = 0; i < _buffers.Count; i++)
_buffers[i].Enqueue(ref entity);
}

public Consumer GenerateConsumer(int capacity)
{
var consumer = new Consumer(capacity);
_buffers.Add(consumer);
return consumer;
}

readonly FasterList<Consumer> _buffers = new FasterList<Consumer>();
}
}

+ 0
- 12
Svelto.ECS/EntityView.cs View File

@@ -37,16 +37,4 @@ namespace Svelto.ECS
entityView = new T { ID = ID };
}
}

[Obsolete("You should only use IEntityViewStruct or IEntityStructs struct implementations now")]
public class EntityView : IEntityViewStruct
{
public EGID ID
{
get { return _ID; }
set { _ID = value; }
}

EGID _ID;
}
}

+ 19
- 1
Svelto.ECS/ExclusiveGroups.cs View File

@@ -24,6 +24,13 @@ namespace Svelto.ECS
_group = ExclusiveGroupStruct.Generate();
}
public ExclusiveGroup(string recognizeAs)
{
_group = ExclusiveGroupStruct.Generate();
_serialisedGroups.Add(recognizeAs, _group);
}
public ExclusiveGroup(ushort range)
{
_group = new ExclusiveGroupStruct(range);
@@ -36,7 +43,7 @@ namespace Svelto.ECS
public static explicit operator int(ExclusiveGroup group)
{
return @group._group;
return group._group;
}

public static ExclusiveGroupStruct operator+(ExclusiveGroup a, int b)
@@ -123,5 +130,16 @@ namespace Svelto.ECS
int _id;
static uint _globalId;
}

public static ExclusiveGroupStruct Search(string holderGroupName)
{
if (_serialisedGroups.ContainsKey(holderGroupName) == false)
throw new Exception("Serialized Group Not Found ".FastConcat(holderGroupName));
return _serialisedGroups[holderGroupName];
}

static readonly Dictionary<string, ExclusiveGroupStruct> _serialisedGroups = new Dictionary<string,
ExclusiveGroupStruct>();
}
}

+ 33
- 36
Svelto.ECS/ExecuteOnEntitiesDB.cs View File

@@ -1,21 +1,21 @@
using Svelto.DataStructures.Experimental;

namespace Svelto.ECS.Internal
{
partial class EntitiesDB
{
public void ExecuteOnEntity<T>(int id, ExclusiveGroup.ExclusiveGroupStruct groupid, EntityAction<T> action) where T : IEntityStruct
public void ExecuteOnEntity<T>(int id,
ExclusiveGroup.ExclusiveGroupStruct groupid,
EntityAction<T> action) where T : IEntityStruct
{
ExecuteOnEntity(id, (int)groupid, action);
}

public void ExecuteOnEntity<T, W>(EGID entityGID, ref W value, EntityAction<T, W> action) where T : IEntityStruct
public void ExecuteOnEntity<T, W>(EGID entityGID, ref W value, EntityAction<T, W> action) where T: IEntityStruct
{
TypeSafeDictionary<T> casted;
if (QueryEntitySafeDictionary(entityGID.groupID, out casted))
{
if (casted != null)
if (casted.ExecuteOnEntityView(entityGID.entityID, ref value, action) == true)
if (casted.ExecuteOnEntityView(entityGID.entityID, ref value, action))
return;
}

@@ -28,7 +28,7 @@ namespace Svelto.ECS.Internal
if (QueryEntitySafeDictionary(entityGID.groupID, out casted))
{
if (casted != null)
if (casted.ExecuteOnEntityView(entityGID.entityID, action) == true)
if (casted.ExecuteOnEntityView(entityGID.entityID, action))
return;
}

@@ -46,7 +46,10 @@ namespace Svelto.ECS.Internal
ExecuteOnEntity(new EGID(id, groupid), ref value, action);
}

public void ExecuteOnEntity<T, W>(int id, ExclusiveGroup.ExclusiveGroupStruct groupid, ref W value, EntityAction<T, W> action) where T : IEntityStruct
public void ExecuteOnEntity<T, W>(int id,
ExclusiveGroup.ExclusiveGroupStruct groupid,
ref W value,
EntityAction<T, W> action) where T : IEntityStruct
{
ExecuteOnEntity(id, (int)groupid, ref value, action);
}
@@ -55,38 +58,36 @@ namespace Svelto.ECS.Internal

public void ExecuteOnEntities<T>(int groupID, EntitiesAction<T> action) where T : IEntityStruct
{
int count;
TypeSafeDictionary<T> typeSafeDictionary;
if (QueryEntitySafeDictionary(@groupID, out typeSafeDictionary) == false) return;
if (QueryEntitySafeDictionary(groupID, out TypeSafeDictionary<T> typeSafeDictionary) == false) return;

var entities = typeSafeDictionary.GetValuesArray(out count);
var entities = typeSafeDictionary.GetValuesArray(out var count);

for (var i = 0; i < count; i++)
action(ref entities[i], this, i);
action(ref entities[i], new EntityActionData(this, i));

SafetyChecks(typeSafeDictionary, count);
}

public void ExecuteOnEntities<T>(ExclusiveGroup.ExclusiveGroupStruct groupStructId, EntitiesAction<T> action) where T : IEntityStruct
public void ExecuteOnEntities<T>(ExclusiveGroup.ExclusiveGroupStruct groupStructId,
EntitiesAction<T> action) where T : IEntityStruct
{
ExecuteOnEntities((int)groupStructId, action);
}

public void ExecuteOnEntities<T, W>(int groupID, ref W value, EntitiesAction<T, W> action) where T : IEntityStruct
public void ExecuteOnEntities<T, W>(int groupID, ref W value, EntitiesAction<T, W> action) where T:IEntityStruct
{
int count;
TypeSafeDictionary<T> typeSafeDictionary;
if (QueryEntitySafeDictionary(@groupID, out typeSafeDictionary) == false) return;
if (QueryEntitySafeDictionary(groupID, out TypeSafeDictionary<T> typeSafeDictionary) == false) return;

var entities = typeSafeDictionary.GetValuesArray(out count);
var entities = typeSafeDictionary.GetValuesArray(out var count);

for (var i = 0; i < count; i++)
action(ref entities[i], ref value, this, i);
action(ref entities[i], ref value, new EntityActionData(this, i));

SafetyChecks(typeSafeDictionary, count);
}

public void ExecuteOnEntities<T, W>(ExclusiveGroup.ExclusiveGroupStruct groupStructId, ref W value, EntitiesAction<T, W> action) where T : IEntityStruct
public void ExecuteOnEntities<T, W>(ExclusiveGroup.ExclusiveGroupStruct groupStructId,
ref W value, EntitiesAction<T, W> action) where T : IEntityStruct
{
ExecuteOnEntities((int)groupStructId, ref value, action);
}
@@ -95,21 +96,18 @@ namespace Svelto.ECS.Internal
public void ExecuteOnAllEntities<T>(AllEntitiesAction<T> action) where T : IEntityStruct
{
var type = typeof(T);
FasterDictionary<int, ITypeSafeDictionary> dic;
var type = typeof(T);

if (_groupedGroups.TryGetValue(type, out dic))
if (_groupedGroups.TryGetValue(type, out var dic))
{
int count;
var typeSafeDictionaries = dic.GetValuesArray(out count);
var typeSafeDictionaries = dic.GetValuesArray(out var count);

for (int j = 0; j < count; j++)
{
int innerCount;
var typeSafeDictionary = typeSafeDictionaries[j];
var casted = typeSafeDictionary as TypeSafeDictionary<T>;

var entities = casted.GetValuesArray(out innerCount);
var entities = casted.GetValuesArray(out var innerCount);

for (int i = 0; i < innerCount; i++)
action(ref entities[i], this);
@@ -121,21 +119,18 @@ namespace Svelto.ECS.Internal

public void ExecuteOnAllEntities<T, W>(ref W value, AllEntitiesAction<T, W> action) where T : IEntityStruct
{
var type = typeof(T);
FasterDictionary<int, ITypeSafeDictionary> dic;
var type = typeof(T);

if (_groupedGroups.TryGetValue(type, out dic))
if (_groupedGroups.TryGetValue(type, out var dic))
{
int count;
var typeSafeDictionaries = dic.GetValuesArray(out count);
var typeSafeDictionaries = dic.GetValuesArray(out var count);

for (int j = 0; j < count; j++)
{
int innerCount;
var typeSafeDictionary = typeSafeDictionaries[j];
var casted = typeSafeDictionary as TypeSafeDictionary<T>;

var entities = casted.GetValuesArray(out innerCount);
var entities = casted.GetValuesArray(out var innerCount);

for (int i = 0; i < innerCount; i++)
action(ref entities[i], ref value, this);
@@ -145,7 +140,7 @@ namespace Svelto.ECS.Internal
}
}

public void ExecuteOnAllEntities<T>(Svelto.ECS.ExclusiveGroup[] groups, EntitiesAction<T> action) where T : IEntityStruct
public void ExecuteOnAllEntities<T>(ExclusiveGroup[] groups, EntitiesAction<T> action) where T : IEntityStruct
{
foreach (var group in groups)
{
@@ -153,7 +148,9 @@ namespace Svelto.ECS.Internal
}
}

public void ExecuteOnAllEntities<T, W>(Svelto.ECS.ExclusiveGroup[] groups, ref W value, EntitiesAction<T, W> action) where T : IEntityStruct
public void ExecuteOnAllEntities<T, W>(ExclusiveGroup[] groups,
ref W value,
EntitiesAction<T, W> action) where T : IEntityStruct
{
foreach (var group in groups)
{


+ 8
- 1
Svelto.ECS/Extensions/Unity/GenericEntityDescriptorHolder.cs View File

@@ -1,14 +1,21 @@
using UnityEngine;

#if UNITY_5 || UNITY_5_3_OR_NEWER
namespace Svelto.ECS.Unity
{
public class GenericEntityDescriptorHolder<T>:
UnityEngine.MonoBehaviour , IEntityDescriptorHolder
MonoBehaviour , IEntityDescriptorHolder
where T: IEntityDescriptor, new()
{
public IEntityDescriptor GetDescriptor()
{
return EntityDescriptorTemplate<T>.descriptor;
}

public string groupName => _groupName;

[SerializeField]
string _groupName;
}
}
#endif

+ 12
- 6
Svelto.ECS/Extensions/Unity/SveltoEntityFactoryForUnity.cs View File

@@ -1,22 +1,23 @@
#if UNITY_5 || UNITY_5_3_OR_NEWER
using Svelto.Context;
using UnityEngine;

namespace Svelto.ECS.Unity
{
public static class SveltoEntityFactoryForUnity
{
public static void Create<T>(EGID ID, UnityContext contextHolder,
IEntityFactory factory) where T : MonoBehaviour, IEntityDescriptorHolder
public static T Create<T>(EGID ID, Transform contextHolder,
IEntityFactory factory) where T : MonoBehaviour, IEntityDescriptorHolder
{
var holder = contextHolder.GetComponentInChildren<T>(true);
var implementors = holder.GetComponents<IImplementor>();

factory.BuildEntity(ID, holder.GetDescriptor(), implementors);

return holder;
}
public static void CreateAll<T>(ExclusiveGroup group, UnityContext contextHolder,
IEntityFactory factory) where T : MonoBehaviour, IEntityDescriptorHolder
public static void CreateAll<T>(ExclusiveGroup group, Transform contextHolder,
IEntityFactory factory) where T : MonoBehaviour, IEntityDescriptorHolder
{
var holders = contextHolder.GetComponentsInChildren<T>(true);

@@ -24,7 +25,12 @@ namespace Svelto.ECS.Unity
{
var implementors = holder.GetComponents<IImplementor>();

factory.BuildEntity(holder.GetInstanceID(), group, holder.GetDescriptor(), implementors);
ExclusiveGroup.ExclusiveGroupStruct realGroup = group;

if (string.IsNullOrEmpty( holder.groupName) == false)
realGroup = ExclusiveGroup.Search(holder.groupName);

factory.BuildEntity(holder.GetInstanceID(), realGroup, holder.GetDescriptor(), implementors);
}
}
}


+ 39
- 43
Svelto.ECS/IEntitiesDB.cs View File

@@ -1,31 +1,23 @@
using System.Collections;
using Svelto.DataStructures;

namespace Svelto.ECS
{
public interface IEntitiesDB
public interface IEntitiesDB: IObsoleteInterfaceDb
{
/// <summary>
/// All the EntityView related methods are left for back compatibility, but
/// shouldn't be used anymore. Always pick EntityViewStruct or EntityStruct
/// over EntityView
/// </summary>
ReadOnlyCollectionStruct<T> QueryEntityViews<T>(int group) where T : class, IEntityStruct;
ReadOnlyCollectionStruct<T> QueryEntityViews<T>(ExclusiveGroup.ExclusiveGroupStruct group) where T : class, IEntityStruct;
/// <summary>
/// All the EntityView related methods are left for back compatibility, but
/// shouldn't be used anymore. Always pick EntityViewStruct or EntityStruct
/// over EntityView
/// </summary>
bool TryQueryEntityView<T>(EGID egid, out T entityView) where T : class, IEntityStruct;
bool TryQueryEntityView<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group, out T entityView) where T : class, IEntityStruct;
/// <summary>
/// All the EntityView related methods are left for back compatibility, but
/// shouldn't be used anymore. Always pick EntityViewStruct or EntityStruct
/// over EntityView
/// ECS is meant to work on a set of Entities. Working on a single entity is sometime necessary, but using
/// the following functions inside a loop would be a mistake as performance can be significantly impacted
/// return the buffer and the index of the entity inside the buffer using the input EGID
/// </summary>
T QueryEntityView<T>(EGID egid) where T : class, IEntityStruct;
T QueryEntityView<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group) where T : class, IEntityStruct;
/// <param name="entityGid"></param>
/// <param name="index"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
bool TryQueryEntitiesAndIndex<T>(int id, int group, out uint index, out T[] array) where T : IEntityStruct;
bool TryQueryEntitiesAndIndex<T>(EGID entityGid, out uint index, out T[] array) where T : IEntityStruct;
bool TryQueryEntitiesAndIndex<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group, out uint index, out T[] array) where T : IEntityStruct;
ref T QueryEntity<T>(EGID entityGid) where T : IEntityStruct;
ref T QueryEntity<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group) where T : IEntityStruct;
ref T QueryEntity<T>(int id, int group) where T : IEntityStruct;
/// <summary>
/// Fast and raw (therefore not safe) return of entities buffer
/// Modifying a buffer would compromise the integrity of the whole DB
@@ -35,7 +27,12 @@ namespace Svelto.ECS
/// <typeparam name="T"></typeparam>
/// <returns></returns>
T[] QueryEntities<T>(int group, out int count) where T : IEntityStruct;
T[] QueryEntities<T>(ExclusiveGroup.ExclusiveGroupStruct groupStruct, out int targetsCount) where T : IEntityStruct;

T[] QueryEntities<T>(ExclusiveGroup.ExclusiveGroupStruct groupStruct, out int count) where T : IEntityStruct;
(T1[], T2[]) QueryEntities<T1, T2>(int group, out int count) where T1 : IEntityStruct where T2 : IEntityStruct;

(T1[], T2[]) QueryEntities<T1, T2>(ExclusiveGroup.ExclusiveGroupStruct groupStruct, out int count)
where T1 : IEntityStruct where T2 : IEntityStruct;
/// <summary>
/// this version returns a mapped version of the entity array so that is possible to find the
/// index of the entity inside the returned buffer through it's EGID
@@ -76,21 +73,6 @@ namespace Svelto.ECS
/// <summary>
/// ECS is meant to work on a set of Entities. Working on a single entity is sometime necessary, but using
/// the following functions inside a loop would be a mistake as performance can be significantly impacted
/// return the buffer and the index of the entity inside the buffer using the input EGID
/// </summary>
/// <param name="entityGid"></param>
/// <param name="index"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
T[] QueryEntitiesAndIndex<T>(EGID entityGid, out uint index) where T : IEntityStruct;
bool TryQueryEntitiesAndIndex<T>(EGID entityGid, out uint index, out T[] array) where T : IEntityStruct;
T[] QueryEntitiesAndIndex<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group, out uint index) where T : IEntityStruct;
bool TryQueryEntitiesAndIndex<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group, out uint index, out T[] array) where T : IEntityStruct;
T[] QueryEntitiesAndIndex<T>(int id, int group, out uint index) where T : IEntityStruct;
bool TryQueryEntitiesAndIndex<T>(int id, int group, out uint index, out T[] array) where T : IEntityStruct;
/// <summary>
/// ECS is meant to work on a set of Entities. Working on a single entity is sometime necessary, but using
/// the following functions inside a loop would be a mistake as performance can be significantly impacted
/// Execute an action on a specific Entity. Be sure that the action is not capturing variables
/// otherwise you will allocate memory which will have a great impact on the execution performance
/// </summary>
@@ -108,9 +90,11 @@ namespace Svelto.ECS
bool Exists<T>(int id, int groupid) where T : IEntityStruct;
bool Exists (ExclusiveGroup.ExclusiveGroupStruct gid);
bool HasAny<T>(int group) where T:IEntityStruct;
bool HasAny<T>(int group) where T:IEntityStruct;
bool HasAny<T>(ExclusiveGroup.ExclusiveGroupStruct groupStruct) where T:IEntityStruct;
IEnumerator IterateUntilEntityExists<T>(ExclusiveGroup group) where T:IEntityStruct;
int Count<T>(ExclusiveGroup.ExclusiveGroupStruct groupStruct) where T:IEntityStruct;
int Count<T>(int groupStruct) where T:IEntityStruct;
}

public delegate void EntityAction<T, W>(ref T target, ref W value);
@@ -119,6 +103,18 @@ namespace Svelto.ECS
public delegate void AllEntitiesAction<T, W>(ref T target, ref W value, IEntitiesDB entitiesDb);
public delegate void AllEntitiesAction<T>(ref T target, IEntitiesDB entitiesDb);
public delegate void EntitiesAction<T, W>(ref T target, ref W value, IEntitiesDB entitiesDb, int index);
public delegate void EntitiesAction<T>(ref T target, IEntitiesDB entitiesDb, int index);
public delegate void EntitiesAction<T, W>(ref T target, ref W value, EntityActionData extraParams);
public delegate void EntitiesAction<T>(ref T target, EntityActionData extraParams);

public struct EntityActionData
{
public readonly IEntitiesDB entitiesDB;
public readonly int entityIndex;

public EntityActionData(IEntitiesDB entitiesDb, int index)
{
this.entitiesDB = entitiesDb;
entityIndex = index;
}
}
}

+ 2
- 0
Svelto.ECS/IEntityDescriptorHolder.cs View File

@@ -3,5 +3,7 @@ namespace Svelto.ECS
public interface IEntityDescriptorHolder
{
IEntityDescriptor GetDescriptor();
string groupName { get; }
}
}

+ 1
- 1
Svelto.ECS/IEntityViewStruct.cs View File

@@ -1,4 +1,4 @@
namespace Svelto.ECS
namespace Svelto.ECS.Hybrid
{
///<summary>EntityViewStructs MUST implement IEntityViewStruct</summary>
public interface IEntityViewStruct:IEntityStruct


+ 51
- 0
Svelto.ECS/IObsoleteInterfaceDb.cs View File

@@ -0,0 +1,51 @@
using System;
using Svelto.DataStructures;

namespace Svelto.ECS
{
public interface IObsoleteInterfaceDb
{
/// <summary>
/// All the EntityView related methods are left for back compatibility, but
/// shouldn't be used anymore. Always pick EntityViewStruct or EntityStruct
/// over EntityView
/// </summary>
[Obsolete]
ReadOnlyCollectionStruct<T> QueryEntityViews<T>(int group) where T : class, IEntityStruct;
[Obsolete]
ReadOnlyCollectionStruct<T> QueryEntityViews<T>(ExclusiveGroup.ExclusiveGroupStruct group) where T : class, IEntityStruct;
/// <summary>
/// All the EntityView related methods are left for back compatibility, but
/// shouldn't be used anymore. Always pick EntityViewStruct or EntityStruct
/// over EntityView
/// </summary>
[Obsolete]
bool TryQueryEntityView<T>(EGID egid, out T entityView) where T : class, IEntityStruct;
[Obsolete]
bool TryQueryEntityView<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group, out T entityView) where T : class, IEntityStruct;
/// <summary>
/// All the EntityView related methods are left for back compatibility, but
/// shouldn't be used anymore. Always pick EntityViewStruct or EntityStruct
/// over EntityView
/// </summary>
[Obsolete]
T QueryEntityView<T>(EGID egid) where T : class, IEntityStruct;
[Obsolete]
T QueryEntityView<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group) where T : class, IEntityStruct;
/// <summary>
/// ECS is meant to work on a set of Entities. Working on a single entity is sometime necessary, but using
/// the following functions inside a loop would be a mistake as performance can be significantly impacted
/// return the buffer and the index of the entity inside the buffer using the input EGID
/// </summary>
/// <param name="entityGid"></param>
/// <param name="index"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[Obsolete]
T[] QueryEntitiesAndIndex<T>(EGID entityGid, out uint index) where T : IEntityStruct;
[Obsolete]
T[] QueryEntitiesAndIndex<T>(int id, ExclusiveGroup.ExclusiveGroupStruct group, out uint index) where T : IEntityStruct;
[Obsolete]
T[] QueryEntitiesAndIndex<T>(int id, int group, out uint index) where T : IEntityStruct;
}
}

Loading…
Cancel
Save