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