New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Engine left unusable, in the updating state, after an uncaught exception in a subsystem #210

Closed
Snack-a-Dog opened this Issue Feb 7, 2016 · 1 comment

Comments

Projects
None yet
2 participants
@Snack-a-Dog
Copy link

Snack-a-Dog commented Feb 7, 2016

If an EntitySystem throws an uncaught exception in its update() method, the Engine is left in the updating state forever and can't be used ever again. Please use the following code to reproduce. After the initial "oopsie" exception, all further updates on the Engine will result in an "Cannot call update() on an Engine that is already updating" exception.

public class EngineExceptionTest extends ApplicationAdapter {

    private Engine engine;

    @Override
    public void create () {
        Gdx.app.setLogLevel(Application.LOG_DEBUG);

        engine = new Engine();
        // ...add bunch of systems
        engine.addSystem(new SystemWithASubtleBug());
        // ...add even more systems
        // ...load the first level
    }

    @Override
    public void render() {
        try {
            engine.update(0.1f);
        } catch (Exception e) {
            Gdx.app.log("fatal", "caught an unexpected exception", e);
            // switch back to the main menu and try to continue
        }
    }

    private static class SystemWithASubtleBug extends EntitySystem {
        @Override
        public void update(float deltaTime) {
            // let's assume that this exception occurs only in very rare cases
            throw new RuntimeException("oopsie");
        }
    }
}

Of course systems shouldn't throw any exceptions normally, but if one does because of some obscure bug, the Engine is essentially left dead, even though the application could still be able to continue. Currently possible workarounds include resetting the updating-field in the Engine to false via Reflection or creating a new Engine and copying the systems into it, both pretty nasty hacks.

A clean fix would be for the Engine to wrap the update loop over all systems into a try and to set "updating = false" (and maybe the componentOperationHandler/entityManager calls) in a finally block. The user of the class would then have the choice of trying to cope with the problem somehow or to let the exception kill the application.

@dsaltares dsaltares added the bug label Feb 8, 2016

dsaltares added a commit to dsaltares/ashley that referenced this issue Feb 8, 2016

@dsaltares dsaltares closed this Feb 8, 2016

@dsaltares

This comment has been minimized.

Copy link
Member

dsaltares commented Feb 8, 2016

Thanks for reporting, it should be available in the next snapshot build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment