Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TypeSafeDictionary.cs 19KB

Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anni fa
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using Svelto.Common;
  4. using Svelto.DataStructures;
  5. using Svelto.ECS.Hybrid;
  6. namespace Svelto.ECS.Internal
  7. {
  8. sealed class TypeSafeDictionary<TValue> : ITypeSafeDictionary<TValue> where TValue : struct, IEntityComponent
  9. {
  10. static readonly Type _type = typeof(TValue);
  11. static readonly bool _hasEgid = typeof(INeedEGID).IsAssignableFrom(_type);
  12. static readonly bool _hasReference = typeof(INeedEntityReference).IsAssignableFrom(_type);
  13. internal static readonly bool isUnmanaged =
  14. _type.IsUnmanagedEx() && (typeof(IEntityViewComponent).IsAssignableFrom(_type) == false);
  15. public TypeSafeDictionary(uint size)
  16. {
  17. if (isUnmanaged)
  18. implUnmgd =
  19. new SveltoDictionary<uint, TValue, NativeStrategy<SveltoDictionaryNode<uint>>,
  20. NativeStrategy<TValue>, NativeStrategy<int>>(size, Allocator.Persistent);
  21. else
  22. {
  23. implMgd =
  24. new SveltoDictionary<uint, TValue, ManagedStrategy<SveltoDictionaryNode<uint>>,
  25. ManagedStrategy<TValue>, ManagedStrategy<int>>(size, Allocator.Managed);
  26. }
  27. }
  28. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  29. public void Add(uint egidEntityId, in TValue entityComponent)
  30. {
  31. if (isUnmanaged)
  32. implUnmgd.Add(egidEntityId, entityComponent);
  33. else
  34. implMgd.Add(egidEntityId, entityComponent);
  35. }
  36. /// todo: Is this really needed, cannot I just use AddEntitiesFromDictionary? Needs to be checked
  37. public void AddEntityToDictionary(EGID fromEntityGid, EGID toEntityID, ITypeSafeDictionary toGroup)
  38. {
  39. if (isUnmanaged)
  40. {
  41. var valueIndex = implUnmgd.GetIndex(fromEntityGid.entityID);
  42. DBC.ECS.Check.Require(toGroup != null
  43. , "Invalid To Group"); //todo check this, if it's right merge GetIndex
  44. {
  45. var toGroupCasted = toGroup as ITypeSafeDictionary<TValue>;
  46. ref var entity = ref implUnmgd.GetDirectValueByRef(valueIndex);
  47. if (_hasEgid)
  48. SetEGIDWithoutBoxing<TValue>.SetIDWithoutBoxing(ref entity, toEntityID);
  49. toGroupCasted.Add(toEntityID.entityID, entity);
  50. }
  51. }
  52. else
  53. {
  54. var valueIndex = implMgd.GetIndex(fromEntityGid.entityID);
  55. DBC.ECS.Check.Require(toGroup != null
  56. , "Invalid To Group"); //todo check this, if it's right merge GetIndex
  57. {
  58. var toGroupCasted = toGroup as ITypeSafeDictionary<TValue>;
  59. ref var entity = ref implMgd.GetDirectValueByRef(valueIndex);
  60. if (_hasEgid)
  61. SetEGIDWithoutBoxing<TValue>.SetIDWithoutBoxing(ref entity, toEntityID);
  62. toGroupCasted.Add(toEntityID.entityID, entity);
  63. }
  64. }
  65. }
  66. /// <summary>
  67. /// Add entities from external typeSafeDictionary (todo: add use case)
  68. /// </summary>
  69. /// <param name="entitiesToSubmit"></param>
  70. /// <param name="groupId"></param>
  71. /// <param name="enginesRoot"></param>
  72. /// <exception cref="TypeSafeDictionaryException"></exception>
  73. public void AddEntitiesFromDictionary
  74. (ITypeSafeDictionary entitiesToSubmit, ExclusiveGroupStruct groupId, EnginesRoot enginesRoot)
  75. {
  76. var safeDictionary = (entitiesToSubmit as TypeSafeDictionary<TValue>);
  77. if (isUnmanaged)
  78. {
  79. var typeSafeDictionary = safeDictionary.implUnmgd;
  80. foreach (var tuple in typeSafeDictionary)
  81. try
  82. {
  83. var egid = new EGID(tuple.Key, groupId);
  84. if (_hasEgid)
  85. SetEGIDWithoutBoxing<TValue>.SetIDWithoutBoxing(ref tuple.Value, egid);
  86. if (_hasReference)
  87. SetEGIDWithoutBoxing<TValue>.SetRefWithoutBoxing(
  88. ref tuple.Value, enginesRoot.entityLocator.GetEntityReference(egid));
  89. implUnmgd.Add(tuple.Key, tuple.Value);
  90. }
  91. catch (Exception e)
  92. {
  93. Console.LogException(
  94. e, "trying to add an EntityComponent with the same ID more than once Entity: ".FastConcat(typeof(TValue).ToString()).FastConcat(", group ").FastConcat(groupId.ToName()).FastConcat(", id ").FastConcat(tuple.Key));
  95. throw;
  96. }
  97. }
  98. else
  99. {
  100. var typeSafeDictionary = safeDictionary.implMgd;
  101. foreach (var tuple in typeSafeDictionary)
  102. try
  103. {
  104. if (_hasEgid)
  105. SetEGIDWithoutBoxing<TValue>.SetIDWithoutBoxing(
  106. ref tuple.Value, new EGID(tuple.Key, groupId));
  107. implMgd.Add(tuple.Key, tuple.Value);
  108. }
  109. catch (Exception e)
  110. {
  111. Console.LogException(
  112. e, "trying to add an EntityComponent with the same ID more than once Entity: ".FastConcat(typeof(TValue).ToString()).FastConcat(", group ").FastConcat(groupId.ToName()).FastConcat(", id ").FastConcat(tuple.Key));
  113. throw;
  114. }
  115. }
  116. }
  117. public void ExecuteEnginesAddOrSwapCallbacks
  118. (FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer>> entityComponentEnginesDB
  119. , ITypeSafeDictionary realDic, ExclusiveGroupStruct? fromGroup, ExclusiveGroupStruct toGroup
  120. , in PlatformProfiler profiler)
  121. {
  122. if (isUnmanaged)
  123. {
  124. var typeSafeDictionary = realDic as ITypeSafeDictionary<TValue>;
  125. //this can be optimized, should pass all the entities and not restart the process for each one
  126. foreach (var value in implUnmgd)
  127. ExecuteEnginesAddOrSwapCallbacksOnSingleEntity(entityComponentEnginesDB
  128. , ref typeSafeDictionary[value.Key], fromGroup
  129. , in profiler, new EGID(value.Key, toGroup));
  130. }
  131. else
  132. {
  133. var typeSafeDictionary = realDic as ITypeSafeDictionary<TValue>;
  134. //this can be optimized, should pass all the entities and not restart the process for each one
  135. foreach (var value in implMgd)
  136. ExecuteEnginesAddOrSwapCallbacksOnSingleEntity(entityComponentEnginesDB
  137. , ref typeSafeDictionary[value.Key], fromGroup
  138. , in profiler, new EGID(value.Key, toGroup));
  139. }
  140. }
  141. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  142. public void Clear()
  143. {
  144. if (isUnmanaged)
  145. {
  146. implUnmgd.Clear();
  147. }
  148. else
  149. {
  150. implMgd.Clear();
  151. }
  152. }
  153. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  154. public void FastClear()
  155. {
  156. if (isUnmanaged)
  157. {
  158. implUnmgd.FastClear();
  159. }
  160. else
  161. {
  162. implMgd.FastClear();
  163. }
  164. }
  165. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  166. public bool ContainsKey(uint egidEntityId)
  167. {
  168. if (isUnmanaged)
  169. {
  170. return implUnmgd.ContainsKey(egidEntityId);
  171. }
  172. else
  173. {
  174. return implMgd.ContainsKey(egidEntityId);
  175. }
  176. }
  177. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  178. public ITypeSafeDictionary Create()
  179. {
  180. return TypeSafeDictionaryFactory<TValue>.Create(1);
  181. }
  182. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  183. public uint GetIndex(uint valueEntityId)
  184. {
  185. if (isUnmanaged)
  186. {
  187. return implUnmgd.GetIndex(valueEntityId);
  188. }
  189. else
  190. {
  191. return implMgd.GetIndex(valueEntityId);
  192. }
  193. }
  194. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  195. public ref TValue GetOrCreate(uint idEntityId)
  196. {
  197. if (isUnmanaged)
  198. {
  199. return ref implUnmgd.GetOrCreate(idEntityId);
  200. }
  201. else
  202. {
  203. return ref implMgd.GetOrCreate(idEntityId);
  204. }
  205. }
  206. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  207. public IBuffer<TValue> GetValues(out uint count)
  208. {
  209. if (isUnmanaged)
  210. {
  211. return implUnmgd.GetValues(out count);
  212. }
  213. else
  214. {
  215. return implMgd.GetValues(out count);
  216. }
  217. }
  218. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  219. public ref TValue GetDirectValueByRef(uint key)
  220. {
  221. if (isUnmanaged)
  222. {
  223. return ref implUnmgd.GetDirectValueByRef(key);
  224. }
  225. else
  226. {
  227. return ref implMgd.GetDirectValueByRef(key);
  228. }
  229. }
  230. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  231. public bool Has(uint key)
  232. {
  233. if (isUnmanaged)
  234. {
  235. return implUnmgd.ContainsKey(key);
  236. }
  237. else
  238. {
  239. return implMgd.ContainsKey(key);
  240. }
  241. }
  242. public void ExecuteEnginesSwapOrRemoveCallbacks
  243. (EGID fromEntityGid, EGID? toEntityID, ITypeSafeDictionary toGroup
  244. , FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer>> engines, in PlatformProfiler profiler)
  245. {
  246. if (isUnmanaged)
  247. {
  248. var valueIndex = implUnmgd.GetIndex(fromEntityGid.entityID);
  249. ref var entity = ref implUnmgd.GetDirectValueByRef(valueIndex);
  250. //move
  251. if (toGroup != null)
  252. {
  253. var toGroupCasted = toGroup as ITypeSafeDictionary<TValue>;
  254. var previousGroup = fromEntityGid.groupID;
  255. //todo: why is setting the EGID if this code just execute callbacks?
  256. if (_hasEgid)
  257. SetEGIDWithoutBoxing<TValue>.SetIDWithoutBoxing(ref entity, toEntityID.Value);
  258. var index = toGroupCasted.GetIndex(toEntityID.Value.entityID);
  259. ExecuteEnginesAddOrSwapCallbacksOnSingleEntity(engines, ref toGroupCasted.GetDirectValueByRef(index)
  260. , previousGroup, in profiler, toEntityID.Value);
  261. }
  262. //remove
  263. else
  264. {
  265. ExecuteEnginesRemoveCallbackOnSingleEntity(engines, ref entity, in profiler, fromEntityGid);
  266. }
  267. }
  268. else
  269. {
  270. var valueIndex = implMgd.GetIndex(fromEntityGid.entityID);
  271. ref var entity = ref implMgd.GetDirectValueByRef(valueIndex);
  272. if (toGroup != null)
  273. {
  274. var toGroupCasted = toGroup as ITypeSafeDictionary<TValue>;
  275. var previousGroup = fromEntityGid.groupID;
  276. //todo: why is setting the EGID if this code just execute callbacks?
  277. if (_hasEgid)
  278. SetEGIDWithoutBoxing<TValue>.SetIDWithoutBoxing(ref entity, toEntityID.Value);
  279. var index = toGroupCasted.GetIndex(toEntityID.Value.entityID);
  280. ExecuteEnginesAddOrSwapCallbacksOnSingleEntity(engines, ref toGroupCasted.GetDirectValueByRef(index)
  281. , previousGroup, in profiler, toEntityID.Value);
  282. }
  283. else
  284. {
  285. ExecuteEnginesRemoveCallbackOnSingleEntity(engines, ref entity, in profiler, fromEntityGid);
  286. }
  287. }
  288. }
  289. public void ExecuteEnginesRemoveCallbacks
  290. (FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer>> engines, in PlatformProfiler profiler
  291. , ExclusiveGroupStruct group)
  292. {
  293. if (isUnmanaged)
  294. {
  295. foreach (var value in implUnmgd)
  296. ExecuteEnginesRemoveCallbackOnSingleEntity(engines, ref implUnmgd.GetValueByRef(value.Key)
  297. , in profiler, new EGID(value.Key, group));
  298. }
  299. else
  300. {
  301. foreach (var value in implMgd)
  302. ExecuteEnginesRemoveCallbackOnSingleEntity(engines, ref implMgd.GetValueByRef(value.Key)
  303. , in profiler, new EGID(value.Key, group));
  304. }
  305. }
  306. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  307. public void RemoveEntityFromDictionary(EGID fromEntityGid)
  308. {
  309. if (isUnmanaged)
  310. {
  311. implUnmgd.Remove(fromEntityGid.entityID);
  312. }
  313. else
  314. {
  315. implMgd.Remove(fromEntityGid.entityID);
  316. }
  317. }
  318. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  319. public void ResizeTo(uint size)
  320. {
  321. if (isUnmanaged)
  322. {
  323. implUnmgd.ResizeTo(size);
  324. }
  325. else
  326. {
  327. implMgd.ResizeTo(size);
  328. }
  329. }
  330. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  331. public void Trim()
  332. {
  333. if (isUnmanaged)
  334. {
  335. implUnmgd.Trim();
  336. }
  337. else
  338. {
  339. implMgd.Trim();
  340. }
  341. }
  342. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  343. public bool TryFindIndex(uint entityId, out uint index)
  344. {
  345. if (isUnmanaged)
  346. {
  347. return implUnmgd.TryFindIndex(entityId, out index);
  348. }
  349. else
  350. {
  351. return implMgd.TryFindIndex(entityId, out index);
  352. }
  353. }
  354. public void KeysEvaluator(Action<uint> action)
  355. {
  356. if (isUnmanaged)
  357. {
  358. foreach (var key in implUnmgd.keys)
  359. {
  360. action(key);
  361. }
  362. }
  363. else
  364. {
  365. foreach (var key in implMgd.keys)
  366. {
  367. action(key);
  368. }
  369. }
  370. }
  371. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  372. public bool TryGetValue(uint entityId, out TValue item)
  373. {
  374. if (isUnmanaged)
  375. {
  376. return implUnmgd.TryGetValue(entityId, out item);
  377. }
  378. else
  379. {
  380. return implMgd.TryGetValue(entityId, out item);
  381. }
  382. }
  383. public uint count
  384. {
  385. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  386. get
  387. {
  388. if (isUnmanaged)
  389. {
  390. return (uint) implUnmgd.count;
  391. }
  392. else
  393. {
  394. return (uint) implMgd.count;
  395. }
  396. }
  397. }
  398. public ref TValue this[uint idEntityId]
  399. {
  400. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  401. get
  402. {
  403. if (isUnmanaged)
  404. {
  405. return ref implUnmgd.GetValueByRef(idEntityId);
  406. }
  407. else
  408. {
  409. return ref implMgd.GetValueByRef(idEntityId);
  410. }
  411. }
  412. }
  413. public void Dispose()
  414. {
  415. if (isUnmanaged)
  416. implUnmgd.Dispose();
  417. else
  418. implMgd.Dispose();
  419. GC.SuppressFinalize(this);
  420. }
  421. void ExecuteEnginesAddOrSwapCallbacksOnSingleEntity
  422. (FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer>> engines, ref TValue entity
  423. , ExclusiveGroupStruct? previousGroup, in PlatformProfiler profiler, EGID egid)
  424. {
  425. //get all the engines linked to TValue
  426. if (!engines.TryGetValue(new RefWrapperType(_type), out var entityComponentsEngines))
  427. return;
  428. if (previousGroup == null)
  429. {
  430. for (var i = 0; i < entityComponentsEngines.count; i++)
  431. try
  432. {
  433. using (profiler.Sample(entityComponentsEngines[i].name))
  434. {
  435. (entityComponentsEngines[i].engine as IReactOnAddAndRemove<TValue>).Add(ref entity, egid);
  436. }
  437. }
  438. catch
  439. {
  440. Console.LogError("Code crashed inside Add callback ".FastConcat(typeof(TValue).ToString()));
  441. throw;
  442. }
  443. }
  444. else
  445. {
  446. for (var i = 0; i < entityComponentsEngines.count; i++)
  447. try
  448. {
  449. using (profiler.Sample(entityComponentsEngines[i].name))
  450. {
  451. (entityComponentsEngines[i].engine as IReactOnSwap<TValue>).MovedTo(
  452. ref entity, previousGroup.Value, egid);
  453. }
  454. }
  455. catch (Exception)
  456. {
  457. Console.LogError("Code crashed inside MoveTo callback ".FastConcat(typeof(TValue).ToString()));
  458. throw;
  459. }
  460. }
  461. }
  462. static void ExecuteEnginesRemoveCallbackOnSingleEntity
  463. (FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer>> engines, ref TValue entity
  464. , in PlatformProfiler profiler, EGID egid)
  465. {
  466. if (!engines.TryGetValue(new RefWrapperType(_type), out var entityComponentsEngines))
  467. return;
  468. for (var i = 0; i < entityComponentsEngines.count; i++)
  469. try
  470. {
  471. using (profiler.Sample(entityComponentsEngines[i].name))
  472. {
  473. (entityComponentsEngines[i].engine as IReactOnAddAndRemove<TValue>).Remove(ref entity, egid);
  474. }
  475. }
  476. catch
  477. {
  478. Console.LogError("Code crashed inside Remove callback ".FastConcat(typeof(TValue).ToString()));
  479. throw;
  480. }
  481. }
  482. internal SveltoDictionary<uint, TValue, ManagedStrategy<SveltoDictionaryNode<uint>>, ManagedStrategy<TValue>,
  483. ManagedStrategy<int>> implMgd;
  484. //used directly by native methods
  485. internal SveltoDictionary<uint, TValue, NativeStrategy<SveltoDictionaryNode<uint>>, NativeStrategy<TValue>,
  486. NativeStrategy<int>> implUnmgd;
  487. }
  488. }