EnttiyStructs can now be built with an initializertags/Rel2
@@ -16,7 +16,6 @@ namespace Svelto.ECS.Internal | |||
void FillWithIndexedEntityViews(ITypeSafeList entityViews); | |||
bool Remove(EGID entityId); | |||
IEntityView GetIndexedEntityView(EGID entityID); | |||
bool isQueryiableEntityView { get; } | |||
} | |||
class TypeSafeDictionaryForClass<TValue> : Dictionary<int, TValue>, ITypeSafeDictionary where TValue : EntityView | |||
@@ -55,53 +54,5 @@ namespace Svelto.ECS.Internal | |||
{ | |||
return this[entityID.GID]; | |||
} | |||
public bool isQueryiableEntityView | |||
{ | |||
get { return true; } | |||
} | |||
} | |||
class TypeSafeDictionaryForStruct<TValue> : Dictionary<int, TValue>, ITypeSafeDictionary where TValue : struct, IEntityStruct | |||
{ | |||
internal static readonly ReadOnlyDictionary<int, TValue> Default = | |||
new ReadOnlyDictionary<int, TValue>(new Dictionary<int, TValue>()); | |||
public void FillWithIndexedEntityViews(ITypeSafeList entityViews) | |||
{ | |||
int count; | |||
var buffer = FasterList<TValue>.NoVirt.ToArrayFast((FasterList<TValue>) entityViews, out count); | |||
try | |||
{ | |||
for (var i = 0; i < count; i++) | |||
{ | |||
var entityView = buffer[i]; | |||
Add(entityView.ID.GID, entityView); | |||
} | |||
} | |||
catch (Exception e) | |||
{ | |||
throw new TypeSafeDictionaryException(e); | |||
} | |||
} | |||
public bool Remove(EGID entityId) | |||
{ | |||
base.Remove(entityId.GID); | |||
return Count > 0; | |||
} | |||
public IEntityView GetIndexedEntityView(EGID entityID) | |||
{ | |||
return this[entityID.GID]; | |||
} | |||
public bool isQueryiableEntityView | |||
{ | |||
get { return false; } | |||
} | |||
} | |||
} |
@@ -118,7 +118,7 @@ namespace Svelto.ECS.Internal | |||
public ITypeSafeDictionary CreateIndexedDictionary() | |||
{ | |||
return new TypeSafeDictionaryForStruct<T>(); | |||
throw new NotSupportedException(); | |||
} | |||
public IEntityView[] ToArrayFast(out int count) | |||
@@ -131,18 +131,20 @@ namespace Svelto.ECS | |||
void RemoveEntity(EGID entityGID) | |||
{ | |||
var entityViewBuilders = _entityInfos[entityGID.GID]; | |||
var entityViewBuildersCount = entityViewBuilders.Length; | |||
var group = _groupEntityViewsDB[entityGID.group]; | |||
//for each entity view generated by the entity descriptor | |||
for (var i = 0; i < entityViewBuildersCount; i++) | |||
{ | |||
var entityViewType = entityViewBuilders[i].GetEntityViewType(); | |||
InternalRemoveEntityViewFromDBDicAndEngines(entityViewType, entityGID); | |||
RemoveEntityViewFromDB(@group, entityViewType, entityGID); | |||
if (entityViewBuilders[i].isQueryiableEntityView) | |||
{ | |||
var group = _groupEntityViewsDB[entityGID.group]; | |||
InternalRemoveEntityViewFromDBDicAndEngines(entityViewType, entityGID); | |||
RemoveEntityViewFromDB(@group, entityViewType, entityGID); | |||
} | |||
RemoveEntityViewFromDB(@_globalEntityViewsDB, entityViewType, entityGID); | |||
} | |||
@@ -161,18 +163,21 @@ namespace Svelto.ECS | |||
{ | |||
foreach (var group in _groupEntityViewsDB[groupID]) | |||
{ | |||
var entityViewType = group.Key; | |||
{ | |||
var entityViewType = group.Key; | |||
int count; | |||
var entities = group.Value.ToArrayFast(out count); | |||
int count; | |||
var entities = group.Value.ToArrayFast(out count); | |||
for (var i = 0; i < count; i++) | |||
{ | |||
var entityID = entities[i].ID; | |||
for (var i = 0; i < count; i++) | |||
{ | |||
var entityID = entities[i].ID; | |||
RemoveEntityViewFromDB(@_globalEntityViewsDB, entityViewType, entityID); | |||
RemoveEntityViewFromDB(@_globalEntityViewsDB, entityViewType, entityID); | |||
InternalRemoveEntityViewFromDBDicAndEngines(entityViewType, entityID); | |||
if (group.Value.isQueryiableEntityView) | |||
InternalRemoveEntityViewFromDBDicAndEngines(entityViewType, entityID); | |||
} | |||
} | |||
} | |||
@@ -182,7 +187,6 @@ namespace Svelto.ECS | |||
void InternalRemoveEntityViewFromDBDicAndEngines(Type entityViewType, EGID id) | |||
{ | |||
var typeSafeDictionary = _globalEntityViewsDBDic[entityViewType]; | |||
if (typeSafeDictionary.isQueryiableEntityView) | |||
{ | |||
var entityView = typeSafeDictionary.GetIndexedEntityView(id); | |||
@@ -55,7 +55,8 @@ namespace Svelto.ECS | |||
foreach (var entityViewsPerType in groupToSubmit.Value) | |||
{ | |||
//add the entity View in the group | |||
AddEntityViewToDB(groupDB, entityViewsPerType); | |||
if (entityViewsPerType.Value.isQueryiableEntityView == true) | |||
AddEntityViewToDB(groupDB, entityViewsPerType); | |||
//add the entity view in the gloal pool | |||
AddEntityViewToDB(_globalEntityViewsDB, entityViewsPerType); | |||
//and it's not a struct, add in the indexable DB too | |||
@@ -63,7 +64,8 @@ namespace Svelto.ECS | |||
} | |||
} | |||
//then submit everything in the engines | |||
//then submit everything in the engines, so that the DB is up to date | |||
//with all the entity views and struct created by the entity built | |||
foreach (var group in groupsToSubmit) | |||
{ | |||
foreach (var entityViewList in group.Value) | |||
@@ -81,23 +83,29 @@ namespace Svelto.ECS | |||
static void AddEntityViewToDB( Dictionary<Type, ITypeSafeList> entityViewsDB, | |||
KeyValuePair<Type, ITypeSafeList> entityViewList) | |||
{ | |||
ITypeSafeList dbList; | |||
{ | |||
ITypeSafeList dbList; | |||
if (entityViewsDB.TryGetValue(entityViewList.Key, out dbList) == false) | |||
dbList = entityViewsDB[entityViewList.Key] = entityViewList.Value.Create(); | |||
if (entityViewsDB.TryGetValue(entityViewList.Key, out dbList) == false) | |||
dbList = entityViewsDB[entityViewList.Key] = entityViewList.Value.Create(); | |||
dbList.AddRange(entityViewList.Value); | |||
dbList.AddRange(entityViewList.Value); | |||
} | |||
} | |||
static void AddEntityViewToEntityViewsDictionary(Dictionary<Type, ITypeSafeDictionary> entityViewsDBdic, | |||
ITypeSafeList entityViews, Type entityViewType) | |||
{ | |||
ITypeSafeDictionary entityViewsDic; | |||
if (entityViewsDBdic.TryGetValue(entityViewType, out entityViewsDic) == false) | |||
entityViewsDic = entityViewsDBdic[entityViewType] = entityViews.CreateIndexedDictionary(); | |||
entityViewsDic.FillWithIndexedEntityViews(entityViews); | |||
if (entityViews.isQueryiableEntityView == true) | |||
{ | |||
ITypeSafeDictionary entityViewsDic; | |||
if (entityViewsDBdic.TryGetValue(entityViewType, out entityViewsDic) == false) | |||
entityViewsDic = entityViewsDBdic[entityViewType] = entityViews.CreateIndexedDictionary(); | |||
entityViewsDic.FillWithIndexedEntityViews(entityViews); | |||
} | |||
} | |||
static void AddEntityViewToTheSuitableEngines(Dictionary<Type, FasterList<IHandleEntityViewEngine>> entityViewEngines, ITypeSafeList entityViewsList, Type entityViewType) | |||
@@ -31,15 +31,15 @@ namespace Svelto.ECS | |||
Check.Require(extraEntityViews.Count > 0, | |||
"don't use a DynamicEntityDescriptorInfo if you don't need to use extra EntityViews"); | |||
var descriptor = new TType(); | |||
var length = descriptor.entityViewsToBuild.Length; | |||
var defaultEntityViewsToBuild = EntityDescriptorTemplate<TType>.Default.entityViewsToBuild; | |||
var length = defaultEntityViewsToBuild.Length; | |||
entityViewsToBuild = new IEntityViewBuilder[length + extraEntityViews.Count]; | |||
Array.Copy(descriptor.entityViewsToBuild, 0, entityViewsToBuild, 0, length); | |||
Array.Copy(defaultEntityViewsToBuild, 0, entityViewsToBuild, 0, length); | |||
Array.Copy(extraEntityViews.ToArrayFast(), 0, entityViewsToBuild, length, extraEntityViews.Count); | |||
name = descriptor.ToString(); | |||
name = EntityDescriptorTemplate<TType>.Default.name; | |||
} | |||
} | |||
@@ -1,6 +1,5 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Xml; | |||
using Svelto.DataStructures; | |||
using Svelto.Utilities; | |||
using Console = Utility.Console; | |||
@@ -11,6 +11,7 @@ namespace Svelto.ECS | |||
Type GetEntityViewType(); | |||
void MoveEntityView(EGID entityID, ITypeSafeList fromSafeList, ITypeSafeList toSafeList); | |||
bool mustBeFilled { get; } | |||
bool isQueryiableEntityView { get; } | |||
} | |||
public class EntityViewBuilder<EntityViewType> : IEntityViewBuilder where EntityViewType : EntityView, new() | |||
@@ -56,23 +57,35 @@ namespace Svelto.ECS | |||
{ | |||
get { return true; } | |||
} | |||
public bool isQueryiableEntityView | |||
{ | |||
get { return true; } | |||
} | |||
public static readonly Type ENTITY_VIEW_TYPE = typeof(EntityViewType); | |||
} | |||
public class EntityViewStructBuilder<EntityViewType> : IEntityViewBuilder where EntityViewType : struct, IEntityStruct | |||
{ | |||
public EntityViewStructBuilder() | |||
{} | |||
public EntityViewStructBuilder(ref EntityViewType initializer) | |||
{ | |||
_initializer = initializer; | |||
} | |||
public void BuildEntityViewAndAddToList(ref ITypeSafeList list, EGID entityID, out IEntityView entityView) | |||
{ | |||
var structEntityView = default(EntityViewType); | |||
structEntityView.ID = entityID; | |||
_initializer.ID = entityID; | |||
if (list == null) | |||
list = new TypeSafeFasterListForECSForStructs<EntityViewType>(); | |||
var castedList = list as TypeSafeFasterListForECSForStructs<EntityViewType>; | |||
castedList.Add(structEntityView); | |||
castedList.Add(_initializer); | |||
entityView = null; | |||
} | |||
@@ -105,6 +118,12 @@ namespace Svelto.ECS | |||
get { return false; } | |||
} | |||
public bool isQueryiableEntityView | |||
{ | |||
get { return false; } | |||
} | |||
public static readonly Type ENTITY_VIEW_TYPE = typeof(EntityViewType); | |||
} | |||
EntityViewType _initializer; | |||
} | |||
} |
@@ -54,7 +54,7 @@ namespace Svelto.ECS.Internal | |||
return FasterList<T>.NoVirt.ToArrayFast((FasterList<T>)entityViews, out count); | |||
} | |||
public T[] QueryGroupedEntityViewsAsArray<T>(int @group, out int count) where T : IEntityView | |||
public T[] QueryGroupedEntityViewsAsArray<T>(int @group, out int count) where T : EntityView | |||
{ | |||
var type = typeof(T); | |||
count = 0; | |||
@@ -1,183 +0,0 @@ | |||
#if EXPERIMENTAL | |||
using System; | |||
using System.Collections.Generic; | |||
using Svelto.DataStructures; | |||
using Svelto.ECS.Experimental.Internal; | |||
namespace Svelto.ECS.Experimental.Internal | |||
{ | |||
public interface IStructEntityViewEngine : IEngine | |||
{ | |||
void CreateStructEntityViews(SharedStructEntityViewLists sharedStructEntityViewLists); | |||
} | |||
public interface IGroupedStructEntityViewsEngine : IEngine | |||
{ | |||
void CreateStructEntityViews(SharedGroupedStructEntityViewsLists sharedStructEntityViewLists); | |||
} | |||
} | |||
namespace Svelto.ECS.Experimental | |||
{ | |||
public interface IGroupedEntityView | |||
{ | |||
int groupID { get; set; } | |||
} | |||
/// <summary> | |||
/// The engines can receive and store IEntityViews structs | |||
/// Unboxing will happen during the Add, but the | |||
/// data will then be stored and processed as stucts | |||
/// </summary> | |||
public interface IStructEntityViewEngine<T> : IStructEntityViewEngine where T:struct, IEntityStruct | |||
{ } | |||
/// <summary> | |||
/// same as above, but the entityViews are grouped by ID | |||
/// usually the ID is the owner of the entityViews of that | |||
/// group | |||
/// </summary> | |||
public interface IGroupedStructEntityViewsEngine<T> : IGroupedStructEntityViewsEngine where T : struct, IGroupedEntityView | |||
{ | |||
void Add(ref T entityView); | |||
void Remove(ref T entityView); | |||
} | |||
public sealed class StructEntityViews<T> where T:struct, IEntityStruct | |||
{ | |||
public T[] GetList(out int numberOfItems) | |||
{ | |||
numberOfItems = _internalList.Count; | |||
return _internalList.ToArrayFast(); | |||
} | |||
public StructEntityViews(SharedStructEntityViewLists container) | |||
{ | |||
_internalList = SharedStructEntityViewLists.NoVirt.GetList<T>(container); | |||
} | |||
public void Add(T entityView) | |||
{ | |||
T convert = (T)entityView; | |||
_internalList.Add(convert); | |||
} | |||
readonly FasterList<T> _internalList; | |||
} | |||
public struct StructGroupEntityViews<T> | |||
where T : struct, IEntityView | |||
{ | |||
public StructGroupEntityViews(SharedGroupedStructEntityViewsLists container) | |||
{ | |||
_container = container; | |||
indices = new Dictionary<int, int>(); | |||
} | |||
public void Add(int groupID, T entityView) | |||
{ | |||
T convert = (T)entityView; | |||
var fasterList = | |||
(SharedGroupedStructEntityViewsLists.NoVirt.GetList<T>(_container, groupID) as FasterList<T>); | |||
indices[entityView.ID] = fasterList.Count; | |||
fasterList.Add(convert); | |||
} | |||
public void Remove(int groupID, T entityView) | |||
{ | |||
var fasterList = | |||
(SharedGroupedStructEntityViewsLists.NoVirt.GetList<T>(_container, groupID) as FasterList<T>); | |||
var index = indices[entityView.ID]; | |||
indices.Remove(entityView.ID); | |||
if (fasterList.UnorderedRemoveAt(index)) | |||
indices[fasterList[index].ID] = index; | |||
} | |||
public T[] GetList(int groupID, out int numberOfItems) | |||
{ | |||
var fasterList = | |||
(SharedGroupedStructEntityViewsLists.NoVirt.GetList<T>(_container, groupID) as FasterList<T>); | |||
return FasterList<T>.NoVirt.ToArrayFast(fasterList, out numberOfItems); | |||
} | |||
readonly SharedGroupedStructEntityViewsLists _container; | |||
readonly Dictionary<int, int> indices; | |||
} | |||
public class SharedStructEntityViewLists | |||
{ | |||
internal SharedStructEntityViewLists() | |||
{ | |||
_collection = new Dictionary<Type, IFasterList>(); | |||
} | |||
internal static class NoVirt | |||
{ | |||
internal static FasterList<T> GetList<T>(SharedStructEntityViewLists obj) where T : struct | |||
{ | |||
IFasterList list; | |||
if (obj._collection.TryGetValue(typeof(T), out list)) | |||
{ | |||
return list as FasterList<T>; | |||
} | |||
list = new FasterList<T>(); | |||
obj._collection.Add(typeof(T), list); | |||
return (FasterList<T>)list; | |||
} | |||
} | |||
readonly Dictionary<Type, IFasterList> _collection; | |||
} | |||
public class SharedGroupedStructEntityViewsLists | |||
{ | |||
internal SharedGroupedStructEntityViewsLists() | |||
{ | |||
_collection = new Dictionary<Type, Dictionary<int, IFasterList>>(); | |||
} | |||
internal static class NoVirt | |||
{ | |||
internal static IFasterList GetList<T>(SharedGroupedStructEntityViewsLists list, int groupID) where T : struct | |||
{ | |||
Dictionary<int, IFasterList> dic = GetGroup<T>(list); | |||
IFasterList localList; | |||
if (dic.TryGetValue(groupID, out localList)) | |||
return localList; | |||
localList = new FasterList<T>(); | |||
dic.Add(groupID, localList); | |||
return localList; | |||
} | |||
internal static Dictionary<int, IFasterList> GetGroup<T>(SharedGroupedStructEntityViewsLists list) where T : struct | |||
{ | |||
Dictionary<int, IFasterList> dic; | |||
if (list._collection.TryGetValue(typeof(T), out dic)) | |||
{ | |||
return dic; | |||
} | |||
dic = new Dictionary<int, IFasterList>(); | |||
list._collection.Add(typeof(T), dic); | |||
return dic; | |||
} | |||
} | |||
readonly Dictionary<Type, Dictionary<int, IFasterList>> _collection; | |||
} | |||
} | |||
#endif |
@@ -8,7 +8,7 @@ namespace Svelto.ECS | |||
FasterReadOnlyList<T> QueryGroupedEntityViews<T>(int group) where T : EntityView; | |||
T[] QueryEntityViewsAsArray<T>(out int count) where T : IEntityView; | |||
T[] QueryGroupedEntityViewsAsArray<T>(int group, out int count) where T : IEntityView; | |||
T[] QueryGroupedEntityViewsAsArray<T>(int group, out int count) where T : EntityView; | |||
bool TryQueryEntityView<T>(EGID ID, out T entityView) where T : EntityView; | |||
T QueryEntityView<T>(EGID entityGID) where T : EntityView; | |||