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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
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
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  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 string _typeName = _type.Name;
  12. static readonly bool _hasEgid = typeof(INeedEGID).IsAssignableFrom(_type);
  13. internal static readonly bool IsUnmanaged =
  14. _type.IsUnmanagedEx() && (typeof(IEntityViewComponent).IsAssignableFrom(_type) == false);
  15. SveltoDictionary<uint, TValue, NativeStrategy<SveltoDictionaryNode<uint>>, ManagedStrategy<TValue>,
  16. ManagedStrategy<int>> implMgd;
  17. //used directly by native methods
  18. internal SveltoDictionary<uint, TValue, NativeStrategy<SveltoDictionaryNode<uint>>, NativeStrategy<TValue>,
  19. NativeStrategy<int>> implUnmgd;
  20. public TypeSafeDictionary(uint size)
  21. {
  22. if (IsUnmanaged)
  23. implUnmgd = new SveltoDictionary<uint, TValue, NativeStrategy<SveltoDictionaryNode<uint>>,
  24. NativeStrategy<TValue>, NativeStrategy<int>>(size);
  25. else
  26. {
  27. implMgd = new SveltoDictionary<uint, TValue, NativeStrategy<SveltoDictionaryNode<uint>>,
  28. ManagedStrategy<TValue>, ManagedStrategy<int>>(size);
  29. }
  30. }
  31. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  32. public void Add(uint egidEntityId, in TValue entityComponent)
  33. {
  34. if (IsUnmanaged)
  35. implUnmgd.Add(egidEntityId, entityComponent);
  36. else
  37. implMgd.Add(egidEntityId, entityComponent);
  38. }
  39. /// <summary>
  40. /// Add entities from external typeSafeDictionary
  41. /// </summary>
  42. /// <param name="entitiesToSubmit"></param>
  43. /// <param name="groupId"></param>
  44. /// <exception cref="TypeSafeDictionaryException"></exception>
  45. public void AddEntitiesFromDictionary(ITypeSafeDictionary entitiesToSubmit, uint groupId)
  46. {
  47. if (IsUnmanaged)
  48. {
  49. var typeSafeDictionary = (entitiesToSubmit as TypeSafeDictionary<TValue>).implUnmgd;
  50. foreach (var tuple in typeSafeDictionary)
  51. try
  52. {
  53. if (_hasEgid)
  54. SetEGIDWithoutBoxing<TValue>.SetIDWithoutBoxing(
  55. ref tuple.Value, new EGID(tuple.Key, groupId));
  56. implUnmgd.Add(tuple.Key, tuple.Value);
  57. }
  58. catch (Exception e)
  59. {
  60. Console.LogException(
  61. e, "trying to add an EntityComponent with the same ID more than once Entity: ".FastConcat(typeof(TValue).ToString()).FastConcat(", group ").FastConcat(groupId).FastConcat(", id ").FastConcat(tuple.Key));
  62. throw;
  63. }
  64. }
  65. else
  66. {
  67. var typeSafeDictionary = (entitiesToSubmit as TypeSafeDictionary<TValue>).implMgd;
  68. foreach (var tuple in typeSafeDictionary)
  69. try
  70. {
  71. if (_hasEgid)
  72. SetEGIDWithoutBoxing<TValue>.SetIDWithoutBoxing(
  73. ref tuple.Value, new EGID(tuple.Key, groupId));
  74. implMgd.Add(tuple.Key, tuple.Value);
  75. }
  76. catch (Exception e)
  77. {
  78. Console.LogException(
  79. e, "trying to add an EntityComponent with the same ID more than once Entity: ".FastConcat(typeof(TValue).ToString()).FastConcat(", group ").FastConcat(groupId).FastConcat(", id ").FastConcat(tuple.Key));
  80. throw;
  81. }
  82. }
  83. }
  84. public void ExecuteEnginesAddOrSwapCallbacks
  85. (FasterDictionary<RefWrapperType, FasterList<IReactEngine>> entityComponentEnginesDB
  86. , ITypeSafeDictionary realDic, ExclusiveGroupStruct? fromGroup, ExclusiveGroupStruct toGroup
  87. , in PlatformProfiler profiler)
  88. {
  89. if (IsUnmanaged)
  90. {
  91. var typeSafeDictionary = realDic as ITypeSafeDictionary<TValue>;
  92. //this can be optimized, should pass all the entities and not restart the process for each one
  93. foreach (var value in implUnmgd)
  94. ExecuteEnginesAddOrSwapCallbacksOnSingleEntity(entityComponentEnginesDB
  95. , ref typeSafeDictionary[value.Key], fromGroup
  96. , in profiler, new EGID(value.Key, toGroup));
  97. }
  98. else
  99. {
  100. var typeSafeDictionary = realDic as ITypeSafeDictionary<TValue>;
  101. //this can be optimized, should pass all the entities and not restart the process for each one
  102. foreach (var value in implMgd)
  103. ExecuteEnginesAddOrSwapCallbacksOnSingleEntity(entityComponentEnginesDB
  104. , ref typeSafeDictionary[value.Key], fromGroup
  105. , in profiler, new EGID(value.Key, toGroup));
  106. }
  107. }
  108. public void AddEntityToDictionary(EGID fromEntityGid, EGID toEntityID, ITypeSafeDictionary toGroup)
  109. {
  110. if (IsUnmanaged)
  111. {
  112. var valueIndex = implUnmgd.GetIndex(fromEntityGid.entityID);
  113. DBC.ECS.Check.Require(toGroup != null
  114. , "Invalid To Group"); //todo check this, if it's right merge GetIndex
  115. {
  116. var toGroupCasted = toGroup as ITypeSafeDictionary<TValue>;
  117. ref var entity = ref implUnmgd.GetDirectValueByRef(valueIndex);
  118. if (_hasEgid)
  119. SetEGIDWithoutBoxing<TValue>.SetIDWithoutBoxing(ref entity, toEntityID);
  120. toGroupCasted.Add(toEntityID.entityID, entity);
  121. }
  122. }
  123. else
  124. {
  125. var valueIndex = implMgd.GetIndex(fromEntityGid.entityID);
  126. DBC.ECS.Check.Require(toGroup != null
  127. , "Invalid To Group"); //todo check this, if it's right merge GetIndex
  128. {
  129. var toGroupCasted = toGroup as ITypeSafeDictionary<TValue>;
  130. ref var entity = ref implMgd.GetDirectValueByRef(valueIndex);
  131. if (_hasEgid)
  132. SetEGIDWithoutBoxing<TValue>.SetIDWithoutBoxing(ref entity, toEntityID);
  133. toGroupCasted.Add(toEntityID.entityID, entity);
  134. }
  135. }
  136. }
  137. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  138. public void Clear()
  139. {
  140. if (IsUnmanaged)
  141. {
  142. implUnmgd.Clear();
  143. }
  144. else
  145. {
  146. implMgd.Clear();
  147. }
  148. }
  149. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  150. public void FastClear()
  151. {
  152. if (IsUnmanaged)
  153. {
  154. implUnmgd.FastClear();
  155. }
  156. else
  157. {
  158. implMgd.FastClear();
  159. }
  160. }
  161. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  162. public bool ContainsKey(uint egidEntityId)
  163. {
  164. if (IsUnmanaged)
  165. {
  166. return implUnmgd.ContainsKey(egidEntityId);
  167. }
  168. else
  169. {
  170. return implMgd.ContainsKey(egidEntityId);
  171. }
  172. }
  173. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  174. public ITypeSafeDictionary Create() { return TypeSafeDictionaryFactory<TValue>.Create(1); }
  175. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  176. public uint GetIndex(uint valueEntityId)
  177. {
  178. if (IsUnmanaged)
  179. {
  180. return this.implUnmgd.GetIndex(valueEntityId);
  181. }
  182. else
  183. {
  184. return this.implMgd.GetIndex(valueEntityId);
  185. }
  186. }
  187. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  188. public ref TValue GetOrCreate(uint idEntityId)
  189. {
  190. if (IsUnmanaged)
  191. {
  192. return ref this.implUnmgd.GetOrCreate(idEntityId);
  193. }
  194. else
  195. {
  196. return ref this.implMgd.GetOrCreate(idEntityId);
  197. }
  198. }
  199. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  200. public IBuffer<TValue> GetValues(out uint count)
  201. {
  202. if (IsUnmanaged)
  203. {
  204. return this.implUnmgd.GetValues(out count);
  205. }
  206. else
  207. {
  208. return this.implMgd.GetValues(out count);
  209. }
  210. }
  211. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  212. public ref TValue GetDirectValueByRef(uint key)
  213. {
  214. if (IsUnmanaged)
  215. {
  216. return ref this.implUnmgd.GetDirectValueByRef(key);
  217. }
  218. else
  219. {
  220. return ref this.implMgd.GetDirectValueByRef(key);
  221. }
  222. }
  223. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  224. public bool Has(uint key)
  225. {
  226. if (IsUnmanaged)
  227. {
  228. return this.implUnmgd.ContainsKey(key);
  229. }
  230. else
  231. {
  232. return this.implMgd.ContainsKey(key);
  233. }
  234. }
  235. public void ExecuteEnginesSwapOrRemoveCallbacks
  236. (EGID fromEntityGid, EGID? toEntityID, ITypeSafeDictionary toGroup
  237. , FasterDictionary<RefWrapperType, FasterList<IReactEngine>> engines, in PlatformProfiler profiler)
  238. {
  239. if (IsUnmanaged)
  240. {
  241. var valueIndex = this.implUnmgd.GetIndex(fromEntityGid.entityID);
  242. ref var entity = ref this.implUnmgd.GetDirectValueByRef(valueIndex);
  243. //move
  244. if (toGroup != null)
  245. {
  246. var toGroupCasted = toGroup as ITypeSafeDictionary<TValue>;
  247. var previousGroup = fromEntityGid.groupID;
  248. if (_hasEgid)
  249. SetEGIDWithoutBoxing<TValue>.SetIDWithoutBoxing(ref entity, toEntityID.Value);
  250. var index = toGroupCasted.GetIndex(toEntityID.Value.entityID);
  251. ExecuteEnginesAddOrSwapCallbacksOnSingleEntity(engines, ref toGroupCasted.GetDirectValueByRef(index)
  252. , previousGroup, in profiler, toEntityID.Value);
  253. }
  254. //remove
  255. else
  256. {
  257. ExecuteEnginesRemoveCallbackOnSingleEntity(engines, ref entity, in profiler, fromEntityGid);
  258. }
  259. }
  260. else
  261. {
  262. var valueIndex = this.implMgd.GetIndex(fromEntityGid.entityID);
  263. ref var entity = ref this.implMgd.GetDirectValueByRef(valueIndex);
  264. if (toGroup != null)
  265. {
  266. var toGroupCasted = toGroup as ITypeSafeDictionary<TValue>;
  267. var previousGroup = fromEntityGid.groupID;
  268. if (_hasEgid)
  269. SetEGIDWithoutBoxing<TValue>.SetIDWithoutBoxing(ref entity, toEntityID.Value);
  270. var index = toGroupCasted.GetIndex(toEntityID.Value.entityID);
  271. ExecuteEnginesAddOrSwapCallbacksOnSingleEntity(engines, ref toGroupCasted.GetDirectValueByRef(index)
  272. , previousGroup, in profiler, toEntityID.Value);
  273. }
  274. else
  275. {
  276. ExecuteEnginesRemoveCallbackOnSingleEntity(engines, ref entity, in profiler, fromEntityGid);
  277. }
  278. }
  279. }
  280. public void ExecuteEnginesRemoveCallbacks
  281. (FasterDictionary<RefWrapperType, FasterList<IReactEngine>> engines, in PlatformProfiler profiler
  282. , ExclusiveGroupStruct group)
  283. {
  284. if (IsUnmanaged)
  285. {
  286. foreach (var value in implUnmgd)
  287. ExecuteEnginesRemoveCallbackOnSingleEntity(engines, ref implUnmgd.GetValueByRef(value.Key)
  288. , in profiler, new EGID(value.Key, group));
  289. }
  290. else
  291. {
  292. foreach (var value in implMgd)
  293. ExecuteEnginesRemoveCallbackOnSingleEntity(engines, ref implMgd.GetValueByRef(value.Key)
  294. , in profiler, new EGID(value.Key, group));
  295. }
  296. }
  297. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  298. public void RemoveEntityFromDictionary(EGID fromEntityGid)
  299. {
  300. if (IsUnmanaged)
  301. {
  302. this.implUnmgd.Remove(fromEntityGid.entityID);
  303. }
  304. else
  305. {
  306. this.implMgd.Remove(fromEntityGid.entityID);
  307. }
  308. }
  309. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  310. public void SetCapacity(uint size)
  311. {
  312. if (IsUnmanaged)
  313. {
  314. this.implUnmgd.SetCapacity(size);
  315. }
  316. else
  317. {
  318. this.implMgd.SetCapacity(size);
  319. }
  320. }
  321. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  322. public void Trim()
  323. {
  324. if (IsUnmanaged)
  325. {
  326. this.implUnmgd.Trim();
  327. }
  328. else
  329. {
  330. this.implMgd.Trim();
  331. }
  332. }
  333. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  334. public bool TryFindIndex(uint entityId, out uint index)
  335. {
  336. if (IsUnmanaged)
  337. {
  338. return implUnmgd.TryFindIndex(entityId, out index);
  339. }
  340. else
  341. {
  342. return implMgd.TryFindIndex(entityId, out index);
  343. }
  344. }
  345. public void KeysEvaluator(Action<uint> action)
  346. {
  347. if (IsUnmanaged)
  348. {
  349. foreach (var key in implUnmgd.keys)
  350. {
  351. action(key);
  352. }
  353. }
  354. else
  355. {
  356. foreach (var key in implMgd.keys)
  357. {
  358. action(key);
  359. }
  360. }
  361. }
  362. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  363. public bool TryGetValue(uint entityId, out TValue item)
  364. {
  365. if (IsUnmanaged)
  366. {
  367. return this.implUnmgd.TryGetValue(entityId, out item);
  368. }
  369. else
  370. {
  371. return this.implMgd.TryGetValue(entityId, out item);
  372. }
  373. }
  374. public uint count
  375. {
  376. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  377. get
  378. {
  379. if (IsUnmanaged)
  380. {
  381. return (uint) this.implUnmgd.count;
  382. }
  383. else
  384. {
  385. return (uint) this.implMgd.count;
  386. }
  387. }
  388. }
  389. public ref TValue this[uint idEntityId]
  390. {
  391. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  392. get
  393. {
  394. if (IsUnmanaged)
  395. {
  396. return ref this.implUnmgd.GetValueByRef(idEntityId);
  397. }
  398. else
  399. {
  400. return ref this.implMgd.GetValueByRef(idEntityId);
  401. }
  402. }
  403. }
  404. static void ExecuteEnginesRemoveCallbackOnSingleEntity
  405. (FasterDictionary<RefWrapperType, FasterList<IReactEngine>> engines, ref TValue entity
  406. , in PlatformProfiler profiler, EGID egid)
  407. {
  408. if (!engines.TryGetValue(new RefWrapperType(_type), out var entityComponentsEngines))
  409. return;
  410. for (var i = 0; i < entityComponentsEngines.count; i++)
  411. try
  412. {
  413. using (profiler.Sample(entityComponentsEngines[i], _typeName))
  414. {
  415. (entityComponentsEngines[i] as IReactOnAddAndRemove<TValue>).Remove(ref entity, egid);
  416. }
  417. }
  418. catch
  419. {
  420. Svelto.Console.LogError(
  421. "Code crashed inside Remove callback ".FastConcat(typeof(TValue).ToString()));
  422. throw;
  423. }
  424. }
  425. void ExecuteEnginesAddOrSwapCallbacksOnSingleEntity
  426. (FasterDictionary<RefWrapperType, FasterList<IReactEngine>> engines, ref TValue entity
  427. , ExclusiveGroupStruct? previousGroup, in PlatformProfiler profiler, EGID egid)
  428. {
  429. //get all the engines linked to TValue
  430. if (!engines.TryGetValue(new RefWrapperType(_type), out var entityComponentsEngines))
  431. return;
  432. if (previousGroup == null)
  433. {
  434. for (var i = 0; i < entityComponentsEngines.count; i++)
  435. try
  436. {
  437. using (profiler.Sample(entityComponentsEngines[i], _typeName))
  438. {
  439. (entityComponentsEngines[i] as IReactOnAddAndRemove<TValue>).Add(ref entity, egid);
  440. }
  441. }
  442. catch
  443. {
  444. Svelto.Console.LogError(
  445. "Code crashed inside Add callback ".FastConcat(typeof(TValue).ToString()));
  446. throw;
  447. }
  448. }
  449. else
  450. {
  451. for (var i = 0; i < entityComponentsEngines.count; i++)
  452. try
  453. {
  454. using (profiler.Sample(entityComponentsEngines[i], _typeName))
  455. {
  456. (entityComponentsEngines[i] as IReactOnSwap<TValue>).MovedTo(
  457. ref entity, previousGroup.Value, egid);
  458. }
  459. }
  460. catch (Exception)
  461. {
  462. Svelto.Console.LogError(
  463. "Code crashed inside MoveTo callback ".FastConcat(typeof(TValue).ToString()));
  464. throw;
  465. }
  466. }
  467. }
  468. public void Dispose()
  469. {
  470. if (IsUnmanaged)
  471. implUnmgd.Dispose();
  472. else
  473. implMgd.Dispose();
  474. GC.SuppressFinalize(this);
  475. }
  476. }
  477. }