159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved.
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met:
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer.
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer in the
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   documentation and/or other materials provided with the distribution.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   may be used to endorse or promote products derived from this software
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   without specific prior written permission.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.app;
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.app.state.AppStateManager;
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.asset.AssetManager;
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.audio.AudioContext;
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.audio.AudioRenderer;
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.audio.Listener;
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.*;
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f;
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.renderer.Camera;
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.renderer.RenderManager;
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.renderer.Renderer;
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.renderer.ViewPort;
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.system.JmeContext.Type;
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.system.*;
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.net.MalformedURLException;
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.net.URL;
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.concurrent.Callable;
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.concurrent.ConcurrentLinkedQueue;
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.concurrent.Future;
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Level;
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Logger;
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The <code>Application</code> class represents an instance of a
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * real-time 3D rendering jME application.
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * An <code>Application</code> provides all the tools that are commonly used in jME3
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * applications.
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * jME3 applications should extend this class and call start() to begin the
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * application.
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class Application implements SystemListener {
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final Logger logger = Logger.getLogger(Application.class.getName());
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected AssetManager assetManager;
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected AudioRenderer audioRenderer;
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Renderer renderer;
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected RenderManager renderManager;
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected ViewPort viewPort;
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected ViewPort guiViewPort;
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected JmeContext context;
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected AppSettings settings;
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Timer timer = new NanoTimer();
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Camera cam;
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Listener listener;
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected boolean inputEnabled = true;
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected boolean pauseOnFocus = true;
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected float speed = 1f;
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected boolean paused = false;
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected MouseInput mouseInput;
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected KeyInput keyInput;
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected JoyInput joyInput;
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected TouchInput touchInput;
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected InputManager inputManager;
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected AppStateManager stateManager;
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private final ConcurrentLinkedQueue<AppTask<?>> taskQueue = new ConcurrentLinkedQueue<AppTask<?>>();
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new instance of <code>Application</code>.
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Application(){
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        initStateManager();
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns true if pause on lost focus is enabled, false otherwise.
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return true if pause on lost focus is enabled
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see #setPauseOnLostFocus(boolean)
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public boolean isPauseOnLostFocus() {
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return pauseOnFocus;
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Enable or disable pause on lost focus.
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * By default, pause on lost focus is enabled.
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * If enabled, the application will stop updating
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * when it loses focus or becomes inactive (e.g. alt-tab).
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * For online or real-time applications, this might not be preferable,
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * so this feature should be set to disabled. For other applications,
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * it is best to keep it on so that CPU usage is not used when
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * not necessary.
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param pauseOnLostFocus True to enable pause on lost focus, false
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * otherwise.
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setPauseOnLostFocus(boolean pauseOnLostFocus) {
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.pauseOnFocus = pauseOnLostFocus;
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Deprecated
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setAssetManager(AssetManager assetManager){
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (this.assetManager != null)
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalStateException("Can only set asset manager"
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                          + " before initialization.");
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.assetManager = assetManager;
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void initAssetManager(){
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (settings != null){
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            String assetCfg = settings.getString("AssetConfigURL");
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (assetCfg != null){
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                URL url = null;
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                try {
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    url = new URL(assetCfg);
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } catch (MalformedURLException ex) {
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (url == null) {
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    url = Application.class.getClassLoader().getResource(assetCfg);
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (url == null) {
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", assetCfg);
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return;
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                assetManager = JmeSystem.newAssetManager(url);
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (assetManager == null){
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            assetManager = JmeSystem.newAssetManager(
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    Thread.currentThread().getContextClassLoader()
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    .getResource("com/jme3/asset/Desktop.cfg"));
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the display settings to define the display created.
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Examples of display parameters include display pixel width and height,
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * color bit depth, z-buffer bits, anti-aliasing samples, and update frequency.
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * If this method is called while the application is already running, then
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * {@link #restart() } must be called to apply the settings to the display.
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param settings The settings to set.
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setSettings(AppSettings settings){
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.settings = settings;
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (context != null && settings.useInput() != inputEnabled){
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // may need to create or destroy input based
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // on settings change
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            inputEnabled = !inputEnabled;
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (inputEnabled){
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                initInput();
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }else{
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                destroyInput();
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else{
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            inputEnabled = settings.useInput();
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Sets the Timer implementation that will be used for calculating
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * frame times.  By default, Application will use the Timer as returned
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * by the current JmeContext implementation.
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setTimer(Timer timer){
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.timer = timer;
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (timer != null) {
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            timer.reset();
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (renderManager != null) {
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            renderManager.setTimer(timer);
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Timer getTimer(){
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return timer;
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void initDisplay(){
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // aquire important objects
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // from the context
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        settings = context.getSettings();
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Only reset the timer if a user has not already provided one
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (timer == null) {
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            timer = context.getTimer();
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        renderer = context.getRenderer();
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void initAudio(){
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (settings.getAudioRenderer() != null && context.getType() != Type.Headless){
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            audioRenderer = JmeSystem.newAudioRenderer(settings);
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            audioRenderer.initialize();
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            AudioContext.setAudioRenderer(audioRenderer);
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            listener = new Listener();
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            audioRenderer.setListener(listener);
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates the camera to use for rendering. Default values are perspective
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * projection with 45° field of view, with near and far values 1 and 1000
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * units respectively.
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void initCamera(){
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cam = new Camera(settings.getWidth(), settings.getHeight());
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cam.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f);
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cam.setLocation(new Vector3f(0f, 0f, 10f));
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        renderManager = new RenderManager(renderer);
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        //Remy - 09/14/2010 setted the timer in the renderManager
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        renderManager.setTimer(timer);
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        viewPort = renderManager.createMainView("Default", cam);
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        viewPort.setClearFlags(true, true, true);
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Create a new cam for the gui
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Camera guiCam = new Camera(settings.getWidth(), settings.getHeight());
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        guiViewPort = renderManager.createPostView("Gui Default", guiCam);
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        guiViewPort.setClearFlags(false, false, false);
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Initializes mouse and keyboard input. Also
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * initializes joystick input if joysticks are enabled in the
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * AppSettings.
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void initInput(){
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        mouseInput = context.getMouseInput();
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (mouseInput != null)
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            mouseInput.initialize();
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        keyInput = context.getKeyInput();
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (keyInput != null)
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            keyInput.initialize();
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        touchInput = context.getTouchInput();
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (touchInput != null)
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            touchInput.initialize();
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (!settings.getBoolean("DisableJoysticks")){
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            joyInput = context.getJoyInput();
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (joyInput != null)
28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                joyInput.initialize();
28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        inputManager = new InputManager(mouseInput, keyInput, joyInput, touchInput);
28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void initStateManager(){
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        stateManager = new AppStateManager(this);
293a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
294a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        // Always register a ResetStatsState to make sure
295a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        // that the stats are cleared every frame
296a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        stateManager.attach(new ResetStatsState());
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The {@link AssetManager asset manager} for this application.
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AssetManager getAssetManager(){
30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return assetManager;
30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the {@link InputManager input manager}.
30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public InputManager getInputManager(){
31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return inputManager;
31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the {@link AppStateManager app state manager}
31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AppStateManager getStateManager() {
31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return stateManager;
31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the {@link RenderManager render manager}
32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public RenderManager getRenderManager() {
32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return renderManager;
32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The {@link Renderer renderer} for the application
32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Renderer getRenderer(){
33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return renderer;
33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The {@link AudioRenderer audio renderer} for the application
33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioRenderer getAudioRenderer() {
33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return audioRenderer;
33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The {@link Listener listener} object for audio
34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Listener getListener() {
34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return listener;
34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The {@link JmeContext display context} for the application
35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public JmeContext getContext(){
35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return context;
35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The {@link Camera camera} for the application
35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Camera getCamera(){
35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return cam;
36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Starts the application in {@link Type#Display display} mode.
36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see #start(com.jme3.system.JmeContext.Type)
36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void start(){
36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        start(JmeContext.Type.Display);
36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Starts the application.
37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creating a rendering context and executing
37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the main loop in a separate thread.
37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void start(JmeContext.Type contextType){
37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (context != null && context.isCreated()){
37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.warning("start() called when application already created!");
37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (settings == null){
38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            settings = new AppSettings(true);
38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.FINE, "Starting application: {0}", getClass().getName());
38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context = JmeSystem.newContext(settings, contextType);
38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.setSystemListener(this);
38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.create(false);
39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Initializes the application's canvas for use.
39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * After calling this method, cast the {@link #getContext() context} to
39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * {@link JmeCanvasContext},
39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * then acquire the canvas with {@link JmeCanvasContext#getCanvas() }
39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * and attach it to an AWT/Swing Frame.
39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The rendering thread will start when the canvas becomes visible on
40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * screen, however if you wish to start the context immediately you
40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * may call {@link #startCanvas() } to force the rendering thread
40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * to start.
40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see JmeCanvasContext
40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see Type#Canvas
40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void createCanvas(){
40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (context != null && context.isCreated()){
40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.warning("createCanvas() called when application already created!");
41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (settings == null){
41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            settings = new AppSettings(true);
41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.FINE, "Starting application: {0}", getClass().getName());
41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context = JmeSystem.newContext(settings, JmeContext.Type.Canvas);
41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.setSystemListener(this);
42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Starts the rendering thread after createCanvas() has been called.
42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Same as calling startCanvas(false)
42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see #startCanvas(boolean)
42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void startCanvas(){
43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        startCanvas(false);
43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Starts the rendering thread after createCanvas() has been called.
43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Calling this method is optional, the canvas will start automatically
43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * when it becomes visible.
43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param waitFor If true, the current thread will block until the
44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * rendering thread is running
44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void startCanvas(boolean waitFor){
44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.create(waitFor);
44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Internal use only.
44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void reshape(int w, int h){
45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        renderManager.notifyReshape(w, h);
45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Restarts the context, applying any changed settings.
45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Changes to the {@link AppSettings} of this Application are not
45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * applied immediately; calling this method forces the context
45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * to restart, applying the new settings.
45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void restart(){
46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.setSettings(settings);
46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.restart();
46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
46659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Requests the context to close, shutting down the main loop
46759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * and making necessary cleanup operations.
46859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
46959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Same as calling stop(false)
47059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
47159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see #stop(boolean)
47259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
47359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void stop(){
47459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        stop(false);
47559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
47659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
47759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
47859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Requests the context to close, shutting down the main loop
47959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * and making necessary cleanup operations.
48059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * After the application has stopped, it cannot be used anymore.
48159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
48259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void stop(boolean waitFor){
48359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.FINE, "Closing application: {0}", getClass().getName());
48459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.destroy(waitFor);
48559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
48659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
48759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
48859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Do not call manually.
48959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Callback from ContextListener.
49059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
49159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Initializes the <code>Application</code>, by creating a display and
49259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * default camera. If display settings are not specified, a default
49359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * 640x480 display is created. Default values are used for the camera;
49459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * perspective projection with 45° field of view, with near
49559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * and far values 1 and 1000 units respectively.
49659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
49759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void initialize(){
49859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (assetManager == null){
49959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            initAssetManager();
50059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
50159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
50259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        initDisplay();
50359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        initCamera();
50459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
50559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (inputEnabled){
50659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            initInput();
50759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
50859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        initAudio();
50959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
51059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // update timer so that the next delta is not too large
51159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        timer.update();
51259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        timer.reset();
51359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
51459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // user code here..
51559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
51659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
51759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
51859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Internal use only.
51959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
52059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void handleError(String errMsg, Throwable t){
52159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.SEVERE, errMsg, t);
52259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // user should add additional code to handle the error.
52359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        stop(); // stop the application
52459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
52559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
52659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
52759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Internal use only.
52859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
52959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void gainFocus(){
53059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (pauseOnFocus) {
53159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            paused = false;
53259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.setAutoFlushFrames(true);
53359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (inputManager != null) {
53459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                inputManager.reset();
53559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
53659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
53759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
53859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
53959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
54059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Internal use only.
54159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
54259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void loseFocus(){
54359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (pauseOnFocus){
54459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            paused = true;
54559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.setAutoFlushFrames(false);
54659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
54759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
54859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
54959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
55059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Internal use only.
55159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
55259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void requestClose(boolean esc){
55359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.destroy(false);
55459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
55559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
55659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
55759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Enqueues a task/callable object to execute in the jME3
55859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * rendering thread.
55959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
56059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Callables are executed right at the beginning of the main loop.
56159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * They are executed even if the application is currently paused
56259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * or out of focus.
56359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
56459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public <V> Future<V> enqueue(Callable<V> callable) {
56559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        AppTask<V> task = new AppTask<V>(callable);
56659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        taskQueue.add(task);
56759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return task;
56859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
56959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
57059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
57159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Do not call manually.
57259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Callback from ContextListener.
57359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
57459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void update(){
57559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Make sure the audio renderer is available to callables
57659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        AudioContext.setAudioRenderer(audioRenderer);
57759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
57859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        AppTask<?> task = taskQueue.poll();
57959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        toploop: do {
58059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (task == null) break;
58159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            while (task.isCancelled()) {
58259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                task = taskQueue.poll();
58359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (task == null) break toploop;
58459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
58559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            task.invoke();
58659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } while (((task = taskQueue.poll()) != null));
587a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
588a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        /* I think the above is really just doing this:
589a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        AppTask<?> task;
590a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        while( (task = taskQueue.poll()) != null ) {
591a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            if (!task.isCancelled()) {
592a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                task.invoke();
593a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            }
594a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        }
595a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        //...but it's hard to say for sure.  It's so twisted
596a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        //up that I don't trust my eyes.  -pspeed
597a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        */
59859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
59959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (speed == 0 || paused)
60059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
60159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
60259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        timer.update();
60359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
60459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (inputEnabled){
60559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            inputManager.update(timer.getTimePerFrame());
60659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
60759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
60859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (audioRenderer != null){
60959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            audioRenderer.update(timer.getTimePerFrame());
61059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
61159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
61259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // user code here..
61359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
61459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
61559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected void destroyInput(){
61659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (mouseInput != null)
61759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            mouseInput.destroy();
61859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
61959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (keyInput != null)
62059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            keyInput.destroy();
62159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
62259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (joyInput != null)
62359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            joyInput.destroy();
62459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
62559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (touchInput != null)
62659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            touchInput.destroy();
62759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
62859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        inputManager = null;
62959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
63059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
63159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
63259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Do not call manually.
63359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Callback from ContextListener.
63459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
63559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void destroy(){
63659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        stateManager.cleanup();
63759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
63859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        destroyInput();
63959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (audioRenderer != null)
64059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            audioRenderer.cleanup();
64159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
64259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        timer.reset();
64359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
64459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
64559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
64659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The GUI viewport. Which is used for the on screen
64759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * statistics and FPS.
64859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
64959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public ViewPort getGuiViewPort() {
65059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return guiViewPort;
65159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
65259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
65359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public ViewPort getViewPort() {
65459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return viewPort;
65559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
65659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
65759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
658