0

I recently asked this question: Box2D - Can't destroy multiple fixtures, but figured out it wasn't an issue with Box2D, but an issue with my java. Here is my code:

public static void removeSpecifiedBodies() {
        for (Body body : bodiesToRemoveList) {
            Array<Fixture> fixtures = body.getFixtureList();
            for (Fixture fixture : fixtures) {
                body.destroyFixture(fixture);
            }
        }
        bodiesToRemoveList.clear();
    }

What I'm doing is looping through all of the bodies in my bodiesToRemoveList. Then, each body has multiple fixtures, so I get all of them and loop through them, destroying each one. After all of this, I clear the bodiesToRemoveList. But, in my second for loop, when I destroy the fixtures, only one is getting destroyed. I did some debugging and found that the for loop only runs once. I'm not sure why this is happening. A google search showed other people with this issue, and I noticed they all removed or cleared items from a list, just like I'm doing. I see no issue with my code, but for some reason nothing I try will fix it. Does anybody seen any issue with my code? Thanks in advanced.

Edit: I'm an idiot. Thanks to everybody who helped. Here is my code, if anybody wants to see it.

public static void removeSpecifiedBodies() {
            Iterator<Body> i = bodiesToRemoveList.iterator();
            while (i.hasNext()) {
                Body desBod = i.next();
                //body.destroyFixture(fixture);
                WorldController.b2world.destroyBody(desBod);
                i.remove();
            }
        bodiesToRemoveList.clear();
    }
Community
  • 1
  • 1
josephoneill
  • 853
  • 2
  • 10
  • 33
  • 1
    how many bodies do you have in bodiesToRemoveList? –  Apr 19 '14 at 15:04
  • possible duplicate of [Calling remove in foreach loop in Java](http://stackoverflow.com/questions/1196586/calling-remove-in-foreach-loop-in-java) – damgad Apr 19 '14 at 15:07
  • For-each loops aren't broken in Java. I suspect whatever `destroyFixture()` is modifies the list you're iterating through causing the issue. – Brian Roach Apr 19 '14 at 15:09
  • Looks like a bug in this poorly-named "Array" class, or perhaps there's some connection between a Fixture and the Array that contains it. Try copying all the Fixtures into an ArrayList, then looping over that to destroy them. – Ernest Friedman-Hill Apr 19 '14 at 15:09

1 Answers1

3

You shouldn't be modifying a list that you are iterating over, unless you're using an Iterator directly (and sharing it with the loop). Since you don't have access to the Iterator that the for loop is using, you are going to get mixed results, for sure.

So, either use the iterator directly, or another method is to accumulate all of the items you want removed from list in to a another collection, and then removeAll from the original collection. This is a bit more expensive as you are iterating across the list twice, but it's simple and clean and for short lists, likely not a real issue.

Otherwise:

List<Fixture> fixtures = body.getFixtureList();
Iterator<Fixture> i = fixtures.iterator();
while(i.hasNext()) {
    Fixture fixture = i.next();
    if (destroyFixture(fixture)) {
        i.remove();
    }
}
Will Hartung
  • 115,893
  • 19
  • 128
  • 203