PotatoCode
PotatoCode

Reputation: 63

Pass an Enum and Return a New Class

I was hoping to make a SceneManager class to provide limited control over a single active scene with methods like setActiveScene(Scenes newScene) where Scenes is an enum, updateScene(double time) which wraps the update method of an active Scene, and getActiveScene() to retrieve certain components of the active scene. The hope was that only the SceneManager could create new Scenes, and that adding a new possible scene would be as simple as adding to the Scenes enum with which class to instantiate. What I had was something like this:

public class SceneManager {
    private static Scene activeScene = null;

    private static void setActiveScene(Scenes newScene) {
        activeScene = newScene.load();
    }

    public enum Scenes {
        START(new StartScene()), MENU(new MenuScene());
    
        private final Scene scene;
    
        Scenes(Scene scene) {
            this.scene = scene;
        }
        
        protected Scene load() { return scene; }
    }
}

It sorta worked except that I need the Scene to only be initialized when it's set. This setup initializes all the scenes right away and that won't work. I was hoping to find a cleaner solution than a switch statement but I'm not sure how else to make it work now. I tried messing with Constructors but that was getting even messier than the switch and probably far less efficient too.

Upvotes: 1

Views: 90

Answers (1)

tgdavies
tgdavies

Reputation: 11411

Two options:

Don't initialise the scenes in their constructors, but with an init method:

interface Scene {
  void init();
  ...
}
...
private static void setActiveScene(Scenes newScene) {
  activeScene = newScene.load();
  activeScene.init();
}

Don't create the scenes when the enum is initialised, only when you load it:

public enum Scenes {
  START(StartScene.class), MENU(MenuScene.class);
  private final Class<Scene> sceneClass;
  ...
  protected Scene load() {
    try {
      return sceneClass.getDeclaredConstructor().newInstance();
    } catch (InvocationTargetException e) {
      throw new RuntimeException(e);
    }
  }
}

Upvotes: 1

Related Questions