Browse Source

refactor platform profiler

entity structs cannot support strings anymore (use ECSString instead)
tags/2.8
sebas77 5 years ago
parent
commit
f9e8cacd35
10 changed files with 88 additions and 74 deletions
  1. +0
    -2
      Svelto.ECS.Components/Components/ExtensionMethodsUECS.cs
  2. +11
    -1
      Svelto.ECS.Components/ECSResources/StringECSDB.cs
  3. +19
    -23
      Svelto.ECS/DataStructures/TypeSafeDictionary.cs
  4. +6
    -0
      Svelto.ECS/DynamicEntityDescriptor.cs
  5. +9
    -12
      Svelto.ECS/EnginesRoot.Entities.cs
  6. +3
    -4
      Svelto.ECS/EnginesRoot.Submission.cs
  7. +0
    -2
      Svelto.ECS/EntityBuilder.CheckFields.cs
  8. +15
    -19
      Svelto.ECS/EntityStream.cs
  9. +6
    -1
      Svelto.ECS/ExtendibleEntityDescriptor.cs
  10. +19
    -10
      Svelto.ECS/Extensions/Unity/SveltoGUIHelper.cs

+ 0
- 2
Svelto.ECS.Components/Components/ExtensionMethodsUECS.cs View File

@@ -36,8 +36,6 @@ public static partial class ExtensionMethods
public static void ProjectOnPlane(ref this float3 vector, in float3 planeNormal)
{
var num1 = math.dot(planeNormal,planeNormal);
if ((double) num1 < (double) Mathf.Epsilon)
return;
var num2 = math.dot(vector,planeNormal) / num1;
vector.x -= planeNormal.x * num2;


+ 11
- 1
Svelto.ECS.Components/ECSResources/StringECSDB.cs View File

@@ -3,10 +3,20 @@ namespace Svelto.ECS.Experimental
public struct ECSString
{
internal uint id;

ECSString(uint toEcs)
{
id = toEcs;
}

public static implicit operator string(ECSString ecsString)
{
return ResourcesECSDB<string>.FromECS(ecsString.id);
}
public static implicit operator ECSString(string text)
{
return new ECSString(ResourcesECSDB<string>.ToECS(text));
}
}
}

+ 19
- 23
Svelto.ECS/DataStructures/TypeSafeDictionary.cs View File

@@ -2,8 +2,7 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Svelto.Common;
using Svelto.Common.Internal;
using Svelto.DataStructures;
using Svelto.DataStructures;
using Svelto.DataStructures.Experimental;

namespace Svelto.ECS.Internal
@@ -14,17 +13,15 @@ namespace Svelto.ECS.Internal
ITypeSafeDictionary Create();

void RemoveEntitiesFromEngines(
Dictionary<Type, FasterList<IEngine>> entityViewEnginesDB,
ref PlatformProfiler profiler);
Dictionary<Type, FasterList<IEngine>> entityViewEnginesDB, in PlatformProfiler profiler);

void MoveEntityFromDictionaryAndEngines(EGID fromEntityGid, EGID? toEntityID, ITypeSafeDictionary toGroup,
Dictionary<Type, FasterList<IEngine>> engines,
ref PlatformProfiler profiler);
Dictionary<Type, FasterList<IEngine>> engines, in PlatformProfiler profiler);

void AddEntitiesFromDictionary(ITypeSafeDictionary entitiesToSubmit, uint groupId);

void AddEntitiesToEngines(Dictionary<Type, FasterList<IEngine>> entityViewEnginesDb,
ITypeSafeDictionary realDic, ref PlatformProfiler profiler);
ITypeSafeDictionary realDic, in PlatformProfiler profiler);

void SetCapacity(uint size);
void Trim();
@@ -32,7 +29,8 @@ namespace Svelto.ECS.Internal
bool Has(uint entityIdEntityId);
}

class TypeSafeDictionary<TValue> : FasterDictionary<uint, TValue>, ITypeSafeDictionary where TValue : struct, IEntityStruct
class TypeSafeDictionary<TValue> : FasterDictionary<uint, TValue>,
ITypeSafeDictionary where TValue : struct, IEntityStruct
{
static readonly Type _type = typeof(TValue);
static readonly string _typeName = _type.Name;
@@ -70,29 +68,28 @@ namespace Svelto.ECS.Internal

public void AddEntitiesToEngines(
Dictionary<Type, FasterList<IEngine>> entityViewEnginesDB,
ITypeSafeDictionary realDic, ref PlatformProfiler profiler)
ITypeSafeDictionary realDic, in PlatformProfiler profiler)
{
foreach (var value in this)
{
var typeSafeDictionary = realDic as TypeSafeDictionary<TValue>;
AddEntityViewToEngines(entityViewEnginesDB, ref typeSafeDictionary.GetValueByRef(value.Key), null,
ref profiler);
in profiler);
}
}

public bool Has(uint entityIdEntityId) { return ContainsKey(entityIdEntityId); }

public void MoveEntityFromDictionaryAndEngines(EGID fromEntityGid, EGID? toEntityID,
ITypeSafeDictionary toGroup,
Dictionary<Type, FasterList<IEngine>> engines,
ref PlatformProfiler profiler)
ITypeSafeDictionary toGroup, Dictionary<Type, FasterList<IEngine>> engines,
in PlatformProfiler profiler)
{
var valueIndex = GetValueIndex(fromEntityGid.entityID);

if (toGroup != null)
{
RemoveEntityViewFromEngines(engines, ref _values[valueIndex], fromEntityGid.groupID, ref profiler);
RemoveEntityViewFromEngines(engines, ref _values[valueIndex], fromEntityGid.groupID, in profiler);
var toGroupCasted = toGroup as TypeSafeDictionary<TValue>;
ref var entity = ref _values[valueIndex];
@@ -114,10 +111,10 @@ namespace Svelto.ECS.Internal
var index = toGroupCasted.Add(fromEntityGid.entityID, ref entity);

AddEntityViewToEngines(engines, ref toGroupCasted._values[index], previousGroup,
ref profiler);
in profiler);
}
else
RemoveEntityViewFromEngines(engines, ref _values[valueIndex], null, ref profiler);
RemoveEntityViewFromEngines(engines, ref _values[valueIndex], null, in profiler);


Remove(fromEntityGid.entityID);
@@ -125,20 +122,20 @@ namespace Svelto.ECS.Internal

public void RemoveEntitiesFromEngines(
Dictionary<Type, FasterList<IEngine>> entityViewEnginesDB,
ref PlatformProfiler profiler)
in PlatformProfiler profiler)
{
var values = GetValuesArray(out var count);

for (var i = 0; i < count; i++)
RemoveEntityViewFromEngines(entityViewEnginesDB, ref values[i], null, ref profiler);
RemoveEntityViewFromEngines(entityViewEnginesDB, ref values[i], null, in profiler);
}

public ITypeSafeDictionary Create() { return new TypeSafeDictionary<TValue>(); }

void AddEntityViewToEngines(Dictionary<Type, FasterList<IEngine>> entityViewEnginesDB,
ref TValue entity,
ExclusiveGroup.ExclusiveGroupStruct? previousGroup,
ref PlatformProfiler profiler)
ref TValue entity,
ExclusiveGroup.ExclusiveGroupStruct? previousGroup,
in PlatformProfiler profiler)
{
//get all the engines linked to TValue
if (!entityViewEnginesDB.TryGetValue(_type, out var entityViewsEngines)) return;
@@ -179,8 +176,7 @@ namespace Svelto.ECS.Internal

static void RemoveEntityViewFromEngines(
Dictionary<Type, FasterList<IEngine>> entityViewEnginesDB, ref TValue entity,
ExclusiveGroup.ExclusiveGroupStruct? previousGroup,
ref PlatformProfiler profiler)
ExclusiveGroup.ExclusiveGroupStruct? previousGroup, in PlatformProfiler profiler)
{
if (!entityViewEnginesDB.TryGetValue(_type, out var entityViewsEngines)) return;



+ 6
- 0
Svelto.ECS/DynamicEntityDescriptor.cs View File

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

namespace Svelto.ECS
{
/// <summary>
/// DynamicEntityDescriptor can be used to add entity views to an existing EntityDescriptor that act as flags,
/// at building time.
/// This method allocates, so it shouldn't be abused
/// </summary>
/// <typeparam name="TType"></typeparam>
public struct DynamicEntityDescriptor<TType>:IEntityDescriptor where TType : IEntityDescriptor, new()
{
public DynamicEntityDescriptor(IEntityBuilder[] extraEntities)


+ 9
- 12
Svelto.ECS/EnginesRoot.Entities.cs View File

@@ -16,15 +16,14 @@ namespace Svelto.ECS
/// </summary>
public void Dispose()
{
var profiler = new PlatformProfiler();
using (profiler.StartNewSession("Final Dispose"))
using (var profiler = new PlatformProfiler("Final Dispose"))
{
foreach (var groups in _groupEntityDB)
foreach (var entityList in groups.Value)
{
try
{
entityList.Value.RemoveEntitiesFromEngines(_reactiveEnginesAddRemove, ref profiler);
entityList.Value.RemoveEntitiesFromEngines(_reactiveEnginesAddRemove, profiler);
}
catch (Exception e)
{
@@ -136,8 +135,7 @@ namespace Svelto.ECS
///
void MoveEntity(IEntityBuilder[] entityBuilders, EGID fromEntityGID, Type originalDescriptorType, EGID? toEntityGID)
{
var profiler = new PlatformProfiler();
using (profiler.StartNewSession("Move Entity"))
using (var sampler = new PlatformProfiler("Move Entity"))
{
//for each entity view generated by the entity descriptor
if (_groupEntityDB.TryGetValue(fromEntityGID.groupID, out var fromGroup) == false)
@@ -167,7 +165,7 @@ namespace Svelto.ECS

for (int i = 0; i < entitiesToMove.Length; i++)
MoveEntityView(fromEntityGID, toEntityGID, toGroup, ref fromGroup,
entitiesToMove[i].GetEntityType(), profiler);
entitiesToMove[i].GetEntityType(), sampler);
}
//otherwise it's a normal static entity descriptor
else
@@ -191,13 +189,13 @@ namespace Svelto.ECS

for (var i = 0; i < entityBuilders.Length; i++)
MoveEntityView(fromEntityGID, toEntityGID, toGroup, ref fromGroup,
entityBuilders[i].GetEntityType(), profiler);
entityBuilders[i].GetEntityType(), sampler);
}
}
}

void MoveEntityView(EGID entityGID, EGID? toEntityGID, Dictionary<Type, ITypeSafeDictionary> toGroup,
ref Dictionary<Type, ITypeSafeDictionary> fromGroup, Type entityViewType, PlatformProfiler profiler)
ref Dictionary<Type, ITypeSafeDictionary> fromGroup, Type entityViewType, in PlatformProfiler profiler)
{
if (fromGroup.TryGetValue(entityViewType, out var fromTypeSafeDictionary) == false)
{
@@ -231,7 +229,7 @@ namespace Svelto.ECS
toEntitiesDictionary,
toEntityGID == null ? _reactiveEnginesAddRemove :
_reactiveEnginesSwap,
ref profiler);
in profiler);

if (fromTypeSafeDictionary.Count == 0) //clean up
{
@@ -263,14 +261,13 @@ namespace Svelto.ECS

void RemoveGroupAndEntitiesFromDB(uint groupID)
{
var profiler = new PlatformProfiler();
using (profiler.StartNewSession("Remove Group"))
using (var profiler = new PlatformProfiler("Remove Group"))
{
var dictionariesOfEntities = _groupEntityDB[groupID];
foreach (var dictionaryOfEntities in dictionariesOfEntities)
{
var platformProfiler = profiler;
dictionaryOfEntities.Value.RemoveEntitiesFromEngines(_reactiveEnginesAddRemove, ref platformProfiler);
dictionaryOfEntities.Value.RemoveEntitiesFromEngines(_reactiveEnginesAddRemove, platformProfiler);
var groupedGroupOfEntities = _groupsPerEntity[dictionaryOfEntities.Key];
groupedGroupOfEntities.Remove(groupID);
}


+ 3
- 4
Svelto.ECS/EnginesRoot.Submission.cs View File

@@ -14,8 +14,7 @@ namespace Svelto.ECS
void SubmitEntityViews()
{
var profiler = new PlatformProfiler();
using (profiler.StartNewSession("Svelto.ECS - Entities Submission"))
using (var profiler = new PlatformProfiler("Svelto.ECS - Entities Submission"))
{
if (_entitiesOperations.Count > 0)
{
@@ -102,7 +101,7 @@ namespace Svelto.ECS
}

void AddEntityViewsToTheDBAndSuitableEngines(DoubleBufferedEntitiesToAdd dbgroupsOfEntitiesToSubmit,
PlatformProfiler profiler)
in PlatformProfiler profiler)
{
//each group is indexed by entity view type. for each type there is a dictionary indexed by entityID
var groupsOfEntitiesToSubmit = dbgroupsOfEntitiesToSubmit.other;
@@ -148,7 +147,7 @@ namespace Svelto.ECS
{
var realDic = groupDB[entityViewsPerType.Key];
entityViewsPerType.Value.AddEntitiesToEngines(_reactiveEnginesAddRemove, realDic, ref profiler);
entityViewsPerType.Value.AddEntitiesToEngines(_reactiveEnginesAddRemove, realDic, in profiler);
}
}
}


+ 0
- 2
Svelto.ECS/EntityBuilder.CheckFields.cs View File

@@ -29,8 +29,6 @@ namespace Svelto.ECS
var field = fields[i];
var fieldFieldType = field.FieldType;
if (fieldFieldType == STRINGTYPE) continue;

SubCheckFields(fieldFieldType);
}
}


+ 15
- 19
Svelto.ECS/EntityStream.cs View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Svelto.DataStructures;
using Svelto.ECS.Internal;

namespace Svelto.ECS
{
@@ -14,27 +15,27 @@ namespace Svelto.ECS
/// 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
/// - you want to communicate between EnginesRoots
/// </summary>
class EntitiesStream
{
internal Consumer<T> GenerateConsumer<T>(string name, 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(name, capacity);
}

internal void PublishEntity<T>(ref T entity) where T : unmanaged, IEntityStruct
{
if (_streams.TryGetValue(typeof(T), out var typeSafeStream))
if (_streams.TryGetValue(typeof(T), out var typeSafeStream))
(typeSafeStream as EntityStream<T>).PublishEntity(ref entity);
else
Console.LogWarning("No Consumers are waiting for this entity to change "
.FastConcat(typeof(T).ToString()));
Console.LogWarningDebug("No Consumers are waiting for this entity to change ", typeof(T));
}

readonly ConcurrentDictionary<Type, ITypeSafeStream> _streams = new ConcurrentDictionary<Type, ITypeSafeStream>();
readonly ConcurrentDictionary<Type, ITypeSafeStream> _streams =
new ConcurrentDictionary<Type, ITypeSafeStream>();
}

interface ITypeSafeStream
@@ -54,10 +55,10 @@ namespace Svelto.ECS
_buffers.Add(consumer);
return consumer;
}
public void RemoveConsumer(Consumer<T> consumer)
{
_buffers.UnorderedRemove(consumer);
_buffers.UnorderedRemove(consumer);
}

readonly FasterListThreadSafe<Consumer<T>> _buffers = new FasterListThreadSafe<Consumer<T>>();
@@ -77,20 +78,15 @@ namespace Svelto.ECS
_ringBuffer.Enqueue(ref entity, _name);
}
/// <summary>
/// this can be better, I probably would need to get the group regardless if it supports EGID or not
/// </summary>
/// <param name="group"></param>
/// <param name="entity"></param>
/// <returns></returns>
public bool TryDequeue(ExclusiveGroup group, out T entity)
{
if (_ringBuffer.TryDequeue(out entity, _name) == true)
{
if (EntityBuilder<T>.HAS_EGID)
return (entity as INeedEGID).ID.groupID == @group;

return true;
throw new ECSException(
"When an exclusive group is defined, TryDeque must operate on an entity with EGID");
}

return false;
@@ -99,10 +95,10 @@ namespace Svelto.ECS
public bool TryDequeue(out T entity) { return _ringBuffer.TryDequeue(out entity, _name); }
public void Flush() { _ringBuffer.Reset(); }
public void Dispose() { _stream.RemoveConsumer(this); }
readonly RingBuffer<T> _ringBuffer;
readonly EntityStream<T> _stream;
readonly string _name;
}
}
}

+ 6
- 1
Svelto.ECS/ExtendibleEntityDescriptor.cs View File

@@ -1,5 +1,10 @@
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
/// </summary>
/// <typeparam name="TType"></typeparam>
public abstract class ExtendibleEntityDescriptor<TType>:IEntityDescriptor where TType : IEntityDescriptor, new()
{
protected ExtendibleEntityDescriptor(IEntityBuilder[] extraEntities)
@@ -7,7 +12,7 @@ namespace Svelto.ECS
_dynamicDescriptor = new DynamicEntityDescriptor<TType>(extraEntities);
}

public IEntityBuilder[] entitiesToBuild { get { return _dynamicDescriptor.entitiesToBuild; } }
public IEntityBuilder[] entitiesToBuild => _dynamicDescriptor.entitiesToBuild;

readonly DynamicEntityDescriptor<TType> _dynamicDescriptor;
}

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

@@ -9,7 +9,7 @@ namespace Svelto.ECS.Unity
{
var holder = Create<T>(new EGID(startIndex++, group), contextHolder, factory);
var childs = contextHolder.GetComponentsInChildren<IEntityDescriptorHolder>(true);
foreach (var child in childs)
{
if (child.GetType() != typeof(T))
@@ -18,10 +18,10 @@ namespace Svelto.ECS.Unity
startIndex = InternalBuildAll(startIndex, child, factory, group, childImplementors);
}
}
return holder;
}
public static T Create<T>(EGID ID, Transform contextHolder,
IEntityFactory factory) where T : MonoBehaviour, IEntityDescriptorHolder
{
@@ -32,7 +32,16 @@ namespace Svelto.ECS.Unity

return holder;
}

public static EntityStructInitializer CreateWithEntity<T>(EGID ID, Transform contextHolder,
IEntityFactory factory, out T holder) where T : MonoBehaviour, IEntityDescriptorHolder
{
holder = contextHolder.GetComponentInChildren<T>(true);
var implementors = holder.GetComponents<IImplementor>();

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

public static uint CreateAll<T>(uint startIndex, ExclusiveGroup group, Transform contextHolder,
IEntityFactory factory) where T : MonoBehaviour, IEntityDescriptorHolder
{
@@ -47,11 +56,11 @@ namespace Svelto.ECS.Unity

return startIndex;
}
static uint InternalBuildAll(uint startIndex, IEntityDescriptorHolder descriptorHolder, IEntityFactory factory, ExclusiveGroup group, IImplementor[] implementors)
{
ExclusiveGroup.ExclusiveGroupStruct realGroup = group;
if (string.IsNullOrEmpty(descriptorHolder.groupName) == false)
realGroup = ExclusiveGroup.Search(descriptorHolder.groupName);

@@ -61,13 +70,13 @@ namespace Svelto.ECS.Unity
egid = new EGID(startIndex++, realGroup);
else
egid = new EGID(holderId, realGroup);
var init = factory.BuildEntity(egid, descriptorHolder.GetDescriptor(), implementors);
init.Init(new EntityHierarchyStruct(group));
return startIndex;
}
}
}
}
#endif

Loading…
Cancel
Save