Seeking clarification on Application States wiki page

Hello, I have been working on some states for my game, and while reading the Application States wiki, I noticed that in the AbstractAppState section (which I am following), initialize and setEnabled(true) do pretty much the same thing.
Where I’m confused however, is what the specific purpose on each handle is. The way I understand it, initialize should be used for prepping the state, but not attaching it, setEnabled should attach/detach the state, and cleanup is for cleaning up the state after it’s not longer needed. But it seems to me that the wiki has a different lifecycle in mind for states.

Is my assumption of the state handles correct?
What is the lifecycle of a AbstractAppState as the wiki describes it?

a) if the wiki is recommending to extend AbstractAppState then it’s ancient. Extend BaseAppState instead and reap many benefits… not the least of which is a more appropriate set of methods to override.
b) AppStateManager javadoc has some information on the lifecycle: AppStateManager (jMonkeyEngine3)

An app state is initialized once (on the render thread) after being attached (from potentially any thread). It can separately be enabled/disabled throughout its life while still attached and initialized. (For example, an in-game menu might be initialized at game start but enabled/disabled only as the user pops open the menu.)

Getting the “when should I enabled versus initialize versus disable” stuff right when extending AbstractAppState is super hard. BaseAppState takes care of this management for you and will call the non-final initialize(Application) method and onEnable(), onDisable() methods as appropriate.

https://javadoc.jmonkeyengine.org/v3.3.2-stable/com/jme3/app/state/BaseAppState.html

Edit: incidentally, if you want to see examples of app states in “real” applications, you can check out how they are used in some of my example apps:

1 Like

It’s nothing but a regular lifecycle , setEnabled doesn’t detach the app state , it ensures that the update of the app state has been hibernated some time until you turn it on again(think of a switch, the switch wonot work w/o plugging in the appliance cable),default is enabled, other methods cleanup() doesn’t do anything recognized indeed it’s created for you like a listener to override in your app state to do something when the app state is detached ,so to recap lifecycle :

#Attach
#initialize()
#onEnabled() listens for an app state being enabled
#onDisabled()

#update
-----------------as long as you donot stop or detach.
#stop()

Think of them as listeners that will eventually fire on a scheduled pathway.

1 Like

These are only available when you extend BaseAppState as described in my comment.

2 Likes

Much appreciated! I’m gonna switch to BaseAppState, you sold me on that!

So, just to make sure I’m on the same page as you and @Pavl_G, the lifecycle of BaseAppState is as follows:

  • attach appstate
  • appstate.initialize
  • appstate.setEnabled/onEnabled/onDisabled
  • update
  • cleanup

Right?
One more question regarding the lifecycle.
Let’s say I have two appstates, one for the main menu (let’s call it Launcher) and one for the game (let’s call it Game). Before this, I had planned to completely detach the Launcher state when Game takes over, but now looking at this structure, I’m unsure if I should be detaching Launcher when Game takes over, or if pausing (setEnabled(false)) would suffice. Any opinions on that?

1 Like

Also, could the wiki on App States be updated slightly to indicate what calls will trigger which handle? Such as:

@Override
    protected void initialize(Application app) {
        //This method is triggered when a state is attached with statemanager.attach()

        //It is technically safe to do all initialization and cleanup in the
        //onEnable()/onDisable() methods. Choosing to use initialize() and
        //cleanup() for this is a matter of performance specifics for the
        //implementor.
        //TODO: initialize your AppState, e.g. attach spatials to rootNode
    }

Or something like that. I think it would help new users understand how things connect together. I could write it myself, but be warned I am not good at explaining things haha

Well, I gave it a shot haha. Feel free to shoot it down, I’m not even sure if it’s needed (or even worded right):

Just depends.

I tend to only detach app states when going backwards.

For example, I’ll leave my MainMenuState attached and just disable it when the game starts. I want it to be able to pop right back up and I do all of the UI building in initialize(). onEnable() only adds it to the guiNode.

But the GameSessionState or whatever is attached by the main menu and gets detached when the game is done… presumably because the next GameSessionState may want completely different settings and should go through initialize() again.

2 Likes

It doesn’t. It explains them as they are still part of the engine.

It also recommends using BaseAppState and says pretty much everything you just did and then some.

1 Like

Gotcha! That makes a lot of sense, pretty much leave things attached unless you want it to initialize again right?

@mitm I know, I had read that page a few times, I was mostly confused about the order of the lifecycle methods, but again, I was trying to use AbstractAppState and like @pspeed said, switching to BaseAppState made implementing the state a lot easier and more intuitive. However, now I’m wondering if BaseAppState should be introduced first in that wiki page, since it’s the recommended way to go. I was using AbstractAppState because that’s the first one I saw, and kind of blindly went with the first option I saw

AbstractAppState is just another way of implementing AppStates so it doesn’t hurt to leave it as is.

It doesn’t work to have BaseAppState before AbstractAppState though as this page currently explains the old vs best way and BaseAppState is literally within sight when reading about Abstract.

Technically, it should just be BaseAppState imo now that the wiki is versioned.

1 Like

I get what your saying. I should have read the whole thing before I jumped in honestly.

Unfortunately on mobile (at least my mobile), the screen didn’t make it that far. I do my referencing on my phone because I’d kill my laptop with the amount of tabs I have open, plus it’s nice to have two screens to work with

Would you guys need help with the wiki? I’m not good at producing content but can confidently edit

I will edit it real quick to explain that there are two ways of doing it earlier in the doc so as not to confuse.

1 Like

Always, I already made a comment to your PR.

1 Like

That would be a great edit. I think adding the extra clarity for newer users can definitely help prevent others (like myself haha) from jumping ahead without understanding their options

Great! I’d be glad to help out!
I didn’t know you commented, I’ll check it out right now!

Check BaseAppState Source :slight_smile: : , its all about a couple of interfaces that get called back within the update of your app when you do stateManager.attach(state);

and you can read those java docs for the raw AppState interface which you can implement also instead.

1 Like

Much appreciated! I’ll pour through those in a bit

FYI: in wiki there is BaseAppState example

there are both AbstractAppState and BaseAppState

tho examples like:

use AbstractAppState

so its like only some part of wiki are ancient, but not all.

2 Likes