eliasku / ecx

ECX is Entity Component System framework for Haxe
52 stars 10 forks source link

System iterates over non-matching entities #6

Closed Misiur closed 8 years ago

Misiur commented 8 years ago

Hi! I moved my project to current ecx dev version, but I encountered a bug (or misunderstood something): https://github.com/Misiur/ECXRemoval

Basically when removing a component from an entity, systems still iterate over that entity causing errors.

Secondary question: shall I use world.commit everytime I fiddle around with an entity (creating, adding components, removing components, destroying entity), or only when creating it? (I tried adding it for problem I described, but nothing changed)

I can run ecx-asteroids without any problems, and I didn't encounter that problem there - even though I see you are using #remove in state machine callbacks. I was wrong: when you ram an asteroid, you'll get

eliasku commented 8 years ago

@Misiur, apologize, family set data update was affected by last changes, should add to tests on that. Fixed. Could you check it right now? Your test successfully prints pairs now.

eliasku commented 8 years ago

tests added

eliasku commented 8 years ago

@Misiur commit should be called when you want to update families. Now only World::delete automatically will update families on World::invalidate.

Misiur commented 8 years ago

That's odd. Ramming an asteroid works fine in ecx-asteroids.

Generated HTML5 output: html5.zip

eliasku commented 8 years ago

@Misiur It happens once because you modify entity out of World Systems running scope. Timer.delay will be called out-side, and then first system will work with not updated family. So to fix this - just add extra world.invalidate() before system in systems() loop. I could add this case to example later if it works.

eliasku commented 8 years ago

@Misiur or even better to have a synchronization system with -1000000 priority for example. In this case you will have clear profiling information. And you will know that this invalidate come from any out-of-world changes

Misiur commented 8 years ago

Yup, works as expected when components are removed from within a system. Not exactly following you on "synchronization system" - you mean I should put there only world#invalidate to handle all out of world changes?

Update: Yup, that works just fine

eliasku commented 8 years ago

coool :)

Two options:

world.invalidate(); // put extra check here
for(system in world.systems()) {
      system.update();
    world.invalidate();
}

config.add(new AnyEmptySystem(), -100000); // just super low value for priority to make it run before all general systems