Part 2 of the small AppState refactoring: added methods to AppStateManager
for retrieving an AppState by ID. Also modified attach() to throw an IllegalArgumentException if the ID is already registered. Updated TestAppStateLifeCycle to add a small ID demonstration.
This commit is contained in:
parent
3dd2755c20
commit
36afe829c6
@ -37,6 +37,8 @@ import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.util.SafeArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* The <code>AppStateManager</code> holds a list of {@link AppState}s which
|
||||
@ -82,6 +84,12 @@ public class AppStateManager {
|
||||
* cleanup.
|
||||
*/
|
||||
private final SafeArrayList<AppState> terminating = new SafeArrayList<AppState>(AppState.class);
|
||||
|
||||
/**
|
||||
* Thread-safe index of every state that is currently attached and has
|
||||
* an ID.
|
||||
*/
|
||||
private final ConcurrentMap<String, AppState> stateIndex = new ConcurrentHashMap<>();
|
||||
|
||||
// All of the above lists need to be thread safe but access will be
|
||||
// synchronized separately.... but always on the states list. This
|
||||
@ -122,7 +130,8 @@ public class AppStateManager {
|
||||
|
||||
/**
|
||||
* Attach a state to the AppStateManager, the same state cannot be attached
|
||||
* twice.
|
||||
* twice. Throws an IllegalArgumentException if the state has an ID and that
|
||||
* ID has already been associated with another AppState.
|
||||
*
|
||||
* @param state The state to attach
|
||||
* @return True if the state was successfully attached, false if the state
|
||||
@ -130,11 +139,16 @@ public class AppStateManager {
|
||||
*/
|
||||
public boolean attach(AppState state){
|
||||
synchronized (states){
|
||||
if( state.getId() != null && stateIndex.putIfAbsent(state.getId(), state) != null ) {
|
||||
throw new IllegalArgumentException("ID:" + state.getId()
|
||||
+ " is already being used by another state:"
|
||||
+ stateIndex.get(state.getId()));
|
||||
}
|
||||
if (!states.contains(state) && !initializing.contains(state)){
|
||||
state.stateAttached(this);
|
||||
initializing.add(state);
|
||||
return true;
|
||||
}else{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -175,6 +189,12 @@ public class AppStateManager {
|
||||
*/
|
||||
public boolean detach(AppState state){
|
||||
synchronized (states){
|
||||
|
||||
// Remove it from the index if it exists.
|
||||
// Note: we remove it directly from the values() in case
|
||||
// the state has changed its ID since registered.
|
||||
stateIndex.values().remove(state);
|
||||
|
||||
if (states.contains(state)){
|
||||
state.stateDetached(this);
|
||||
states.remove(state);
|
||||
@ -249,6 +269,35 @@ public class AppStateManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state associated with the specified ID at the time it was
|
||||
* attached or null if not state was attached with that ID.
|
||||
*/
|
||||
public <T extends AppState> T getState( String id, Class<T> stateClass ) {
|
||||
return stateClass.cast(stateIndex.get(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is currently a state associated with the specified
|
||||
* ID.
|
||||
*/
|
||||
public boolean hasState( String id ) {
|
||||
return stateIndex.containsKey(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state associated with the specified ID at the time it
|
||||
* was attached or throws an IllegalArgumentException if the ID was
|
||||
* not found.
|
||||
*/
|
||||
public <T extends AppState> T stateForId( String id, Class<T> stateClass ) {
|
||||
T result = getState(id, stateClass);
|
||||
if( result == null ) {
|
||||
throw new IllegalArgumentException("State not found for:" + id);
|
||||
}
|
||||
return stateClass.cast(result);
|
||||
}
|
||||
|
||||
protected void initializePending(){
|
||||
AppState[] array = getInitializing();
|
||||
if (array.length == 0)
|
||||
|
@ -64,7 +64,10 @@ public class TestAppStateLifeCycle extends SimpleApplication {
|
||||
rootNode.attachChild(geom);
|
||||
|
||||
System.out.println("Attaching test state.");
|
||||
stateManager.attach(new TestState());
|
||||
stateManager.attach(new TestState());
|
||||
|
||||
System.out.println("Attaching test state with an ID.");
|
||||
stateManager.attach(new TestState("Test ID"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -74,51 +77,64 @@ public class TestAppStateLifeCycle extends SimpleApplication {
|
||||
System.out.println("Detaching test state.");
|
||||
stateManager.detach(stateManager.getState(TestState.class));
|
||||
System.out.println("Done");
|
||||
}
|
||||
}
|
||||
|
||||
if( stateManager.hasState("Test ID") ) {
|
||||
System.out.println("Detaching test state with an ID.");
|
||||
stateManager.detach(stateManager.getState("Test ID", TestState.class));
|
||||
System.out.println("Done");
|
||||
}
|
||||
}
|
||||
|
||||
public class TestState extends AbstractAppState {
|
||||
|
||||
public TestState() {
|
||||
}
|
||||
|
||||
public TestState( String id ) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(AppStateManager stateManager, Application app) {
|
||||
super.initialize(stateManager, app);
|
||||
System.out.println("Initialized");
|
||||
System.out.println("Initialized, id:" + getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateAttached(AppStateManager stateManager) {
|
||||
super.stateAttached(stateManager);
|
||||
System.out.println("Attached");
|
||||
System.out.println("Attached, id:" + getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float tpf) {
|
||||
super.update(tpf);
|
||||
System.out.println("update");
|
||||
System.out.println("update, id:" + getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderManager rm) {
|
||||
super.render(rm);
|
||||
System.out.println("render");
|
||||
System.out.println("render, id:" + getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postRender() {
|
||||
super.postRender();
|
||||
System.out.println("postRender");
|
||||
System.out.println("postRender, id:" + getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateDetached(AppStateManager stateManager) {
|
||||
super.stateDetached(stateManager);
|
||||
System.out.println("Detached");
|
||||
System.out.println("Detached, id:" + getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
super.cleanup();
|
||||
System.out.println("Cleanup");
|
||||
System.out.println("Cleanup, id:" + getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user