INTERNAL_ERROR when call children()
Esp9527 opened this issue · comments
Describe the bug
v3.2.9
To Reproduce
Steps to reproduce the behavior:
`
#include <flecs.h>
#include <vector>
#include <iostream>
struct Player {
int id;
};
struct Monster {
int id;
};
struct Attack {
int id;
};
struct Buffer {
int id;
};
struct Cast{};
struct Died{};
struct Prefabs{
struct Player{};
struct Monster{};
struct Buffer{};
struct Attack{};
};
int main(int, char *[]) {
flecs::world world;
world.component<Monster>();
world.component<Player>();
world.component<Attack>();
world.component<Died>();
world.prefab<Prefabs::Player>()
.override<Player>();
world.prefab<Prefabs::Attack>()
.override<Attack>();
world.prefab<Prefabs::Monster>()
.override<Monster>();
world.prefab<Prefabs::Buffer>()
.override<Buffer>();
auto player = world.entity().is_a<Prefabs::Player>();
auto monster = world.entity().is_a<Prefabs::Monster>();
flecs::entity attack, buffer;
world.system<Player>("System-Player")
.each([&attack](flecs::entity e, Player& p){
if(attack) return;
std::cout << " System-Player-Run " << std::endl;
auto world = e.world();
auto attack = world.entity().is_a<Prefabs::Attack>().child_of(e);
// attack.set<Attack>({});
});
world.system<Attack>("System-Attack")
.each([&buffer, &monster](flecs::entity e, Attack& a){
if(buffer) return;
std::cout << " System-Attack-Run " << std::endl;
auto world = e.world();
buffer = world.entity().is_a<Prefabs::Buffer>().child_of(monster);
monster.add<Died>();
});
world.observer<>("Observer-Died")
.term<Died>()
.event(flecs::OnSet)
.each([](flecs::entity e){
std::cout << " Observer-Died-Run " << std::endl;
e.children([](flecs::entity c){});
});
ecs_log_set_level(3);
world.app().target_fps(20).run();
return 0;
}
`
Expected behavior
0>player,monster,attack,buffer is prefabs
1>create a player , monster
2>player create a attack
3>attack create a buffer (child of monster), and monster add died
4> monster observer died, and call children (crash)
will print fatal: observable.c: 1002: assert: r->table == elem->table INTERNAL_ERROR
`
// flecs_emit_forward
ecs_record_t *r = elem->record;
ecs_assert(rc_idr->id == elem->id, ECS_INTERNAL_ERROR, NULL);
ecs_assert(r != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(flecs_entities_get(world, elem->src) == r,
ECS_INTERNAL_ERROR, NULL);
ecs_dbg_assert(r->table == elem->table, ECS_INTERNAL_ERROR, NULL);
int32_t offset = ECS_RECORD_TO_ROW(r->row);
flecs_emit_forward_id(world, er, er_onset, emit_ids, it, table,
rc_idr, elem->src, r->table, tr->index, offset, trav, evtx);
`
fatal: observable.c: 1002: assert: r->table == elem->table INTERNAL_ERROR
Additional context
Add any other context about the problem here (operating system, hardware, ...).
Yup that's a bug! Looking into it.
Was able to reduce the reproducer to:
#include <flecs.h>
struct Foo{};
int main(int, char *[]) {
flecs::world world;
world.component<Foo>();
world.observer<>()
.term<Foo>()
.event(flecs::OnAdd)
.each([](flecs::entity e){
e.children([](flecs::entity c){});
});
flecs::entity p1 = world.entity();
flecs::entity e1 = world.entity().is_a(p1);
world.defer_begin();
world.entity().is_a(p1).child_of(e1);
e1.add<Foo>();
world.defer_end();
return 0;
}
Fixed!