Browse Source

Reduced the scope of the synchronized block to something
more reasonable (rather than essentially encompassing the
entire application if you build your app around AppStates)
but the realy benefit is now the app states can add/remove
other app states without random oddness happening.
...and it's ever so slightly more efficient now, too.


git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7220 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

PSp..om 14 years ago
parent
commit
f9c321e6e9
1 changed files with 35 additions and 34 deletions
  1. 35 34
      engine/src/core/com/jme3/app/state/AppStateManager.java

+ 35 - 34
engine/src/core/com/jme3/app/state/AppStateManager.java

@@ -50,11 +50,21 @@ public class AppStateManager {
 
     private final ArrayList<AppState> states = new ArrayList<AppState>();
     private final Application app;
+    private AppState[] stateArray;
 
     public AppStateManager(Application app){
         this.app = app;
     }
 
+    protected AppState[] getArray(){
+        synchronized (states){
+            if (stateArray == null){
+                stateArray = states.toArray(new AppState[states.size()]);
+            }
+            return stateArray;
+        }
+    }
+
     /**
      * Attach a state to the AppStateManager, the same state cannot be attached
      * twice.
@@ -68,6 +78,7 @@ public class AppStateManager {
             if (!states.contains(state)){
                 state.stateAttached(this);
                 states.add(state);
+                stateArray = null;
                 return true;
             }else{
                 return false;
@@ -87,6 +98,7 @@ public class AppStateManager {
             if (states.contains(state)){
                 state.stateDetached(this);
                 states.remove(state);
+                stateArray = null;
                 return true;
             }else{
                 return false;
@@ -132,18 +144,15 @@ public class AppStateManager {
      * @param tpf Time per frame.
      */
     public void update(float tpf){
-        synchronized (states){
-            int num = states.size();
-            for (int i = 0; i < num; i++){
-                AppState state = states.get(i);
-                if (!state.isInitialized())
-                    state.initialize(this, app);
+        AppState[] array = getArray();
+        for (AppState state : array){
+            if (!state.isInitialized())
+                state.initialize(this, app);
 
-                if (state.isEnabled()) {
-                   state.update(tpf);
-                }
+            if (state.isEnabled()) {
+                state.update(tpf);
             }
-        } 
+        }
     }
 
     /**
@@ -151,16 +160,13 @@ public class AppStateManager {
      * @param rm The RenderManager
      */
     public void render(RenderManager rm){
-        synchronized (states){
-            int num = states.size();
-            for (int i = 0; i < num; i++){
-                AppState state = states.get(i);
-                if (!state.isInitialized())
-                    state.initialize(this, app);
+        AppState[] array = getArray();
+        for (AppState state : array){
+            if (!state.isInitialized())
+                state.initialize(this, app);
 
-                if (state.isEnabled()) {
-                   state.render(rm);
-                }
+            if (state.isEnabled()) {
+                state.render(rm);
             }
         }
     }
@@ -170,16 +176,13 @@ public class AppStateManager {
      * @param rm The RenderManager
      */
     public void postRender(){
-        synchronized (states){
-            int num = states.size();
-            for (int i = 0; i < num; i++){
-                AppState state = states.get(i);
-                if (!state.isInitialized())
-                    state.initialize(this, app);
+        AppState[] array = getArray();
+        for (AppState state : array){
+            if (!state.isInitialized())
+                state.initialize(this, app);
 
-                if (state.isEnabled()) {
-                   state.postRender();
-                }
+            if (state.isEnabled()) {
+                state.postRender();
             }
         }
     }
@@ -188,11 +191,9 @@ public class AppStateManager {
      * Calls cleanup on attached states, do not call directly.
      */
     public void cleanup(){
-        synchronized (states){
-            for (int i = 0; i < states.size(); i++){
-                AppState state = states.get(i);
-                state.cleanup();
-            }
+        AppState[] array = getArray();
+        for (AppState state : array){
+            state.cleanup();
         }
-    }
+    }    
 }