瀏覽代碼

add dot

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10120 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
nor..om 12 年之前
父節點
當前提交
28bb74fa95
共有 1 個文件被更改,包括 656 次插入656 次删除
  1. 656 656
      engine/src/core/com/jme3/app/Application.java

+ 656 - 656
engine/src/core/com/jme3/app/Application.java

@@ -1,656 +1,656 @@
-/*
- * 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.AppStateManager;
-import com.jme3.asset.AssetManager;
-import com.jme3.audio.AudioContext;
-import com.jme3.audio.AudioRenderer;
-import com.jme3.audio.Listener;
-import com.jme3.input.*;
-import com.jme3.math.Vector3f;
-import com.jme3.renderer.Camera;
-import com.jme3.renderer.RenderManager;
-import com.jme3.renderer.Renderer;
-import com.jme3.renderer.ViewPort;
-import com.jme3.system.*;
-import com.jme3.system.JmeContext.Type;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.Future;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * The <code>Application</code> class represents an instance of a
- * real-time 3D rendering jME application.
- *
- * An <code>Application</code> provides all the tools that are commonly used in jME3
- * applications.
- *
- * jME3 applications *SHOULD NOT EXTEND* this class but extend {@link com.jme3.appSimpleApplication} instead.
- *
- */
-public class Application implements SystemListener {
-
-    private static final Logger logger = Logger.getLogger(Application.class.getName());
-
-    protected AssetManager assetManager;
-
-    protected AudioRenderer audioRenderer;
-    protected Renderer renderer;
-    protected RenderManager renderManager;
-    protected ViewPort viewPort;
-    protected ViewPort guiViewPort;
-
-    protected JmeContext context;
-    protected AppSettings settings;
-    protected Timer timer = new NanoTimer();
-    protected Camera cam;
-    protected Listener listener;
-
-    protected boolean inputEnabled = true;
-    protected boolean pauseOnFocus = true;
-    protected float speed = 1f;
-    protected boolean paused = false;
-    protected MouseInput mouseInput;
-    protected KeyInput keyInput;
-    protected JoyInput joyInput;
-    protected TouchInput touchInput;
-    protected InputManager inputManager;
-    protected AppStateManager stateManager;
-
-    private final ConcurrentLinkedQueue<AppTask<?>> taskQueue = new ConcurrentLinkedQueue<AppTask<?>>();
-
-    /**
-     * Create a new instance of <code>Application</code>.
-     */
-    public Application(){
-        initStateManager();
-    }
-
-    /**
-     * Returns true if pause on lost focus is enabled, false otherwise.
-     *
-     * @return true if pause on lost focus is enabled
-     *
-     * @see #setPauseOnLostFocus(boolean)
-     */
-    public boolean isPauseOnLostFocus() {
-        return pauseOnFocus;
-    }
-
-    /**
-     * Enable or disable pause on lost focus.
-     * <p>
-     * By default, pause on lost focus is enabled.
-     * If enabled, the application will stop updating
-     * when it loses focus or becomes inactive (e.g. alt-tab).
-     * For online or real-time applications, this might not be preferable,
-     * so this feature should be set to disabled. For other applications,
-     * it is best to keep it on so that CPU usage is not used when
-     * not necessary.
-     *
-     * @param pauseOnLostFocus True to enable pause on lost focus, false
-     * otherwise.
-     */
-    public void setPauseOnLostFocus(boolean pauseOnLostFocus) {
-        this.pauseOnFocus = pauseOnLostFocus;
-    }
-
-    @Deprecated
-    public void setAssetManager(AssetManager assetManager){
-        if (this.assetManager != null)
-            throw new IllegalStateException("Can only set asset manager"
-                                          + " before initialization.");
-
-        this.assetManager = assetManager;
-    }
-
-    private void initAssetManager(){
-        if (settings != null){
-            String assetCfg = settings.getString("AssetConfigURL");
-            if (assetCfg != null){
-                URL url = null;
-                try {
-                    url = new URL(assetCfg);
-                } catch (MalformedURLException ex) {
-                }
-                if (url == null) {
-                    url = Application.class.getClassLoader().getResource(assetCfg);
-                    if (url == null) {
-                        logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", assetCfg);
-                        return;
-                    }
-                }
-                assetManager = JmeSystem.newAssetManager(url);
-            }
-        }
-        if (assetManager == null){
-            assetManager = JmeSystem.newAssetManager(
-                    Thread.currentThread().getContextClassLoader()
-                    .getResource("com/jme3/asset/Desktop.cfg"));
-        }
-    }
-
-    /**
-     * Set the display settings to define the display created.
-     * <p>
-     * Examples of display parameters include display pixel width and height,
-     * color bit depth, z-buffer bits, anti-aliasing samples, and update frequency.
-     * If this method is called while the application is already running, then
-     * {@link #restart() } must be called to apply the settings to the display.
-     *
-     * @param settings The settings to set.
-     */
-    public void setSettings(AppSettings settings){
-        this.settings = settings;
-        if (context != null && settings.useInput() != inputEnabled){
-            // may need to create or destroy input based
-            // on settings change
-            inputEnabled = !inputEnabled;
-            if (inputEnabled){
-                initInput();
-            }else{
-                destroyInput();
-            }
-        }else{
-            inputEnabled = settings.useInput();
-        }
-    }
-
-    /**
-     * Sets the Timer implementation that will be used for calculating
-     * frame times.  By default, Application will use the Timer as returned
-     * by the current JmeContext implementation.
-     */
-    public void setTimer(Timer timer){
-        this.timer = timer;
-
-        if (timer != null) {
-            timer.reset();
-        }
-
-        if (renderManager != null) {
-            renderManager.setTimer(timer);
-        }
-    }
-
-    public Timer getTimer(){
-        return timer;
-    }
-
-    private void initDisplay(){
-        // aquire important objects
-        // from the context
-        settings = context.getSettings();
-
-        // Only reset the timer if a user has not already provided one
-        if (timer == null) {
-            timer = context.getTimer();
-        }
-
-        renderer = context.getRenderer();
-    }
-
-    private void initAudio(){
-        if (settings.getAudioRenderer() != null && context.getType() != Type.Headless){
-            audioRenderer = JmeSystem.newAudioRenderer(settings);
-            audioRenderer.initialize();
-            AudioContext.setAudioRenderer(audioRenderer);
-
-            listener = new Listener();
-            audioRenderer.setListener(listener);
-        }
-    }
-
-    /**
-     * Creates the camera to use for rendering. Default values are perspective
-     * projection with 45° field of view, with near and far values 1 and 1000
-     * units respectively.
-     */
-    private void initCamera(){
-        cam = new Camera(settings.getWidth(), settings.getHeight());
-
-        cam.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f);
-        cam.setLocation(new Vector3f(0f, 0f, 10f));
-        cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);
-
-        renderManager = new RenderManager(renderer);
-        //Remy - 09/14/2010 setted the timer in the renderManager
-        renderManager.setTimer(timer);
-        viewPort = renderManager.createMainView("Default", cam);
-        viewPort.setClearFlags(true, true, true);
-
-        // Create a new cam for the gui
-        Camera guiCam = new Camera(settings.getWidth(), settings.getHeight());
-        guiViewPort = renderManager.createPostView("Gui Default", guiCam);
-        guiViewPort.setClearFlags(false, false, false);
-    }
-
-    /**
-     * Initializes mouse and keyboard input. Also
-     * initializes joystick input if joysticks are enabled in the
-     * AppSettings.
-     */
-    private void initInput(){
-        mouseInput = context.getMouseInput();
-        if (mouseInput != null)
-            mouseInput.initialize();
-
-        keyInput = context.getKeyInput();
-        if (keyInput != null)
-            keyInput.initialize();
-
-        touchInput = context.getTouchInput();
-        if (touchInput != null)
-            touchInput.initialize();
-
-        if (!settings.getBoolean("DisableJoysticks")){
-            joyInput = context.getJoyInput();
-            if (joyInput != null)
-                joyInput.initialize();
-        }
-
-        inputManager = new InputManager(mouseInput, keyInput, joyInput, touchInput);
-    }
-
-    private void initStateManager(){
-        stateManager = new AppStateManager(this);
-
-        // Always register a ResetStatsState to make sure
-        // that the stats are cleared every frame
-        stateManager.attach(new ResetStatsState());
-    }
-
-    /**
-     * @return The {@link AssetManager asset manager} for this application.
-     */
-    public AssetManager getAssetManager(){
-        return assetManager;
-    }
-
-    /**
-     * @return the {@link InputManager input manager}.
-     */
-    public InputManager getInputManager(){
-        return inputManager;
-    }
-
-    /**
-     * @return the {@link AppStateManager app state manager}
-     */
-    public AppStateManager getStateManager() {
-        return stateManager;
-    }
-
-    /**
-     * @return the {@link RenderManager render manager}
-     */
-    public RenderManager getRenderManager() {
-        return renderManager;
-    }
-
-    /**
-     * @return The {@link Renderer renderer} for the application
-     */
-    public Renderer getRenderer(){
-        return renderer;
-    }
-
-    /**
-     * @return The {@link AudioRenderer audio renderer} for the application
-     */
-    public AudioRenderer getAudioRenderer() {
-        return audioRenderer;
-    }
-
-    /**
-     * @return The {@link Listener listener} object for audio
-     */
-    public Listener getListener() {
-        return listener;
-    }
-
-    /**
-     * @return The {@link JmeContext display context} for the application
-     */
-    public JmeContext getContext(){
-        return context;
-    }
-
-    /**
-     * @return The {@link Camera camera} for the application
-     */
-    public Camera getCamera(){
-        return cam;
-    }
-
-    /**
-     * Starts the application in {@link Type#Display display} mode.
-     *
-     * @see #start(com.jme3.system.JmeContext.Type)
-     */
-    public void start(){
-        start(JmeContext.Type.Display);
-    }
-
-    /**
-     * Starts the application.
-     * Creating a rendering context and executing
-     * the main loop in a separate thread.
-     */
-    public void start(JmeContext.Type contextType){
-        if (context != null && context.isCreated()){
-            logger.warning("start() called when application already created!");
-            return;
-        }
-
-        if (settings == null){
-            settings = new AppSettings(true);
-        }
-
-        logger.log(Level.FINE, "Starting application: {0}", getClass().getName());
-        context = JmeSystem.newContext(settings, contextType);
-        context.setSystemListener(this);
-        context.create(false);
-    }
-
-    /**
-     * Initializes the application's canvas for use.
-     * <p>
-     * After calling this method, cast the {@link #getContext() context} to
-     * {@link JmeCanvasContext},
-     * then acquire the canvas with {@link JmeCanvasContext#getCanvas() }
-     * and attach it to an AWT/Swing Frame.
-     * The rendering thread will start when the canvas becomes visible on
-     * screen, however if you wish to start the context immediately you
-     * may call {@link #startCanvas() } to force the rendering thread
-     * to start.
-     *
-     * @see JmeCanvasContext
-     * @see Type#Canvas
-     */
-    public void createCanvas(){
-        if (context != null && context.isCreated()){
-            logger.warning("createCanvas() called when application already created!");
-            return;
-        }
-
-        if (settings == null){
-            settings = new AppSettings(true);
-        }
-
-        logger.log(Level.FINE, "Starting application: {0}", getClass().getName());
-        context = JmeSystem.newContext(settings, JmeContext.Type.Canvas);
-        context.setSystemListener(this);
-    }
-
-    /**
-     * Starts the rendering thread after createCanvas() has been called.
-     * <p>
-     * Same as calling startCanvas(false)
-     *
-     * @see #startCanvas(boolean)
-     */
-    public void startCanvas(){
-        startCanvas(false);
-    }
-
-    /**
-     * Starts the rendering thread after createCanvas() has been called.
-     * <p>
-     * Calling this method is optional, the canvas will start automatically
-     * when it becomes visible.
-     *
-     * @param waitFor If true, the current thread will block until the
-     * rendering thread is running
-     */
-    public void startCanvas(boolean waitFor){
-        context.create(waitFor);
-    }
-
-    /**
-     * Internal use only.
-     */
-    public void reshape(int w, int h){
-        renderManager.notifyReshape(w, h);
-    }
-
-    /**
-     * Restarts the context, applying any changed settings.
-     * <p>
-     * Changes to the {@link AppSettings} of this Application are not
-     * applied immediately; calling this method forces the context
-     * to restart, applying the new settings.
-     */
-    public void restart(){
-        context.setSettings(settings);
-        context.restart();
-    }
-
-    /**
-     * Requests the context to close, shutting down the main loop
-     * and making necessary cleanup operations.
-     *
-     * Same as calling stop(false)
-     *
-     * @see #stop(boolean)
-     */
-    public void stop(){
-        stop(false);
-    }
-
-    /**
-     * Requests the context to close, shutting down the main loop
-     * and making necessary cleanup operations.
-     * After the application has stopped, it cannot be used anymore.
-     */
-    public void stop(boolean waitFor){
-        logger.log(Level.FINE, "Closing application: {0}", getClass().getName());
-        context.destroy(waitFor);
-    }
-
-    /**
-     * Do not call manually.
-     * Callback from ContextListener.
-     * <p>
-     * Initializes the <code>Application</code>, by creating a display and
-     * default camera. If display settings are not specified, a default
-     * 640x480 display is created. Default values are used for the camera;
-     * perspective projection with 45° field of view, with near
-     * and far values 1 and 1000 units respectively.
-     */
-    public void initialize(){
-        if (assetManager == null){
-            initAssetManager();
-        }
-
-        initDisplay();
-        initCamera();
-
-        if (inputEnabled){
-            initInput();
-        }
-        initAudio();
-
-        // update timer so that the next delta is not too large
-//        timer.update();
-        timer.reset();
-
-        // user code here..
-    }
-
-    /**
-     * Internal use only.
-     */
-    public void handleError(String errMsg, Throwable t){
-        // Print error to log.
-        logger.log(Level.SEVERE, errMsg, t);
-        // Display error message on screen
-        if (t != null) {
-            JmeSystem.showErrorDialog(errMsg + "\n" + t.getClass().getSimpleName() +
-                    (t.getMessage() != null ? ": " +  t.getMessage() : ""));
-        } else {
-            JmeSystem.showErrorDialog(errMsg);
-        }
-
-        stop(); // stop the application
-    }
-
-    /**
-     * Internal use only.
-     */
-    public void gainFocus(){
-        if (pauseOnFocus) {
-            paused = false;
-            context.setAutoFlushFrames(true);
-            if (inputManager != null) {
-                inputManager.reset();
-            }
-        }
-    }
-
-    /**
-     * Internal use only.
-     */
-    public void loseFocus(){
-        if (pauseOnFocus){
-            paused = true;
-            context.setAutoFlushFrames(false);
-        }
-    }
-
-    /**
-     * Internal use only.
-     */
-    public void requestClose(boolean esc){
-        context.destroy(false);
-    }
-
-    /**
-     * Enqueues a task/callable object to execute in the jME3
-     * rendering thread.
-     * <p>
-     * Callables are executed right at the beginning of the main loop.
-     * They are executed even if the application is currently paused
-     * or out of focus.
-     */
-    public <V> Future<V> enqueue(Callable<V> callable) {
-        AppTask<V> task = new AppTask<V>(callable);
-        taskQueue.add(task);
-        return task;
-    }
-
-    /**
-     * Runs tasks enqueued via {@link #enqueue(Callable)}
-     */
-    protected void runQueuedTasks() {
-	  AppTask<?> task;
-        while( (task = taskQueue.poll()) != null ) {
-            if (!task.isCancelled()) {
-                task.invoke();
-            }
-        }
-    }
-
-    /**
-     * Do not call manually.
-     * Callback from ContextListener.
-     */
-    public void update(){
-        // Make sure the audio renderer is available to callables
-        AudioContext.setAudioRenderer(audioRenderer);
-
-        runQueuedTasks();
-
-        if (speed == 0 || paused)
-            return;
-
-        timer.update();
-
-        if (inputEnabled){
-            inputManager.update(timer.getTimePerFrame());
-        }
-
-        if (audioRenderer != null){
-            audioRenderer.update(timer.getTimePerFrame());
-        }
-
-        // user code here..
-    }
-
-    protected void destroyInput(){
-        if (mouseInput != null)
-            mouseInput.destroy();
-
-        if (keyInput != null)
-            keyInput.destroy();
-
-        if (joyInput != null)
-            joyInput.destroy();
-
-        if (touchInput != null)
-            touchInput.destroy();
-
-        inputManager = null;
-    }
-
-    /**
-     * Do not call manually.
-     * Callback from ContextListener.
-     */
-    public void destroy(){
-        stateManager.cleanup();
-
-        destroyInput();
-        if (audioRenderer != null)
-            audioRenderer.cleanup();
-
-        timer.reset();
-    }
-
-    /**
-     * @return The GUI viewport. Which is used for the on screen
-     * statistics and FPS.
-     */
-    public ViewPort getGuiViewPort() {
-        return guiViewPort;
-    }
-
-    public ViewPort getViewPort() {
-        return viewPort;
-    }
-
-}
+/*
+ * 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.AppStateManager;
+import com.jme3.asset.AssetManager;
+import com.jme3.audio.AudioContext;
+import com.jme3.audio.AudioRenderer;
+import com.jme3.audio.Listener;
+import com.jme3.input.*;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.Camera;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.Renderer;
+import com.jme3.renderer.ViewPort;
+import com.jme3.system.*;
+import com.jme3.system.JmeContext.Type;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Future;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * The <code>Application</code> class represents an instance of a
+ * real-time 3D rendering jME application.
+ *
+ * An <code>Application</code> provides all the tools that are commonly used in jME3
+ * applications.
+ *
+ * jME3 applications *SHOULD NOT EXTEND* this class but extend {@link com.jme3.app.SimpleApplication} instead.
+ *
+ */
+public class Application implements SystemListener {
+
+    private static final Logger logger = Logger.getLogger(Application.class.getName());
+
+    protected AssetManager assetManager;
+
+    protected AudioRenderer audioRenderer;
+    protected Renderer renderer;
+    protected RenderManager renderManager;
+    protected ViewPort viewPort;
+    protected ViewPort guiViewPort;
+
+    protected JmeContext context;
+    protected AppSettings settings;
+    protected Timer timer = new NanoTimer();
+    protected Camera cam;
+    protected Listener listener;
+
+    protected boolean inputEnabled = true;
+    protected boolean pauseOnFocus = true;
+    protected float speed = 1f;
+    protected boolean paused = false;
+    protected MouseInput mouseInput;
+    protected KeyInput keyInput;
+    protected JoyInput joyInput;
+    protected TouchInput touchInput;
+    protected InputManager inputManager;
+    protected AppStateManager stateManager;
+
+    private final ConcurrentLinkedQueue<AppTask<?>> taskQueue = new ConcurrentLinkedQueue<AppTask<?>>();
+
+    /**
+     * Create a new instance of <code>Application</code>.
+     */
+    public Application(){
+        initStateManager();
+    }
+
+    /**
+     * Returns true if pause on lost focus is enabled, false otherwise.
+     *
+     * @return true if pause on lost focus is enabled
+     *
+     * @see #setPauseOnLostFocus(boolean)
+     */
+    public boolean isPauseOnLostFocus() {
+        return pauseOnFocus;
+    }
+
+    /**
+     * Enable or disable pause on lost focus.
+     * <p>
+     * By default, pause on lost focus is enabled.
+     * If enabled, the application will stop updating
+     * when it loses focus or becomes inactive (e.g. alt-tab).
+     * For online or real-time applications, this might not be preferable,
+     * so this feature should be set to disabled. For other applications,
+     * it is best to keep it on so that CPU usage is not used when
+     * not necessary.
+     *
+     * @param pauseOnLostFocus True to enable pause on lost focus, false
+     * otherwise.
+     */
+    public void setPauseOnLostFocus(boolean pauseOnLostFocus) {
+        this.pauseOnFocus = pauseOnLostFocus;
+    }
+
+    @Deprecated
+    public void setAssetManager(AssetManager assetManager){
+        if (this.assetManager != null)
+            throw new IllegalStateException("Can only set asset manager"
+                                          + " before initialization.");
+
+        this.assetManager = assetManager;
+    }
+
+    private void initAssetManager(){
+        if (settings != null){
+            String assetCfg = settings.getString("AssetConfigURL");
+            if (assetCfg != null){
+                URL url = null;
+                try {
+                    url = new URL(assetCfg);
+                } catch (MalformedURLException ex) {
+                }
+                if (url == null) {
+                    url = Application.class.getClassLoader().getResource(assetCfg);
+                    if (url == null) {
+                        logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", assetCfg);
+                        return;
+                    }
+                }
+                assetManager = JmeSystem.newAssetManager(url);
+            }
+        }
+        if (assetManager == null){
+            assetManager = JmeSystem.newAssetManager(
+                    Thread.currentThread().getContextClassLoader()
+                    .getResource("com/jme3/asset/Desktop.cfg"));
+        }
+    }
+
+    /**
+     * Set the display settings to define the display created.
+     * <p>
+     * Examples of display parameters include display pixel width and height,
+     * color bit depth, z-buffer bits, anti-aliasing samples, and update frequency.
+     * If this method is called while the application is already running, then
+     * {@link #restart() } must be called to apply the settings to the display.
+     *
+     * @param settings The settings to set.
+     */
+    public void setSettings(AppSettings settings){
+        this.settings = settings;
+        if (context != null && settings.useInput() != inputEnabled){
+            // may need to create or destroy input based
+            // on settings change
+            inputEnabled = !inputEnabled;
+            if (inputEnabled){
+                initInput();
+            }else{
+                destroyInput();
+            }
+        }else{
+            inputEnabled = settings.useInput();
+        }
+    }
+
+    /**
+     * Sets the Timer implementation that will be used for calculating
+     * frame times.  By default, Application will use the Timer as returned
+     * by the current JmeContext implementation.
+     */
+    public void setTimer(Timer timer){
+        this.timer = timer;
+
+        if (timer != null) {
+            timer.reset();
+        }
+
+        if (renderManager != null) {
+            renderManager.setTimer(timer);
+        }
+    }
+
+    public Timer getTimer(){
+        return timer;
+    }
+
+    private void initDisplay(){
+        // aquire important objects
+        // from the context
+        settings = context.getSettings();
+
+        // Only reset the timer if a user has not already provided one
+        if (timer == null) {
+            timer = context.getTimer();
+        }
+
+        renderer = context.getRenderer();
+    }
+
+    private void initAudio(){
+        if (settings.getAudioRenderer() != null && context.getType() != Type.Headless){
+            audioRenderer = JmeSystem.newAudioRenderer(settings);
+            audioRenderer.initialize();
+            AudioContext.setAudioRenderer(audioRenderer);
+
+            listener = new Listener();
+            audioRenderer.setListener(listener);
+        }
+    }
+
+    /**
+     * Creates the camera to use for rendering. Default values are perspective
+     * projection with 45° field of view, with near and far values 1 and 1000
+     * units respectively.
+     */
+    private void initCamera(){
+        cam = new Camera(settings.getWidth(), settings.getHeight());
+
+        cam.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f);
+        cam.setLocation(new Vector3f(0f, 0f, 10f));
+        cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);
+
+        renderManager = new RenderManager(renderer);
+        //Remy - 09/14/2010 setted the timer in the renderManager
+        renderManager.setTimer(timer);
+        viewPort = renderManager.createMainView("Default", cam);
+        viewPort.setClearFlags(true, true, true);
+
+        // Create a new cam for the gui
+        Camera guiCam = new Camera(settings.getWidth(), settings.getHeight());
+        guiViewPort = renderManager.createPostView("Gui Default", guiCam);
+        guiViewPort.setClearFlags(false, false, false);
+    }
+
+    /**
+     * Initializes mouse and keyboard input. Also
+     * initializes joystick input if joysticks are enabled in the
+     * AppSettings.
+     */
+    private void initInput(){
+        mouseInput = context.getMouseInput();
+        if (mouseInput != null)
+            mouseInput.initialize();
+
+        keyInput = context.getKeyInput();
+        if (keyInput != null)
+            keyInput.initialize();
+
+        touchInput = context.getTouchInput();
+        if (touchInput != null)
+            touchInput.initialize();
+
+        if (!settings.getBoolean("DisableJoysticks")){
+            joyInput = context.getJoyInput();
+            if (joyInput != null)
+                joyInput.initialize();
+        }
+
+        inputManager = new InputManager(mouseInput, keyInput, joyInput, touchInput);
+    }
+
+    private void initStateManager(){
+        stateManager = new AppStateManager(this);
+
+        // Always register a ResetStatsState to make sure
+        // that the stats are cleared every frame
+        stateManager.attach(new ResetStatsState());
+    }
+
+    /**
+     * @return The {@link AssetManager asset manager} for this application.
+     */
+    public AssetManager getAssetManager(){
+        return assetManager;
+    }
+
+    /**
+     * @return the {@link InputManager input manager}.
+     */
+    public InputManager getInputManager(){
+        return inputManager;
+    }
+
+    /**
+     * @return the {@link AppStateManager app state manager}
+     */
+    public AppStateManager getStateManager() {
+        return stateManager;
+    }
+
+    /**
+     * @return the {@link RenderManager render manager}
+     */
+    public RenderManager getRenderManager() {
+        return renderManager;
+    }
+
+    /**
+     * @return The {@link Renderer renderer} for the application
+     */
+    public Renderer getRenderer(){
+        return renderer;
+    }
+
+    /**
+     * @return The {@link AudioRenderer audio renderer} for the application
+     */
+    public AudioRenderer getAudioRenderer() {
+        return audioRenderer;
+    }
+
+    /**
+     * @return The {@link Listener listener} object for audio
+     */
+    public Listener getListener() {
+        return listener;
+    }
+
+    /**
+     * @return The {@link JmeContext display context} for the application
+     */
+    public JmeContext getContext(){
+        return context;
+    }
+
+    /**
+     * @return The {@link Camera camera} for the application
+     */
+    public Camera getCamera(){
+        return cam;
+    }
+
+    /**
+     * Starts the application in {@link Type#Display display} mode.
+     *
+     * @see #start(com.jme3.system.JmeContext.Type)
+     */
+    public void start(){
+        start(JmeContext.Type.Display);
+    }
+
+    /**
+     * Starts the application.
+     * Creating a rendering context and executing
+     * the main loop in a separate thread.
+     */
+    public void start(JmeContext.Type contextType){
+        if (context != null && context.isCreated()){
+            logger.warning("start() called when application already created!");
+            return;
+        }
+
+        if (settings == null){
+            settings = new AppSettings(true);
+        }
+
+        logger.log(Level.FINE, "Starting application: {0}", getClass().getName());
+        context = JmeSystem.newContext(settings, contextType);
+        context.setSystemListener(this);
+        context.create(false);
+    }
+
+    /**
+     * Initializes the application's canvas for use.
+     * <p>
+     * After calling this method, cast the {@link #getContext() context} to
+     * {@link JmeCanvasContext},
+     * then acquire the canvas with {@link JmeCanvasContext#getCanvas() }
+     * and attach it to an AWT/Swing Frame.
+     * The rendering thread will start when the canvas becomes visible on
+     * screen, however if you wish to start the context immediately you
+     * may call {@link #startCanvas() } to force the rendering thread
+     * to start.
+     *
+     * @see JmeCanvasContext
+     * @see Type#Canvas
+     */
+    public void createCanvas(){
+        if (context != null && context.isCreated()){
+            logger.warning("createCanvas() called when application already created!");
+            return;
+        }
+
+        if (settings == null){
+            settings = new AppSettings(true);
+        }
+
+        logger.log(Level.FINE, "Starting application: {0}", getClass().getName());
+        context = JmeSystem.newContext(settings, JmeContext.Type.Canvas);
+        context.setSystemListener(this);
+    }
+
+    /**
+     * Starts the rendering thread after createCanvas() has been called.
+     * <p>
+     * Same as calling startCanvas(false)
+     *
+     * @see #startCanvas(boolean)
+     */
+    public void startCanvas(){
+        startCanvas(false);
+    }
+
+    /**
+     * Starts the rendering thread after createCanvas() has been called.
+     * <p>
+     * Calling this method is optional, the canvas will start automatically
+     * when it becomes visible.
+     *
+     * @param waitFor If true, the current thread will block until the
+     * rendering thread is running
+     */
+    public void startCanvas(boolean waitFor){
+        context.create(waitFor);
+    }
+
+    /**
+     * Internal use only.
+     */
+    public void reshape(int w, int h){
+        renderManager.notifyReshape(w, h);
+    }
+
+    /**
+     * Restarts the context, applying any changed settings.
+     * <p>
+     * Changes to the {@link AppSettings} of this Application are not
+     * applied immediately; calling this method forces the context
+     * to restart, applying the new settings.
+     */
+    public void restart(){
+        context.setSettings(settings);
+        context.restart();
+    }
+
+    /**
+     * Requests the context to close, shutting down the main loop
+     * and making necessary cleanup operations.
+     *
+     * Same as calling stop(false)
+     *
+     * @see #stop(boolean)
+     */
+    public void stop(){
+        stop(false);
+    }
+
+    /**
+     * Requests the context to close, shutting down the main loop
+     * and making necessary cleanup operations.
+     * After the application has stopped, it cannot be used anymore.
+     */
+    public void stop(boolean waitFor){
+        logger.log(Level.FINE, "Closing application: {0}", getClass().getName());
+        context.destroy(waitFor);
+    }
+
+    /**
+     * Do not call manually.
+     * Callback from ContextListener.
+     * <p>
+     * Initializes the <code>Application</code>, by creating a display and
+     * default camera. If display settings are not specified, a default
+     * 640x480 display is created. Default values are used for the camera;
+     * perspective projection with 45° field of view, with near
+     * and far values 1 and 1000 units respectively.
+     */
+    public void initialize(){
+        if (assetManager == null){
+            initAssetManager();
+        }
+
+        initDisplay();
+        initCamera();
+
+        if (inputEnabled){
+            initInput();
+        }
+        initAudio();
+
+        // update timer so that the next delta is not too large
+//        timer.update();
+        timer.reset();
+
+        // user code here..
+    }
+
+    /**
+     * Internal use only.
+     */
+    public void handleError(String errMsg, Throwable t){
+        // Print error to log.
+        logger.log(Level.SEVERE, errMsg, t);
+        // Display error message on screen
+        if (t != null) {
+            JmeSystem.showErrorDialog(errMsg + "\n" + t.getClass().getSimpleName() +
+                    (t.getMessage() != null ? ": " +  t.getMessage() : ""));
+        } else {
+            JmeSystem.showErrorDialog(errMsg);
+        }
+
+        stop(); // stop the application
+    }
+
+    /**
+     * Internal use only.
+     */
+    public void gainFocus(){
+        if (pauseOnFocus) {
+            paused = false;
+            context.setAutoFlushFrames(true);
+            if (inputManager != null) {
+                inputManager.reset();
+            }
+        }
+    }
+
+    /**
+     * Internal use only.
+     */
+    public void loseFocus(){
+        if (pauseOnFocus){
+            paused = true;
+            context.setAutoFlushFrames(false);
+        }
+    }
+
+    /**
+     * Internal use only.
+     */
+    public void requestClose(boolean esc){
+        context.destroy(false);
+    }
+
+    /**
+     * Enqueues a task/callable object to execute in the jME3
+     * rendering thread.
+     * <p>
+     * Callables are executed right at the beginning of the main loop.
+     * They are executed even if the application is currently paused
+     * or out of focus.
+     */
+    public <V> Future<V> enqueue(Callable<V> callable) {
+        AppTask<V> task = new AppTask<V>(callable);
+        taskQueue.add(task);
+        return task;
+    }
+
+    /**
+     * Runs tasks enqueued via {@link #enqueue(Callable)}
+     */
+    protected void runQueuedTasks() {
+	  AppTask<?> task;
+        while( (task = taskQueue.poll()) != null ) {
+            if (!task.isCancelled()) {
+                task.invoke();
+            }
+        }
+    }
+
+    /**
+     * Do not call manually.
+     * Callback from ContextListener.
+     */
+    public void update(){
+        // Make sure the audio renderer is available to callables
+        AudioContext.setAudioRenderer(audioRenderer);
+
+        runQueuedTasks();
+
+        if (speed == 0 || paused)
+            return;
+
+        timer.update();
+
+        if (inputEnabled){
+            inputManager.update(timer.getTimePerFrame());
+        }
+
+        if (audioRenderer != null){
+            audioRenderer.update(timer.getTimePerFrame());
+        }
+
+        // user code here..
+    }
+
+    protected void destroyInput(){
+        if (mouseInput != null)
+            mouseInput.destroy();
+
+        if (keyInput != null)
+            keyInput.destroy();
+
+        if (joyInput != null)
+            joyInput.destroy();
+
+        if (touchInput != null)
+            touchInput.destroy();
+
+        inputManager = null;
+    }
+
+    /**
+     * Do not call manually.
+     * Callback from ContextListener.
+     */
+    public void destroy(){
+        stateManager.cleanup();
+
+        destroyInput();
+        if (audioRenderer != null)
+            audioRenderer.cleanup();
+
+        timer.reset();
+    }
+
+    /**
+     * @return The GUI viewport. Which is used for the on screen
+     * statistics and FPS.
+     */
+    public ViewPort getGuiViewPort() {
+        return guiViewPort;
+    }
+
+    public ViewPort getViewPort() {
+        return viewPort;
+    }
+
+}