AppState documentation refers to non-existent app.getRootNode()

The documentation for AppState, specifically the code related to AbstractAppState, has the following:

@Override
public void initialize(AppStateManager stateManager, Application app) {
    // [...]
    this.app.getRootNode().attachChild(getX()); 

However, the Application class doesn’t contain a getRootNode() method in version 3.2.2, so this code doesn’t compile.

If this could be fixed to reflect the current API, I would be obliged.

The documentation looks correct to me. The example shows app as a SimpleApplication. The assignment to app casts the Application object to a SimpleApplication object.

public class MyAppState extends AbstractAppState {

    private SimpleApplication app;

    private Node x = new Node("x");  // some custom class fields...
    public Node getX(){ return x; }  // some custom methods...

    @Override
    public void initialize(AppStateManager stateManager, Application app) {
      super.initialize(stateManager, app);
      this.app = (SimpleApplication)app;          // cast to a more specific class

      // init stuff that is independent of whether state is PAUSED or RUNNING
      this.app.getRootNode().attachChild(getX()); // modify scene graph...
      this.app.doSomething();                     // call custom methods...
   }

   @Override
    public void cleanup() {
      super.cleanup();
      // unregister all my listeners, detach all my nodes, etc...
      this.app.getRootNode().detachChild(getX()); // modify scene graph...
      this.app.doSomethingElse();                 // call custom methods...
    }

    @Override
    public void setEnabled(boolean enabled) {
      // Pause and unpause
      super.setEnabled(enabled);
      if(enabled){
        // init stuff that is in use while this state is RUNNING
        this.app.getRootNode().attachChild(getX()); // modify scene graph...
        this.app.doSomethingElse();                 // call custom methods...
      } else {
        // take away everything not needed while this state is PAUSED
        ...
      }
    }

    // Note that update is only called while the state is both attached and enabled.
    @Override
    public void update(float tpf) {
      // do the following while game is RUNNING
      this.app.getRootNode().getChild("blah").scale(tpf); // modify scene graph...
      x.setUserData(...);                                 // call some methods...
    }

}

AKA:

!=

1 Like

Yes, it looks like I was missing the cast. In my code, I didn’t have the line

this.app = (SimpleApplication)app;          // cast to a more specific class

My code implements the Application interface, rather than subclassing the SimpleApplication class (I’m trying to be future-compatible, given that I read that the plan was to switch to Application as an interface, since “SimpleApplication especially is a mess”). It seems the documentation has an implicit assumption that users are still using SimpleApplication, hence my confusion.

So I guess that it does work correctly as-is and doesn’t necessarily need to be fixed. It’s just confusing for those using the newer Application interface.l

You should continue to use SimpleApplication or you will end up providing all of these helper methods yourself.

SimpleApplication will not disappear. There will just be an alternative someday… and a migration path to get there should you decide to.

Even I still extend SimpleApplication even though I’m the one who started the refactoring. I just generally ignore everything about SimpleApplication except the super(AppState…) constructor and simpleInit().

1 Like