Browse Source

Moved the stats view stuff out into an app state
that is added automatically as part of simple app
construction.


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

PSp..om 13 years ago
parent
commit
4c18bfaecb

+ 36 - 50
engine/src/core/com/jme3/app/SimpleApplication.java

@@ -31,6 +31,7 @@
  */
 package com.jme3.app;
 
+import com.jme3.app.state.AppState;
 import com.jme3.font.BitmapFont;
 import com.jme3.font.BitmapText;
 import com.jme3.input.FlyByCamera;
@@ -72,14 +73,10 @@ public abstract class SimpleApplication extends Application {
                                                                          
     protected Node rootNode = new Node("Root Node");
     protected Node guiNode = new Node("Gui Node");
-    protected float secondCounter = 0.0f;
-    protected int frameCounter = 0;
     protected BitmapText fpsText;
     protected BitmapFont guiFont;
-    protected StatsView statsView;
     protected FlyByCamera flyCam;
     protected boolean showSettings = true;
-    private  boolean showFps = true;
     private AppActionListener actionListener = new AppActionListener();
     
     private class AppActionListener implements ActionListener {
@@ -103,15 +100,22 @@ public abstract class SimpleApplication extends Application {
             } else if (name.equals(INPUT_MAPPING_MEMORY)) {
                 BufferUtils.printCurrentDirectMemory(null);
             }else if (name.equals(INPUT_MAPPING_HIDE_STATS)){
-                boolean show = showFps;
-                setDisplayFps(!show);
-                setDisplayStatView(!show);
+                if (stateManager.getState(StatsAppState.class) != null) {
+                    stateManager.getState(StatsAppState.class).toggleStats();
+                }
             }
         }
     }
 
     public SimpleApplication() {
+        this( new StatsAppState() );
+    }
+
+    public SimpleApplication( AppState... initialStates ) {
         super();
+        for (AppState a : initialStates) {
+            stateManager.attach(a);
+        }
     }
 
     @Override
@@ -175,38 +179,12 @@ public abstract class SimpleApplication extends Application {
         this.showSettings = showSettings;
     }
 
-    /**
-     * Attaches FPS statistics to guiNode and displays it on the screen.
-     *
-     */
-    public void loadFPSText() {
-        guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
-        fpsText = new BitmapText(guiFont, false);
-        fpsText.setLocalTranslation(0, fpsText.getLineHeight(), 0);
-        fpsText.setText("Frames per second");
-        guiNode.attachChild(fpsText);
-    }
-
-    /**
-     * Attaches Statistics View to guiNode and displays it on the screen
-     * above FPS statistics line.
-     *
-     */
-    public void loadStatsView() {
-        statsView = new StatsView("Statistics View", assetManager, renderer.getStatistics());
-//         move it up so it appears above fps text
-        statsView.setLocalTranslation(0, fpsText.getLineHeight(), 0);
-        guiNode.attachChild(statsView);
-    }
-
     @Override
     public void initialize() {
         super.initialize();
 
         guiNode.setQueueBucket(Bucket.Gui);
         guiNode.setCullHint(CullHint.Never);
-        loadFPSText();
-        loadStatsView();
         viewPort.attachScene(rootNode);
         guiViewPort.attachScene(guiNode);
 
@@ -221,12 +199,20 @@ public abstract class SimpleApplication extends Application {
 
             inputManager.addMapping(INPUT_MAPPING_CAMERA_POS, new KeyTrigger(KeyInput.KEY_C));
             inputManager.addMapping(INPUT_MAPPING_MEMORY, new KeyTrigger(KeyInput.KEY_M));
-            inputManager.addMapping(INPUT_MAPPING_HIDE_STATS, new KeyTrigger(KeyInput.KEY_F5));
+            if (stateManager.getState(StatsAppState.class) != null) {
+                inputManager.addMapping(INPUT_MAPPING_HIDE_STATS, new KeyTrigger(KeyInput.KEY_F5));
+            }
             inputManager.addListener(actionListener, INPUT_MAPPING_EXIT,
                     INPUT_MAPPING_CAMERA_POS, INPUT_MAPPING_MEMORY, INPUT_MAPPING_HIDE_STATS);
             
         }
 
+        if (stateManager.getState(StatsAppState.class) != null) {
+            // Some of the tests rely on having access to fpsText
+            // for quick display.  Maybe a different way would be better.
+            fpsText = stateManager.getState(StatsAppState.class).getFpsText();
+        }
+
         // call user code
         simpleInitApp();
     }
@@ -240,42 +226,42 @@ public abstract class SimpleApplication extends Application {
 
         float tpf = timer.getTimePerFrame() * speed;
 
-        if (showFps) {
-            secondCounter += timer.getTimePerFrame();
-            frameCounter ++;
-            if (secondCounter >= 1.0f) {
-                int fps = (int) (frameCounter / secondCounter);
-                fpsText.setText("Frames per second: " + fps);
-                secondCounter = 0.0f;
-                frameCounter = 0;
-            }          
-        }
-
         // update states
         stateManager.update(tpf);
 
         // simple update and root node
         simpleUpdate(tpf);
+ 
         rootNode.updateLogicalState(tpf);
         guiNode.updateLogicalState(tpf);
+        
         rootNode.updateGeometricState();
         guiNode.updateGeometricState();
 
+        // Moving this here to make sure it is always done.
+        // Now the sets are cleared every frame (guaranteed)
+        // and more than one viewer can access the data.  This
+        // used to be cleared by StatsView but then only StatsView
+        // could get accurate counts.
+        renderer.getStatistics().clearFrame();        
+                
         // render states
         stateManager.render(renderManager);
         renderManager.render(tpf, context.isRenderable());
         simpleRender(renderManager);
-        stateManager.postRender();
+        stateManager.postRender();        
     }
 
     public void setDisplayFps(boolean show) {
-        showFps = show;
-        fpsText.setCullHint(show ? CullHint.Never : CullHint.Always);
+        if (stateManager.getState(StatsAppState.class) != null) {
+            stateManager.getState(StatsAppState.class).setDisplayFps(show);
+        }
     }
 
     public void setDisplayStatView(boolean show) {
-        statsView.setEnabled(show);
-        statsView.setCullHint(show ? CullHint.Never : CullHint.Always);
+        if (stateManager.getState(StatsAppState.class) != null) {
+            stateManager.getState(StatsAppState.class).setDisplayStatView(show);
+        }
     }
 
     public abstract void simpleInitApp();

+ 198 - 0
engine/src/core/com/jme3/app/StatsAppState.java

@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.app;
+
+import com.jme3.app.state.AbstractAppState;
+import com.jme3.app.state.AppStateManager;
+import com.jme3.font.BitmapFont;
+import com.jme3.font.BitmapText;
+import com.jme3.renderer.RenderManager;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial.CullHint;
+
+
+/**
+ *  Displays stats in SimpleApplication's GUI node or
+ *  using the node and font parameters provided.  
+ *
+ *  @author    Paul Speed
+ */
+public class StatsAppState extends AbstractAppState {
+
+    private Application app;
+    protected StatsView statsView;
+    protected boolean showSettings = true;
+    private  boolean showFps = true;
+    private  boolean showStats = true;
+    
+    protected Node guiNode;
+    protected float secondCounter = 0.0f;
+    protected int frameCounter = 0;
+    protected BitmapText fpsText;
+    protected BitmapFont guiFont;
+
+    public StatsAppState() {
+    }    
+
+    public StatsAppState( Node guiNode, BitmapFont guiFont ) {
+        this.guiNode = guiNode;
+        this.guiFont = guiFont;
+    }
+
+    public BitmapText getFpsText() {
+        return fpsText;
+    }
+
+    public float getSecondCounter() {
+        return secondCounter;
+    }
+
+    public void toggleStats() {
+        setDisplayFps( !showFps );
+        setDisplayStatView( !showStats );
+    }
+
+    public void setDisplayFps(boolean show) {
+        showFps = show;
+        if (fpsText != null) {
+            fpsText.setCullHint(show ? CullHint.Never : CullHint.Always);
+        }
+    }
+
+    public void setDisplayStatView(boolean show) {
+        showStats = show;
+        if (statsView != null ) {
+            statsView.setEnabled(show);
+            statsView.setCullHint(show ? CullHint.Never : CullHint.Always);
+        }
+    }
+
+    @Override
+    public void initialize(AppStateManager stateManager, Application app) {
+        super.initialize(stateManager, app);
+        this.app = app;
+               
+        if (app instanceof SimpleApplication) {
+            SimpleApplication simpleApp = (SimpleApplication)app;
+            if (guiNode == null)
+                guiNode = simpleApp.guiNode;
+            if (guiFont == null )
+                guiFont = simpleApp.guiFont;
+        } 
+        
+        if (guiNode == null) {
+            throw new RuntimeException( "No guiNode specific and cannot be automatically determined." );
+        } 
+        
+        if (guiFont == null) {
+            guiFont = app.getAssetManager().loadFont("Interface/Fonts/Default.fnt");
+        }
+        
+        loadFpsText();  
+        loadStatsView();      
+    }
+            
+    /**
+     * Attaches FPS statistics to guiNode and displays it on the screen.
+     *
+     */
+    public void loadFpsText() {
+        fpsText = new BitmapText(guiFont, false);
+        fpsText.setLocalTranslation(0, fpsText.getLineHeight(), 0);
+        fpsText.setText("Frames per second");
+        fpsText.setCullHint(showFps ? CullHint.Never : CullHint.Always);
+        guiNode.attachChild(fpsText);
+    }
+
+    /**
+     * Attaches Statistics View to guiNode and displays it on the screen
+     * above FPS statistics line.
+     *
+     */
+    public void loadStatsView() {
+        statsView = new StatsView("Statistics View", 
+                                  app.getAssetManager(), 
+                                  app.getRenderer().getStatistics());
+        // move it up so it appears above fps text
+        statsView.setLocalTranslation(0, fpsText.getLineHeight(), 0);
+        statsView.setEnabled(showStats);
+        statsView.setCullHint(showStats ? CullHint.Never : CullHint.Always);        
+        guiNode.attachChild(statsView);
+    }
+        
+    @Override
+    public void setEnabled(boolean enabled) {
+        super.setEnabled(enabled);
+        
+        if (enabled) {
+            fpsText.setCullHint(showFps ? CullHint.Never : CullHint.Always);
+            statsView.setEnabled(showStats);
+            statsView.setCullHint(showStats ? CullHint.Never : CullHint.Always);        
+        } else {
+            fpsText.setCullHint(CullHint.Always);
+            statsView.setEnabled(false);
+            statsView.setCullHint(CullHint.Always);        
+        }
+    }
+    
+    @Override
+    public void update(float tpf) {
+        if (showFps) {
+            secondCounter += app.getTimer().getTimePerFrame();
+            frameCounter ++;
+            if (secondCounter >= 1.0f) {
+                int fps = (int) (frameCounter / secondCounter);
+                fpsText.setText("Frames per second: " + fps);
+                secondCounter = 0.0f;
+                frameCounter = 0;
+            }          
+        }
+    }
+
+    @Override
+    public void render(RenderManager rm) {
+    }
+
+    @Override
+    public void postRender(){
+    }
+
+    @Override
+    public void cleanup() {
+        super.cleanup();
+        
+        guiNode.detachChild(statsView);
+        guiNode.detachChild(fpsText);
+    }
+
+
+}

+ 1 - 1
engine/src/core/com/jme3/app/StatsView.java

@@ -108,7 +108,7 @@ public class StatsView extends Node implements Control {
         // Moved to SimpleApplication to make sure it is
         // done even if there is no StatsView or the StatsView
         // is disable.
-        statistics.clearFrame();
+        //statistics.clearFrame();
     }
 
     public Control cloneForSpatial(Spatial spatial) {