Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (c) 2009-2012 jMonkeyEngine
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  * * Redistributions of source code must retain the above copyright
     10  *   notice, this list of conditions and the following disclaimer.
     11  *
     12  * * Redistributions in binary form must reproduce the above copyright
     13  *   notice, this list of conditions and the following disclaimer in the
     14  *   documentation and/or other materials provided with the distribution.
     15  *
     16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
     17  *   may be used to endorse or promote products derived from this software
     18  *   without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 package com.jme3.app;
     33 
     34 import com.jme3.app.state.AbstractAppState;
     35 import com.jme3.app.state.AppStateManager;
     36 import com.jme3.font.BitmapFont;
     37 import com.jme3.font.BitmapText;
     38 import com.jme3.renderer.RenderManager;
     39 import com.jme3.scene.Node;
     40 import com.jme3.scene.Spatial.CullHint;
     41 
     42 
     43 /**
     44  *  Displays stats in SimpleApplication's GUI node or
     45  *  using the node and font parameters provided.
     46  *
     47  *  @author    Paul Speed
     48  */
     49 public class StatsAppState extends AbstractAppState {
     50 
     51     private Application app;
     52     protected StatsView statsView;
     53     protected boolean showSettings = true;
     54     private  boolean showFps = true;
     55     private  boolean showStats = true;
     56 
     57     protected Node guiNode;
     58     protected float secondCounter = 0.0f;
     59     protected int frameCounter = 0;
     60     protected BitmapText fpsText;
     61     protected BitmapFont guiFont;
     62 
     63     public StatsAppState() {
     64     }
     65 
     66     public StatsAppState( Node guiNode, BitmapFont guiFont ) {
     67         this.guiNode = guiNode;
     68         this.guiFont = guiFont;
     69     }
     70 
     71     /**
     72      *  Called by SimpleApplication to provide an early font
     73      *  so that the fpsText can be created before init.  This
     74      *  is because several applications expect to directly access
     75      *  fpsText... unfortunately.
     76      */
     77     void setFont( BitmapFont guiFont ) {
     78         this.guiFont = guiFont;
     79         this.fpsText = new BitmapText(guiFont, false);
     80     }
     81 
     82     public BitmapText getFpsText() {
     83         return fpsText;
     84     }
     85 
     86     public StatsView getStatsView() {
     87         return statsView;
     88     }
     89 
     90     public float getSecondCounter() {
     91         return secondCounter;
     92     }
     93 
     94     public void toggleStats() {
     95         setDisplayFps( !showFps );
     96         setDisplayStatView( !showStats );
     97     }
     98 
     99     public void setDisplayFps(boolean show) {
    100         showFps = show;
    101         if (fpsText != null) {
    102             fpsText.setCullHint(show ? CullHint.Never : CullHint.Always);
    103         }
    104     }
    105 
    106     public void setDisplayStatView(boolean show) {
    107         showStats = show;
    108         if (statsView != null ) {
    109             statsView.setEnabled(show);
    110             statsView.setCullHint(show ? CullHint.Never : CullHint.Always);
    111         }
    112     }
    113 
    114     @Override
    115     public void initialize(AppStateManager stateManager, Application app) {
    116         super.initialize(stateManager, app);
    117         this.app = app;
    118 
    119         if (app instanceof SimpleApplication) {
    120             SimpleApplication simpleApp = (SimpleApplication)app;
    121             if (guiNode == null)
    122                 guiNode = simpleApp.guiNode;
    123             if (guiFont == null )
    124                 guiFont = simpleApp.guiFont;
    125         }
    126 
    127         if (guiNode == null) {
    128             throw new RuntimeException( "No guiNode specific and cannot be automatically determined." );
    129         }
    130 
    131         if (guiFont == null) {
    132             guiFont = app.getAssetManager().loadFont("Interface/Fonts/Default.fnt");
    133         }
    134 
    135         loadFpsText();
    136         loadStatsView();
    137     }
    138 
    139     /**
    140      * Attaches FPS statistics to guiNode and displays it on the screen.
    141      *
    142      */
    143     public void loadFpsText() {
    144         if (fpsText == null) {
    145             fpsText = new BitmapText(guiFont, false);
    146         }
    147 
    148         fpsText.setLocalTranslation(0, fpsText.getLineHeight(), 0);
    149         fpsText.setText("Frames per second");
    150         fpsText.setCullHint(showFps ? CullHint.Never : CullHint.Always);
    151         guiNode.attachChild(fpsText);
    152     }
    153 
    154     /**
    155      * Attaches Statistics View to guiNode and displays it on the screen
    156      * above FPS statistics line.
    157      *
    158      */
    159     public void loadStatsView() {
    160         statsView = new StatsView("Statistics View",
    161                                   app.getAssetManager(),
    162                                   app.getRenderer().getStatistics());
    163         // move it up so it appears above fps text
    164         statsView.setLocalTranslation(0, fpsText.getLineHeight(), 0);
    165         statsView.setEnabled(showStats);
    166         statsView.setCullHint(showStats ? CullHint.Never : CullHint.Always);
    167         guiNode.attachChild(statsView);
    168     }
    169 
    170     @Override
    171     public void setEnabled(boolean enabled) {
    172         super.setEnabled(enabled);
    173 
    174         if (enabled) {
    175             fpsText.setCullHint(showFps ? CullHint.Never : CullHint.Always);
    176             statsView.setEnabled(showStats);
    177             statsView.setCullHint(showStats ? CullHint.Never : CullHint.Always);
    178         } else {
    179             fpsText.setCullHint(CullHint.Always);
    180             statsView.setEnabled(false);
    181             statsView.setCullHint(CullHint.Always);
    182         }
    183     }
    184 
    185     @Override
    186     public void update(float tpf) {
    187         if (showFps) {
    188             secondCounter += app.getTimer().getTimePerFrame();
    189             frameCounter ++;
    190             if (secondCounter >= 1.0f) {
    191                 int fps = (int) (frameCounter / secondCounter);
    192                 fpsText.setText("Frames per second: " + fps);
    193                 secondCounter = 0.0f;
    194                 frameCounter = 0;
    195             }
    196         }
    197     }
    198 
    199     @Override
    200     public void cleanup() {
    201         super.cleanup();
    202 
    203         guiNode.detachChild(statsView);
    204         guiNode.detachChild(fpsText);
    205     }
    206 
    207 
    208 }
    209