Hi folks,
I have a problem while implementing an action that should happen after the user requested to close the app (e.g. via pressing Esc). My main class inherits from SimpleApplication so I thought there will be something like simpleClose or simpleCleanup to place my code as there are simpleInitApp or simpleUpdate etc… but there are only stop()/stop(boolean) and destroy(). I hesitate from overriding them and I’ll need to call super anyways or I register a new event at the input listener…
So is there any recommended way to implement such a “shutdown hook” with SimpleApplication?
override destroy() and call super.destroy()
Will do so, thank you!
The cleanup() methods of any attached app states will also be called during shutdown.
For things that don’t actually need to override the behavior of destroy (ie: by stopping the destruction) and are already doing app-state-y things, cleanup() may be a better option.
I’m currently implementing the approach described in https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:multithreading and therefore I maintain an instance of a ScheduledThreadPoolExecutor in my main app class available for all app states and things… I don’t felt like moving this piece of data into an app state but found the concept of the app state’s cleanup() methods good so that’s why I asked.
The thing is… your other app states would have an easier time getting at the executor if it was also an app state. Otherwise you have to pass references to application all over the place.
Where to draw the lines on these idioms is personal preference on some level, but personally I’ve nearly completely gutted my SimpleApplication subclass in favor of separate app states… the flexibility has been nothing but up side.
Passing my application’s reference to many places is actually what I’m doing now - is that a sign of a bad design? Instead should I create individual (and small?) app states for e.g. the task to maintain my executor?
To reference one app state from within another it’s a good idea to use something like this?
[java]app.getStateManager().getState(MyExecutorAppState.class);[/java]
You can pass references to Application around. Sometimes that’s easier than passing asset manager, etc…
But a lot of times, my stuff only needs other app states… so I just use the state manager that I was provided.
I do cheat a little, though. I created a base AppState class that keeps the state manager around and has its own getState() method:
[java]
protected <T extends AppState> T getState( Class<T> stateType ) {
return stateManager.getState(stateType);
}
[/java]
or whatever. Then my states merely need to do getState()… so in your example:
getState(MyExecutorAppState.class).execute( myCallable );
I don’t think its an “issue” passing app around… You might want to access different AppStates or maybe even check if specific AppStates exist to enable certain functions or UI elements etc. I think paul is thinking from a quite specific implementation view where the “interconnection” of your applications main functions is already implemented though other means (e.g. and entity system and/or database) and you really just need some “hook” into the main update loop / lifetime at specific places.
@normen said:
You might want to access different AppStates or maybe even check if specific AppStates exist to enable certain functions or UI elements etc.
All of those things can be done without an Application reference. And anyway, Application is also provided on the initialize() of app states.
In general, though, I find the only things I ever need Application for are rootNode, guiNode, camera, and asset manager. AppStates I think as a rule should hold a reference to their state manager.
And in Mythruna, asset manager and root node are the only things I pass around anymore. My various cameras are available through app states. And part of me likes making the AssetManager passing specific as it clearly shows a "class that will be loading assets". Hmm... actually, even my root nodes are available through app states now. I may do the same for AssetManager.
I fear it maybe become an issue and constrain me later when I e.g. implement another main app class launching some editor instead of the game itself - currently the app is the lowest common denominator providing all the basic objects of my “game”… and I’m using app states to encapsulate “major functions” like display and lifecycle of stars (depending on time of the day which is handled in app) or the sun or the sky from other app states so there are not too many dependencies between these app states I have to think about… maybe I have to rethink app state as they are designed to depend on each other?
I don’t know… but my app states are definitely two levels deep. Sort of a base layer of useful stuff like animation, GUI, etc. that the other app states can then depend on.
Maybe that model will work for me too since atm my main app is the complete base layer… and that could be split up I think ^^
There are basic dependencies in my game (as in every game I assume) so there’s no way round this fact.
Anyways thank you for showing me some pros and cons about that passing app and app state topic!
It was really convenient when I went to create a quick prototype that just used some of Mythruna’s parts… so that I could work on some physics stuff. I could just depend on that project, write a new SimpleApplication, and include the app states I wanted.