SanderMertens / flecs

A fast entity component system (ECS) for C & C++
https://www.flecs.dev
Other
6.47k stars 454 forks source link

runtime component c++ example bug maybe #1014

Closed yafacex closed 1 year ago

yafacex commented 1 year ago
flecs::entity position = world.component("Position")
    .member<float>("x")
    .member<float>("y");
    //.member<std::string>("z");

flecs::entity velocity = world.component("Velocity")
    .member<float>("dx")
    .member<float>("dy");
    //.member<std::string>("z");

// Create entity, set value of position using reflection API
flecs::entity e1 = world.entity("A1");
void* ptrPos1 = e1.get_mut(position);
void* ptrVel1 = e1.get_mut(velocity);

flecs::entity e2 = world.entity("A2");
void* ptrPos2 = e2.get_mut(position);
void* ptrVel2 = e2.get_mut(velocity);

after run, ptrPos1 == ptrPos2, component from two different entities has same address, Is that right?

SanderMertens commented 1 year ago

Yes that's expected. One thing to keep in mind is that for every ECS operation (add, remove, set, get_mut, clear, delete, ..) you do, entities can get shuffled around in memory. What happens here is:

void* ptrPos1 = e1.get_mut(position); // entity moves to table [Position]
void* ptrVel1 = e1.get_mut(velocity); // entity moves to table [Position, Velocity]

flecs::entity e2 = world.entity("A2");
void* ptrPos2 = e2.get_mut(position); // entity moves to table [Position]
void* ptrVel2 = e2.get_mut(velocity); // entity moves to table [Position, Velocity[

As you can see, after the first get_mut operation, both entities initially end up as only entity in [Position], which is why at that moment they occupy the same memory. However, if you were to compare the results of get_mut after all operations completed, you'd see that they are different:

flecs::entity e1 = world.entity("A1");
void* ptrPos1 = e1.get_mut(position);
void* ptrVel1 = e1.get_mut(velocity);

flecs::entity e2 = world.entity("A2");
void* ptrPos2 = e2.get_mut(position);
void* ptrVel2 = e2.get_mut(velocity);

assert(e1.get_mut(position) != e2.get_mut(position)); // OK