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();
    }
4
  • 1
    how many bodies do you have in bodiesToRemoveList? Commented Apr 19, 2014 at 15:04
  • possible duplicate of Calling remove in foreach loop in Java Commented Apr 19, 2014 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. Commented Apr 19, 2014 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. Commented Apr 19, 2014 at 15:09

1 Answer 1

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();
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Alright, thanks. I tried this, but get an error while trying to remove from the iterator. I added new code to the op.
Nevermind. I'm an idiot. No need to loop through the body list AND use the iterator. Thanks. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.