v0.7.8
A smaller release with something big cooking inside and some handy new features.
Components can now be added and removed in batches which results in less archetype-switching of the modified entity and way better performance. In the example bellow a single archetype movement is performed after the last call to add():
ecs::World w;
// Create an entity with Position.
ecs::Entity e = w.add();
w.add<Position>();
...
w.bulk(e)
// add Velocity to entity e
.add<Velocity>()
// remove Position from entity e
.del<Position>()
// add Rotation to entity e
.add<Rotation>()
// add a bunch of other components to entity e
.add<Something1, Something2, Something3>();
With this syntax new in place the batch version of set() function has been slightly altered to match it:
// Old version of the set function
w.set<Position>(e, {1,2,3})
.set<Velocity>({1,0,0});
// New version
w.set(e)
.set<Position>({1,2,3})
.set<Velocity>({1,0,0});
Each entity can be assigned a unique name now. This is useful for debugging or entity lookup when entity id is not present for any reason. If you try to assign an already existing name to some entity, the function does nothing (and triggers an assert if you have them enabled).
ecs::World w;
ecs::Entity e = w.add();
// Entity "e" named "my_unique_name".
// The string is copied and stored internally.
w.name(e, "my_unique_name");
// If you know the length of the string, you can provide it as well
w.name(e, "my_unique_name", 14);
// Pointer to the string used as entity name for entity "e"
const char* name = w.name(e);
// Entity identified by the string returned.
// In this case, "e_by_name" and "e" are equal.
ecs::Entity e_by_name = w.get("my_unique_name");
// The name can be unset by setting it to nullptr
w.name(e, nullptr);
If you already have a dedicated string storage it would be a waste to duplicate the memory. In this case you can use ecs::world::name_raw to name entities. In this case the string is NOT copied and NOT stored internally. You are responsible for its lifetime. The pointer also needs to be stable. Otherwise, any time your storage tries to move the string to a different place you have to unset the name before it happens and set it anew after the move is done.
const char* pUserManagedString = ...;
w.name_raw(e, pUserManagedString);
// If you now the length, you can provide it
w.name_raw(e, pUserManagedString, userManagedStringLength);
// If the user-managed string pointer is not stable, you need to unset the name before the pointer changes location
w.name_raw(e, nullptr);
...
// ... the change of pointer happens
...
// After the user-managed string changed location and obtained a new pointer, you set the name again
w.name_raw(e, pUserManagedString);
Fixed:
- entities with uni components could be moved to a non-matching uni chunk by defragmentation b18f56f
- deleting an empty archetype might have cause wrong query matching e13d754eb44ff309dc831f5de1a982c5d36b71f
- proper checks for the root archetype 36f3f4f
- ecs::world::cleanup not clearing everything properly 0d7e26a
- various theoretical issues with bash scripts 743f38a
Changed:
- bulk operations behavior bd3dd6a
- internal refactoring in preparation for Entity and Component merger 6e3ead1
Tweaked:
- slightly less work when comparing queries c4e8de7
Added:
- ability to bulk-add/del components b03ea78
- support for naming entities 30b9ed6
- GAIA_ASSUME as a wrapper for [[assume]] and similar compiler-specific attributes 4531995
Full Changelog: v0.7.7...v0.7.8