Search code examples
javaexceptioniteratorcontrol-flowconceptual

Java Flow Control Problem


I am programming a simple 2d game engine. I've decided how I'd like the engine to function: it will be composed of objects containing "events" that my main game loop will trigger when appropriate.

A little more about the structure: Every GameObject has an updateEvent method. objectList is a list of all the objects that will receive update events. Only objects on this list have their updateEvent method called by the game loop.

I’m trying to implement this method in the GameObject class (This specification is what I’d like the method to achieve):

/**
* This method removes a GameObject from objectList.  The GameObject 
* should immediately stop executing code, that is, absolutely no more
* code inside update events will be executed for the removed game object.
* If necessary, control should transfer to the game loop.
* @param go The GameObject to be removed
*/
public void remove(GameObject go)

So if an object tries to remove itself inside of an update event, control should transfer back to the game engine:

public void updateEvent() {
    //object's update event
    remove(this);
    System.out.println("Should never reach here!");
}

Here’s what I have so far. It works, but the more I read about using exceptions for flow control the less I like it, so I want to see if there are alternatives.

Remove Method

public void remove(GameObject go) {
    //add to removedList
    //flag as removed
    //throw an exception if removing self from inside an updateEvent
}

Game Loop

for(GameObject go : objectList) {
    try {
        if (!go.removed) {
            go.updateEvent();
        } else {
            //object is scheduled to be removed, do nothing
        }
    } catch(ObjectRemovedException e) {
        //control has been transferred back to the game loop
        //no need to do anything here
    }
}
// now remove the objects that are in removedList from objectList

2 questions:

  1. Am I correct in assuming that the only way to implement the stop-right-away part of the remove method as described above is by throwing a custom exception and catching it in the game loop? (I know, using exceptions for flow control is like goto, which is bad. I just can’t think of another way to do what I want!)

  2. For the removal from the list itself, it is possible for one object to remove one that is farther down on the list. Currently I’m checking a removed flag before executing any code, and at the end of each pass removing the objects to avoid concurrent modification. Is there a better, preferably instant/non-polling way to do this?

[Edit] After reading your answers, I think I'll change the method specs. The instant-remove behavior is something I’ve become used to working with in a different engine, but you’re right, it doesn’t really fit in with how Java works. Time to go try to wrap my head around a slightly different method of thinking!


Solution

  • Why not simply return, i.e.,

    public void updateEvent() { 
        //object's update event 
        remove(this); 
        return;   
        //obviously unreachable 
        System.out.println("Should never reach here!");     }