diff --git a/jme3-android/src/main/java/com/jme3/app/AndroidHarness.java b/jme3-android/src/main/java/com/jme3/app/AndroidHarness.java index b103e92df..142a23d98 100644 --- a/jme3-android/src/main/java/com/jme3/app/AndroidHarness.java +++ b/jme3-android/src/main/java/com/jme3/app/AndroidHarness.java @@ -50,7 +50,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt /** * The jme3 application object */ - protected Application app = null; + protected LegacyApplication app = null; /** * Sets the desired RGB size for the surfaceview. 16 = RGB565, 24 = RGB888. @@ -178,7 +178,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt private boolean inConfigChange = false; private class DataObject { - protected Application app = null; + protected LegacyApplication app = null; } @Override @@ -241,7 +241,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt try { if (app == null) { @SuppressWarnings("unchecked") - Class clazz = (Class) Class.forName(appClass); + Class clazz = (Class) Class.forName(appClass); app = clazz.newInstance(); } diff --git a/jme3-android/src/main/java/com/jme3/app/AndroidHarnessFragment.java b/jme3-android/src/main/java/com/jme3/app/AndroidHarnessFragment.java index 5673c8609..fed2d8863 100644 --- a/jme3-android/src/main/java/com/jme3/app/AndroidHarnessFragment.java +++ b/jme3-android/src/main/java/com/jme3/app/AndroidHarnessFragment.java @@ -207,7 +207,7 @@ public class AndroidHarnessFragment extends Fragment implements protected ImageView splashImageView = null; final private String ESCAPE_EVENT = "TouchEscape"; private boolean firstDrawFrame = true; - private Application app = null; + private LegacyApplication app = null; private int viewWidth = 0; private int viewHeight = 0; @@ -258,7 +258,7 @@ public class AndroidHarnessFragment extends Fragment implements try { if (app == null) { @SuppressWarnings("unchecked") - Class clazz = (Class) Class.forName(appClass); + Class clazz = (Class) Class.forName(appClass); app = clazz.newInstance(); } diff --git a/jme3-core/src/main/java/com/jme3/app/Application.java b/jme3-core/src/main/java/com/jme3/app/Application.java index 9688a5d1e..82e4959a7 100644 --- a/jme3-core/src/main/java/com/jme3/app/Application.java +++ b/jme3-core/src/main/java/com/jme3/app/Application.java @@ -33,112 +33,53 @@ 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.input.InputManager; import com.jme3.profile.AppProfiler; -import com.jme3.profile.AppStep; 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 Application class represents an instance of a - * real-time 3D rendering jME application. - * - * An Application 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. - * + * The Application interface represents the minimum exposed + * capabilities of a concrete jME3 application. */ -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 LostFocusBehavior lostFocusBehavior = LostFocusBehavior.ThrottleOnLostFocus; - 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; - - protected AppProfiler prof; - - private final ConcurrentLinkedQueue> taskQueue = new ConcurrentLinkedQueue>(); - - /** - * Create a new instance of Application. - */ - public Application(){ - initStateManager(); - } +public interface Application { /** * Determine the application's behavior when unfocused. - * + * * @return The lost focus behavior of the application. */ - public LostFocusBehavior getLostFocusBehavior() { - return lostFocusBehavior; - } - + public LostFocusBehavior getLostFocusBehavior(); + /** * Change the application's behavior when unfocused. - * - * By default, the application will - * {@link LostFocusBehavior#ThrottleOnLostFocus throttle the update loop} + * + * By default, the application will + * {@link LostFocusBehavior#ThrottleOnLostFocus throttle the update loop} * so as to not take 100% CPU usage when it is not in focus, e.g. * alt-tabbed, minimized, or obstructed by another window. - * + * * @param lostFocusBehavior The new lost focus behavior to use. - * + * * @see LostFocusBehavior */ - public void setLostFocusBehavior(LostFocusBehavior lostFocusBehavior) { - this.lostFocusBehavior = lostFocusBehavior; - } - + public void setLostFocusBehavior(LostFocusBehavior lostFocusBehavior); + /** * Returns true if pause on lost focus is enabled, false otherwise. * * @return true if pause on lost focus is enabled * - * @see #getLostFocusBehavior() + * @see #getLostFocusBehavior() */ - public boolean isPauseOnLostFocus() { - return getLostFocusBehavior() == LostFocusBehavior.PauseOnLostFocus; - } + public boolean isPauseOnLostFocus(); /** * Enable or disable pause on lost focus. @@ -153,52 +94,10 @@ public class Application implements SystemListener { * * @param pauseOnLostFocus True to enable pause on lost focus, false * otherwise. - * + * * @see #setLostFocusBehavior(com.jme3.app.LostFocusBehavior) */ - public void setPauseOnLostFocus(boolean pauseOnLostFocus) { - if (pauseOnLostFocus) { - setLostFocusBehavior(LostFocusBehavior.PauseOnLostFocus); - } else { - setLostFocusBehavior(LostFocusBehavior.Disabled); - } - } - - @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(){ - URL assetCfgUrl = null; - - if (settings != null){ - String assetCfg = settings.getString("AssetConfigURL"); - if (assetCfg != null){ - try { - assetCfgUrl = new URL(assetCfg); - } catch (MalformedURLException ex) { - } - if (assetCfgUrl == null) { - assetCfgUrl = Application.class.getClassLoader().getResource(assetCfg); - if (assetCfgUrl == null) { - logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", assetCfg); - return; - } - } - } - } - if (assetCfgUrl == null) { - assetCfgUrl = JmeSystem.getPlatformAssetConfigURL(); - } - if (assetManager == null){ - assetManager = JmeSystem.newAssetManager(assetCfgUrl); - } - } + public void setPauseOnLostFocus(boolean pauseOnLostFocus); /** * Set the display settings to define the display created. @@ -210,321 +109,83 @@ public class Application implements SystemListener { * * @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(); - } - } + public void setSettings(AppSettings settings); /** * 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); - - if (prof != null) { - renderManager.setAppProfiler(prof); - } - - 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(); - } + public void setTimer(Timer timer); - 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()); - } + public Timer getTimer(); /** * @return The {@link AssetManager asset manager} for this application. */ - public AssetManager getAssetManager(){ - return assetManager; - } + public AssetManager getAssetManager(); /** * @return the {@link InputManager input manager}. */ - public InputManager getInputManager(){ - return inputManager; - } + public InputManager getInputManager(); /** * @return the {@link AppStateManager app state manager} */ - public AppStateManager getStateManager() { - return stateManager; - } + public AppStateManager getStateManager(); /** * @return the {@link RenderManager render manager} */ - public RenderManager getRenderManager() { - return renderManager; - } + public RenderManager getRenderManager(); /** * @return The {@link Renderer renderer} for the application */ - public Renderer getRenderer(){ - return renderer; - } + public Renderer getRenderer(); /** * @return The {@link AudioRenderer audio renderer} for the application */ - public AudioRenderer getAudioRenderer() { - return audioRenderer; - } + public AudioRenderer getAudioRenderer(); /** * @return The {@link Listener listener} object for audio */ - public Listener getListener() { - return listener; - } + public Listener getListener(); /** * @return The {@link JmeContext display context} for the application */ - public JmeContext getContext(){ - return context; - } + public JmeContext getContext(); /** - * @return The {@link Camera camera} for the application + * @return The main {@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, false); - } - - /** - * Starts the application in {@link Type#Display display} mode. - * - * @see #start(com.jme3.system.JmeContext.Type) - */ - public void start(boolean waitFor){ - start(JmeContext.Type.Display, waitFor); - } + public Camera getCamera(); /** * Starts the application. - * Creating a rendering context and executing - * the main loop in a separate thread. */ - public void start(JmeContext.Type contextType) { - start(contextType, false); - } - + public void start(); + /** * Starts the application. - * Creating a rendering context and executing - * the main loop in a separate thread. */ - public void start(JmeContext.Type contextType, boolean waitFor){ - 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(waitFor); - } + public void start(boolean waitFor); /** * Sets an AppProfiler hook that will be called back for * specific steps within a single update frame. Value defaults * to null. */ - public void setAppProfiler(AppProfiler prof) { - this.prof = prof; - if (renderManager != null) { - renderManager.setAppProfiler(prof); - } - } - - /** - * Returns the current AppProfiler hook, or null if none is set. - */ - public AppProfiler getAppProfiler() { - return prof; - } + public void setAppProfiler(AppProfiler prof); /** - * Initializes the application's canvas for use. - *

- * 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. - *

- * Same as calling startCanvas(false) - * - * @see #startCanvas(boolean) - */ - public void startCanvas(){ - startCanvas(false); - } - - /** - * Starts the rendering thread after createCanvas() has been called. - *

- * 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. + * Returns the current AppProfiler hook, or null if none is set. */ - public void reshape(int w, int h){ - renderManager.notifyReshape(w, h); - } + public AppProfiler getAppProfiler(); /** * Restarts the context, applying any changed settings. @@ -533,10 +194,7 @@ public class Application implements SystemListener { * applied immediately; calling this method forces the context * to restart, applying the new settings. */ - public void restart(){ - context.setSettings(settings); - context.restart(); - } + public void restart(); /** * Requests the context to close, shutting down the main loop @@ -546,102 +204,14 @@ public class Application implements SystemListener { * * @see #stop(boolean) */ - public void stop(){ - stop(false); - } + public void stop(); /** * 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. - *

- * Initializes the Application, 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 not in headless mode - if (context.getType() != JmeContext.Type.Headless) { - 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 (lostFocusBehavior != LostFocusBehavior.Disabled) { - if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) { - paused = false; - } - context.setAutoFlushFrames(true); - if (inputManager != null) { - inputManager.reset(); - } - } - } - - /** - * Internal use only. - */ - public void loseFocus(){ - if (lostFocusBehavior != LostFocusBehavior.Disabled){ - if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) { - paused = true; - } - context.setAutoFlushFrames(false); - } - } - - /** - * Internal use only. - */ - public void requestClose(boolean esc){ - context.destroy(false); - } + public void stop(boolean waitFor); /** * Enqueues a task/callable object to execute in the jME3 @@ -650,15 +220,11 @@ public class Application implements SystemListener { * 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. - * + * * @param callable The callable to run in the main jME3 thread */ - public Future enqueue(Callable callable) { - AppTask task = new AppTask(callable); - taskQueue.add(task); - return task; - } - + public Future enqueue(Callable callable); + /** * Enqueues a runnable object to execute in the jME3 * rendering thread. @@ -666,109 +232,16 @@ public class Application implements SystemListener { * Runnables are executed right at the beginning of the main loop. * They are executed even if the application is currently paused * or out of focus. - * + * * @param runnable The runnable to run in the main jME3 thread - */ - public void enqueue(Runnable runnable){ - enqueue(new RunnableWrapper(runnable)); - } - - /** - * 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); - - if (prof!=null) prof.appStep(AppStep.QueuedTasks); - runQueuedTasks(); - - if (speed == 0 || paused) - return; - - timer.update(); - - if (inputEnabled){ - if (prof!=null) prof.appStep(AppStep.ProcessInput); - inputManager.update(timer.getTimePerFrame()); - } - - if (audioRenderer != null){ - if (prof!=null) prof.appStep(AppStep.ProcessAudio); - 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(); - } + public void enqueue(Runnable runnable); /** * @return The GUI viewport. Which is used for the on screen * statistics and FPS. */ - public ViewPort getGuiViewPort() { - return guiViewPort; - } - - public ViewPort getViewPort() { - return viewPort; - } - - private class RunnableWrapper implements Callable{ - private final Runnable runnable; - - public RunnableWrapper(Runnable runnable){ - this.runnable = runnable; - } + public ViewPort getGuiViewPort(); - @Override - public Object call(){ - runnable.run(); - return null; - } - - } - + public ViewPort getViewPort(); } diff --git a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java new file mode 100644 index 000000000..89a81be5b --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java @@ -0,0 +1,774 @@ +/* + * 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.profile.AppProfiler; +import com.jme3.profile.AppStep; +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 LegacyApplication class represents an instance of a + * real-time 3D rendering jME application. + * + * An LegacyApplication 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 LegacyApplication implements Application, SystemListener { + + private static final Logger logger = Logger.getLogger(LegacyApplication.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 LostFocusBehavior lostFocusBehavior = LostFocusBehavior.ThrottleOnLostFocus; + 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; + + protected AppProfiler prof; + + private final ConcurrentLinkedQueue> taskQueue = new ConcurrentLinkedQueue>(); + + /** + * Create a new instance of LegacyApplication. + */ + public LegacyApplication(){ + initStateManager(); + } + + /** + * Determine the application's behavior when unfocused. + * + * @return The lost focus behavior of the application. + */ + public LostFocusBehavior getLostFocusBehavior() { + return lostFocusBehavior; + } + + /** + * Change the application's behavior when unfocused. + * + * By default, the application will + * {@link LostFocusBehavior#ThrottleOnLostFocus throttle the update loop} + * so as to not take 100% CPU usage when it is not in focus, e.g. + * alt-tabbed, minimized, or obstructed by another window. + * + * @param lostFocusBehavior The new lost focus behavior to use. + * + * @see LostFocusBehavior + */ + public void setLostFocusBehavior(LostFocusBehavior lostFocusBehavior) { + this.lostFocusBehavior = lostFocusBehavior; + } + + /** + * Returns true if pause on lost focus is enabled, false otherwise. + * + * @return true if pause on lost focus is enabled + * + * @see #getLostFocusBehavior() + */ + public boolean isPauseOnLostFocus() { + return getLostFocusBehavior() == LostFocusBehavior.PauseOnLostFocus; + } + + /** + * Enable or disable pause on lost focus. + *

+ * 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. + * + * @see #setLostFocusBehavior(com.jme3.app.LostFocusBehavior) + */ + public void setPauseOnLostFocus(boolean pauseOnLostFocus) { + if (pauseOnLostFocus) { + setLostFocusBehavior(LostFocusBehavior.PauseOnLostFocus); + } else { + setLostFocusBehavior(LostFocusBehavior.Disabled); + } + } + + @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(){ + URL assetCfgUrl = null; + + if (settings != null){ + String assetCfg = settings.getString("AssetConfigURL"); + if (assetCfg != null){ + try { + assetCfgUrl = new URL(assetCfg); + } catch (MalformedURLException ex) { + } + if (assetCfgUrl == null) { + assetCfgUrl = LegacyApplication.class.getClassLoader().getResource(assetCfg); + if (assetCfgUrl == null) { + logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", assetCfg); + return; + } + } + } + } + if (assetCfgUrl == null) { + assetCfgUrl = JmeSystem.getPlatformAssetConfigURL(); + } + if (assetManager == null){ + assetManager = JmeSystem.newAssetManager(assetCfgUrl); + } + } + + /** + * Set the display settings to define the display created. + *

+ * 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); + + if (prof != null) { + renderManager.setAppProfiler(prof); + } + + 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, false); + } + + /** + * Starts the application in {@link Type#Display display} mode. + * + * @see #start(com.jme3.system.JmeContext.Type) + */ + public void start(boolean waitFor){ + start(JmeContext.Type.Display, waitFor); + } + + /** + * Starts the application. + * Creating a rendering context and executing + * the main loop in a separate thread. + */ + public void start(JmeContext.Type contextType) { + start(contextType, false); + } + + /** + * Starts the application. + * Creating a rendering context and executing + * the main loop in a separate thread. + */ + public void start(JmeContext.Type contextType, boolean waitFor){ + 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(waitFor); + } + + /** + * Sets an AppProfiler hook that will be called back for + * specific steps within a single update frame. Value defaults + * to null. + */ + public void setAppProfiler(AppProfiler prof) { + this.prof = prof; + if (renderManager != null) { + renderManager.setAppProfiler(prof); + } + } + + /** + * Returns the current AppProfiler hook, or null if none is set. + */ + public AppProfiler getAppProfiler() { + return prof; + } + + /** + * Initializes the application's canvas for use. + *

+ * 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. + *

+ * Same as calling startCanvas(false) + * + * @see #startCanvas(boolean) + */ + public void startCanvas(){ + startCanvas(false); + } + + /** + * Starts the rendering thread after createCanvas() has been called. + *

+ * 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. + *

+ * 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. + *

+ * Initializes the Application, 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 not in headless mode + if (context.getType() != JmeContext.Type.Headless) { + 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 (lostFocusBehavior != LostFocusBehavior.Disabled) { + if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) { + paused = false; + } + context.setAutoFlushFrames(true); + if (inputManager != null) { + inputManager.reset(); + } + } + } + + /** + * Internal use only. + */ + public void loseFocus(){ + if (lostFocusBehavior != LostFocusBehavior.Disabled){ + if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) { + 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. + *

+ * 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. + * + * @param callable The callable to run in the main jME3 thread + */ + public Future enqueue(Callable callable) { + AppTask task = new AppTask(callable); + taskQueue.add(task); + return task; + } + + /** + * Enqueues a runnable object to execute in the jME3 + * rendering thread. + *

+ * Runnables are executed right at the beginning of the main loop. + * They are executed even if the application is currently paused + * or out of focus. + * + * @param runnable The runnable to run in the main jME3 thread + */ + public void enqueue(Runnable runnable){ + enqueue(new RunnableWrapper(runnable)); + } + + /** + * 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); + + if (prof!=null) prof.appStep(AppStep.QueuedTasks); + runQueuedTasks(); + + if (speed == 0 || paused) + return; + + timer.update(); + + if (inputEnabled){ + if (prof!=null) prof.appStep(AppStep.ProcessInput); + inputManager.update(timer.getTimePerFrame()); + } + + if (audioRenderer != null){ + if (prof!=null) prof.appStep(AppStep.ProcessAudio); + 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; + } + + private class RunnableWrapper implements Callable{ + private final Runnable runnable; + + public RunnableWrapper(Runnable runnable){ + this.runnable = runnable; + } + + @Override + public Object call(){ + runnable.run(); + return null; + } + + } + +} diff --git a/jme3-core/src/main/java/com/jme3/app/SimpleApplication.java b/jme3-core/src/main/java/com/jme3/app/SimpleApplication.java index 9433754dc..310191007 100644 --- a/jme3-core/src/main/java/com/jme3/app/SimpleApplication.java +++ b/jme3-core/src/main/java/com/jme3/app/SimpleApplication.java @@ -59,17 +59,17 @@ import com.jme3.system.JmeSystem; * C- Display the camera position and rotation in the console. * M- Display memory usage in the console. * - * + * * A {@link com.jme3.app.FlyCamAppState} is by default attached as well and can * be removed by calling stateManager.detach( stateManager.getState(FlyCamAppState.class) ); */ -public abstract class SimpleApplication extends Application { +public abstract class SimpleApplication extends LegacyApplication { public static final String INPUT_MAPPING_EXIT = "SIMPLEAPP_Exit"; public static final String INPUT_MAPPING_CAMERA_POS = DebugKeysAppState.INPUT_MAPPING_CAMERA_POS; public static final String INPUT_MAPPING_MEMORY = DebugKeysAppState.INPUT_MAPPING_MEMORY; public static final String INPUT_MAPPING_HIDE_STATS = "SIMPLEAPP_HideStats"; - + protected Node rootNode = new Node("Root Node"); protected Node guiNode = new Node("Gui Node"); protected BitmapText fpsText; @@ -77,7 +77,7 @@ public abstract class SimpleApplication extends Application { protected FlyByCamera flyCam; protected boolean showSettings = true; private AppActionListener actionListener = new AppActionListener(); - + private class AppActionListener implements ActionListener { public void onAction(String name, boolean value, float tpf) { @@ -101,7 +101,7 @@ public abstract class SimpleApplication extends Application { public SimpleApplication( AppState... initialStates ) { super(); - + if (initialStates != null) { for (AppState a : initialStates) { if (a != null) { @@ -193,7 +193,7 @@ public abstract class SimpleApplication extends Application { guiViewPort.attachScene(guiNode); if (inputManager != null) { - + // We have to special-case the FlyCamAppState because too // many SimpleApplication subclasses expect it to exist in // simpleInit(). But at least it only gets initialized if @@ -201,7 +201,7 @@ public abstract class SimpleApplication extends Application { if (stateManager.getState(FlyCamAppState.class) != null) { flyCam = new FlyByCamera(cam); flyCam.setMoveSpeed(1f); // odd to set this here but it did it before - stateManager.getState(FlyCamAppState.class).setCamera( flyCam ); + stateManager.getState(FlyCamAppState.class).setCamera( flyCam ); } if (context.getType() == Type.Display) { @@ -210,10 +210,10 @@ public abstract class SimpleApplication extends Application { if (stateManager.getState(StatsAppState.class) != null) { inputManager.addMapping(INPUT_MAPPING_HIDE_STATS, new KeyTrigger(KeyInput.KEY_F5)); - inputManager.addListener(actionListener, INPUT_MAPPING_HIDE_STATS); + inputManager.addListener(actionListener, INPUT_MAPPING_HIDE_STATS); } - - inputManager.addListener(actionListener, INPUT_MAPPING_EXIT); + + inputManager.addListener(actionListener, INPUT_MAPPING_EXIT); } if (stateManager.getState(StatsAppState.class) != null) { @@ -230,37 +230,37 @@ public abstract class SimpleApplication extends Application { @Override public void update() { if (prof!=null) prof.appStep(AppStep.BeginFrame); - + super.update(); // makes sure to execute AppTasks if (speed == 0 || paused) { return; } float tpf = timer.getTimePerFrame() * speed; - + // update states if (prof!=null) prof.appStep(AppStep.StateManagerUpdate); stateManager.update(tpf); // simple update and root node simpleUpdate(tpf); - + if (prof!=null) prof.appStep(AppStep.SpatialUpdate); rootNode.updateLogicalState(tpf); guiNode.updateLogicalState(tpf); - + rootNode.updateGeometricState(); guiNode.updateGeometricState(); - + // render states if (prof!=null) prof.appStep(AppStep.StateManagerRender); stateManager.render(renderManager); - + if (prof!=null) prof.appStep(AppStep.RenderFrame); renderManager.render(tpf, context.isRenderable()); simpleRender(renderManager); stateManager.postRender(); - + if (prof!=null) prof.appStep(AppStep.EndFrame); } diff --git a/jme3-core/src/main/java/com/jme3/app/StatsAppState.java b/jme3-core/src/main/java/com/jme3/app/StatsAppState.java index 346733257..d5ffde097 100644 --- a/jme3-core/src/main/java/com/jme3/app/StatsAppState.java +++ b/jme3-core/src/main/java/com/jme3/app/StatsAppState.java @@ -46,7 +46,7 @@ import com.jme3.scene.shape.Quad; /** * Displays stats in SimpleApplication's GUI node or - * using the node and font parameters provided. + * using the node and font parameters provided. * * @author Paul Speed */ @@ -58,7 +58,7 @@ public class StatsAppState extends AbstractAppState { private boolean showFps = true; private boolean showStats = true; private boolean darkenBehind = true; - + protected Node guiNode; protected float secondCounter = 0.0f; protected int frameCounter = 0; @@ -68,7 +68,7 @@ public class StatsAppState extends AbstractAppState { protected Geometry darkenStats; public StatsAppState() { - } + } public StatsAppState( Node guiNode, BitmapFont guiFont ) { this.guiNode = guiNode; @@ -89,7 +89,7 @@ public class StatsAppState extends AbstractAppState { public BitmapText getFpsText() { return fpsText; } - + public StatsView getStatsView() { return statsView; } @@ -110,7 +110,7 @@ public class StatsAppState extends AbstractAppState { if (darkenFps != null) { darkenFps.setCullHint(showFps && darkenBehind ? CullHint.Never : CullHint.Always); } - + } } @@ -138,7 +138,7 @@ public class StatsAppState extends AbstractAppState { public void initialize(AppStateManager stateManager, Application app) { super.initialize(stateManager, app); this.app = app; - + if (app instanceof SimpleApplication) { SimpleApplication simpleApp = (SimpleApplication)app; if (guiNode == null) { @@ -147,21 +147,21 @@ public class StatsAppState extends AbstractAppState { if (guiFont == null ) { guiFont = simpleApp.guiFont; } - } - + } + if (guiNode == null) { throw new RuntimeException( "No guiNode specific and cannot be automatically determined." ); - } - + } + if (guiFont == null) { guiFont = app.getAssetManager().loadFont("Interface/Fonts/Default.fnt"); } - - loadFpsText(); - loadStatsView(); + + loadFpsText(); + loadStatsView(); loadDarken(); } - + /** * Attaches FPS statistics to guiNode and displays it on the screen. * @@ -170,12 +170,12 @@ public class StatsAppState extends AbstractAppState { if (fpsText == null) { fpsText = new BitmapText(guiFont, false); } - + fpsText.setLocalTranslation(0, fpsText.getLineHeight(), 0); fpsText.setText("Frames per second"); fpsText.setCullHint(showFps ? CullHint.Never : CullHint.Always); guiNode.attachChild(fpsText); - + } /** @@ -184,53 +184,53 @@ public class StatsAppState extends AbstractAppState { * */ public void loadStatsView() { - statsView = new StatsView("Statistics View", - app.getAssetManager(), + statsView = new StatsView("Statistics View", + app.getAssetManager(), app.getRenderer().getStatistics()); // move it up so it appears above fps text statsView.setLocalTranslation(0, fpsText.getLineHeight(), 0); statsView.setEnabled(showStats); - statsView.setCullHint(showStats ? CullHint.Never : CullHint.Always); + statsView.setCullHint(showStats ? CullHint.Never : CullHint.Always); guiNode.attachChild(statsView); } - + public void loadDarken() { - Material mat = new Material(app.assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); mat.setColor("Color", new ColorRGBA(0,0,0,0.5f)); mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); - + darkenFps = new Geometry("StatsDarken", new Quad(200, fpsText.getLineHeight())); darkenFps.setMaterial(mat); darkenFps.setLocalTranslation(0, 0, -1); darkenFps.setCullHint(showFps && darkenBehind ? CullHint.Never : CullHint.Always); guiNode.attachChild(darkenFps); - + darkenStats = new Geometry("StatsDarken", new Quad(200, statsView.getHeight())); darkenStats.setMaterial(mat); darkenStats.setLocalTranslation(0, fpsText.getHeight(), -1); darkenStats.setCullHint(showStats && darkenBehind ? CullHint.Never : CullHint.Always); guiNode.attachChild(darkenStats); } - + @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); - + if (enabled) { fpsText.setCullHint(showFps ? CullHint.Never : CullHint.Always); darkenFps.setCullHint(showFps && darkenBehind ? CullHint.Never : CullHint.Always); statsView.setEnabled(showStats); - statsView.setCullHint(showStats ? CullHint.Never : CullHint.Always); + statsView.setCullHint(showStats ? CullHint.Never : CullHint.Always); darkenStats.setCullHint(showStats && darkenBehind ? CullHint.Never : CullHint.Always); } else { fpsText.setCullHint(CullHint.Always); darkenFps.setCullHint(CullHint.Always); statsView.setEnabled(false); - statsView.setCullHint(CullHint.Always); + statsView.setCullHint(CullHint.Always); darkenStats.setCullHint(CullHint.Always); } } - + @Override public void update(float tpf) { if (showFps) { @@ -241,14 +241,14 @@ public class StatsAppState extends AbstractAppState { fpsText.setText("Frames per second: " + fps); secondCounter = 0.0f; frameCounter = 0; - } + } } } @Override public void cleanup() { super.cleanup(); - + guiNode.detachChild(statsView); guiNode.detachChild(fpsText); guiNode.detachChild(darkenFps); diff --git a/jme3-desktop/src/main/java/com/jme3/app/AppletHarness.java b/jme3-desktop/src/main/java/com/jme3/app/AppletHarness.java index 18fc82a61..159bd95ac 100644 --- a/jme3-desktop/src/main/java/com/jme3/app/AppletHarness.java +++ b/jme3-desktop/src/main/java/com/jme3/app/AppletHarness.java @@ -50,12 +50,12 @@ import javax.swing.SwingUtilities; */ public class AppletHarness extends Applet { - public static final HashMap appToApplet - = new HashMap(); + public static final HashMap appToApplet + = new HashMap(); protected JmeCanvasContext context; protected Canvas canvas; - protected Application app; + protected LegacyApplication app; protected String appClass; protected URL appCfg = null; @@ -103,7 +103,7 @@ public class AppletHarness extends Applet { JmeSystem.setLowPermissions(true); try{ - Class clazz = (Class) Class.forName(appClass); + Class clazz = (Class) Class.forName(appClass); app = clazz.newInstance(); }catch (ClassNotFoundException ex){ ex.printStackTrace(); diff --git a/jme3-examples/src/main/java/jme3test/app/TestApplication.java b/jme3-examples/src/main/java/jme3test/app/TestApplication.java index e5306fdc8..1559318bf 100644 --- a/jme3-examples/src/main/java/jme3test/app/TestApplication.java +++ b/jme3-examples/src/main/java/jme3test/app/TestApplication.java @@ -32,19 +32,19 @@ package jme3test.app; -import com.jme3.app.Application; +import com.jme3.app.LegacyApplication; import com.jme3.system.AppSettings; import com.jme3.system.JmeContext.Type; /** - * Test Application functionality, such as create, restart, destroy, etc. + * Test LegacyApplication functionality, such as create, restart, destroy, etc. * @author Kirill */ public class TestApplication { public static void main(String[] args) throws InterruptedException{ System.out.println("Creating application.."); - Application app = new Application(); + LegacyApplication app = new LegacyApplication(); System.out.println("Starting application in LWJGL mode.."); app.start(); System.out.println("Waiting 5 seconds"); @@ -54,7 +54,7 @@ public class TestApplication { Thread.sleep(2000); System.out.println("Starting in fullscreen mode"); - app = new Application(); + app = new LegacyApplication(); AppSettings settings = new AppSettings(true); settings.setFullscreen(true); settings.setResolution(-1,-1); // current width/height @@ -65,7 +65,7 @@ public class TestApplication { Thread.sleep(2000); System.out.println("Creating offscreen buffer application"); - app = new Application(); + app = new LegacyApplication(); app.start(Type.OffscreenSurface); Thread.sleep(3000); System.out.println("Destroying offscreen buffer"); diff --git a/jme3-examples/src/main/java/jme3test/app/TestBareBonesApp.java b/jme3-examples/src/main/java/jme3test/app/TestBareBonesApp.java index cf80c9005..5d3298279 100644 --- a/jme3-examples/src/main/java/jme3test/app/TestBareBonesApp.java +++ b/jme3-examples/src/main/java/jme3test/app/TestBareBonesApp.java @@ -32,7 +32,7 @@ package jme3test.app; -import com.jme3.app.Application; +import com.jme3.app.LegacyApplication; import com.jme3.math.Vector3f; import com.jme3.scene.Geometry; import com.jme3.scene.shape.Box; @@ -40,7 +40,7 @@ import com.jme3.scene.shape.Box; /** * Test a bare-bones application, without SimpleApplication. */ -public class TestBareBonesApp extends Application { +public class TestBareBonesApp extends LegacyApplication { private Geometry boxGeom; @@ -72,7 +72,7 @@ public class TestBareBonesApp extends Application { // do some animation float tpf = timer.getTimePerFrame(); boxGeom.rotate(tpf * 2, tpf * 4, tpf * 3); - + // dont forget to update the scenes boxGeom.updateLogicalState(tpf); boxGeom.updateGeometricState(); diff --git a/jme3-examples/src/main/java/jme3test/app/TestContextRestart.java b/jme3-examples/src/main/java/jme3test/app/TestContextRestart.java index b7e6634e1..0baaef3d6 100644 --- a/jme3-examples/src/main/java/jme3test/app/TestContextRestart.java +++ b/jme3-examples/src/main/java/jme3test/app/TestContextRestart.java @@ -32,7 +32,7 @@ package jme3test.app; -import com.jme3.app.Application; +import com.jme3.app.LegacyApplication; import com.jme3.system.AppSettings; public class TestContextRestart { @@ -40,7 +40,7 @@ public class TestContextRestart { public static void main(String[] args) throws InterruptedException{ AppSettings settings = new AppSettings(true); - final Application app = new Application(); + final LegacyApplication app = new LegacyApplication(); app.setSettings(settings); app.start(); diff --git a/jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java b/jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java index 1ae7a2ada..a19e2add8 100644 --- a/jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java +++ b/jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java @@ -32,13 +32,13 @@ package jme3test.app.state; -import com.jme3.app.Application; +import com.jme3.app.LegacyApplication; import com.jme3.niftygui.NiftyJmeDisplay; import com.jme3.scene.Spatial; import com.jme3.system.AppSettings; import com.jme3.system.JmeContext; -public class TestAppStates extends Application { +public class TestAppStates extends LegacyApplication { public static void main(String[] args){ TestAppStates app = new TestAppStates(); @@ -50,7 +50,7 @@ public class TestAppStates extends Application { AppSettings settings = new AppSettings(true); settings.setResolution(1024, 768); setSettings(settings); - + super.start(contextType); } diff --git a/jme3-examples/src/main/java/jme3test/awt/AppHarness.java b/jme3-examples/src/main/java/jme3test/awt/AppHarness.java index 862f0ab74..77e8d7092 100644 --- a/jme3-examples/src/main/java/jme3test/awt/AppHarness.java +++ b/jme3-examples/src/main/java/jme3test/awt/AppHarness.java @@ -32,7 +32,7 @@ package jme3test.awt; -import com.jme3.app.Application; +import com.jme3.app.LegacyApplication; import com.jme3.system.AppSettings; import com.jme3.system.JmeCanvasContext; import com.jme3.system.JmeSystem; @@ -53,7 +53,7 @@ public class AppHarness extends Applet { private JmeCanvasContext context; private Canvas canvas; - private Application app; + private LegacyApplication app; private String appClass; private URL appCfg = null; @@ -79,7 +79,7 @@ public class AppHarness extends Applet { JmeSystem.setLowPermissions(true); try{ - Class clazz = (Class) Class.forName(appClass); + Class clazz = (Class) Class.forName(appClass); app = clazz.newInstance(); }catch (ClassNotFoundException ex){ ex.printStackTrace(); @@ -91,11 +91,11 @@ public class AppHarness extends Applet { app.setSettings(settings); app.createCanvas(); - + context = (JmeCanvasContext) app.getContext(); canvas = context.getCanvas(); canvas.setSize(getWidth(), getHeight()); - + add(canvas); app.startCanvas(); } @@ -110,14 +110,14 @@ public class AppHarness extends Applet { appClass = getParameter("AppClass"); if (appClass == null) throw new RuntimeException("The required parameter AppClass isn't specified!"); - + try { appCfg = new URL(getParameter("AppSettingsURL")); } catch (MalformedURLException ex) { ex.printStackTrace(); appCfg = null; } - + createCanvas(); System.out.println("applet:init"); } diff --git a/jme3-examples/src/main/java/jme3test/awt/TestApplet.java b/jme3-examples/src/main/java/jme3test/awt/TestApplet.java index 1d5019d8b..8ac4b7f0a 100644 --- a/jme3-examples/src/main/java/jme3test/awt/TestApplet.java +++ b/jme3-examples/src/main/java/jme3test/awt/TestApplet.java @@ -32,7 +32,7 @@ package jme3test.awt; -import com.jme3.app.Application; +import com.jme3.app.LegacyApplication; import com.jme3.app.SimpleApplication; import com.jme3.system.AppSettings; import com.jme3.system.JmeCanvasContext; @@ -46,7 +46,7 @@ import javax.swing.SwingUtilities; public class TestApplet extends Applet { private static JmeCanvasContext context; - private static Application app; + private static LegacyApplication app; private static Canvas canvas; private static TestApplet applet; @@ -62,7 +62,7 @@ public class TestApplet extends Applet { JmeSystem.setLowPermissions(true); try{ - Class clazz = (Class) Class.forName(appClass); + Class clazz = (Class) Class.forName(appClass); app = clazz.newInstance(); }catch (ClassNotFoundException ex){ ex.printStackTrace(); @@ -74,7 +74,7 @@ public class TestApplet extends Applet { app.setSettings(settings); app.createCanvas(); - + context = (JmeCanvasContext) app.getContext(); canvas = context.getCanvas(); canvas.setSize(settings.getWidth(), settings.getHeight()); diff --git a/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java b/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java index 7e7b58a36..be4e5e8f6 100644 --- a/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java +++ b/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java @@ -32,7 +32,7 @@ package jme3test.awt; -import com.jme3.app.Application; +import com.jme3.app.LegacyApplication; import com.jme3.app.SimpleApplication; import com.jme3.system.AppSettings; import com.jme3.system.JmeCanvasContext; @@ -55,7 +55,7 @@ public class TestCanvas { private static JmeCanvasContext context; private static Canvas canvas; - private static Application app; + private static LegacyApplication app; private static JFrame frame; private static Container canvasPanel1, canvasPanel2; private static Container currentPanel; @@ -64,20 +64,20 @@ public class TestCanvas { private static void createTabs(){ tabbedPane = new JTabbedPane(); - + canvasPanel1 = new JPanel(); canvasPanel1.setLayout(new BorderLayout()); tabbedPane.addTab("jME3 Canvas 1", canvasPanel1); - + canvasPanel2 = new JPanel(); canvasPanel2.setLayout(new BorderLayout()); tabbedPane.addTab("jME3 Canvas 2", canvasPanel2); - + frame.getContentPane().add(tabbedPane); - + currentPanel = canvasPanel1; } - + private static void createMenu(){ JMenuBar menuBar = new JMenuBar(); frame.setJMenuBar(menuBar); @@ -95,12 +95,12 @@ public class TestCanvas { itemRemoveCanvas.setText("Add Canvas"); }else if (itemRemoveCanvas.getText().equals("Add Canvas")){ currentPanel.add(canvas, BorderLayout.CENTER); - + itemRemoveCanvas.setText("Remove Canvas"); } } }); - + final JMenuItem itemHideCanvas = new JMenuItem("Hide Canvas"); menuTortureMethods.add(itemHideCanvas); itemHideCanvas.addActionListener(new ActionListener() { @@ -114,7 +114,7 @@ public class TestCanvas { } } }); - + final JMenuItem itemSwitchTab = new JMenuItem("Switch to tab #2"); menuTortureMethods.add(itemSwitchTab); itemSwitchTab.addActionListener(new ActionListener(){ @@ -130,9 +130,9 @@ public class TestCanvas { currentPanel = canvasPanel1; itemSwitchTab.setText("Switch to tab #2"); } - } + } }); - + JMenuItem itemSwitchLaf = new JMenuItem("Switch Look and Feel"); menuTortureMethods.add(itemSwitchLaf); itemSwitchLaf.addActionListener(new ActionListener(){ @@ -146,7 +146,7 @@ public class TestCanvas { frame.pack(); } }); - + JMenuItem itemSmallSize = new JMenuItem("Set size to (0, 0)"); menuTortureMethods.add(itemSmallSize); itemSmallSize.addActionListener(new ActionListener(){ @@ -157,7 +157,7 @@ public class TestCanvas { frame.setPreferredSize(preferred); } }); - + JMenuItem itemKillCanvas = new JMenuItem("Stop/Start Canvas"); menuTortureMethods.add(itemKillCanvas); itemKillCanvas.addActionListener(new ActionListener() { @@ -181,7 +181,7 @@ public class TestCanvas { } }); } - + private static void createFrame(){ frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); @@ -202,7 +202,7 @@ public class TestCanvas { settings.setHeight(480); try{ - Class clazz = (Class) Class.forName(appClass); + Class clazz = (Class) Class.forName(appClass); app = clazz.newInstance(); }catch (ClassNotFoundException ex){ ex.printStackTrace(); @@ -233,7 +233,7 @@ public class TestCanvas { return null; } }); - + } public static void main(String[] args){ @@ -244,20 +244,20 @@ public class TestCanvas { Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]); Logger.getLogger("").addHandler(consoleHandler); - + createCanvas(appClass); - + try { Thread.sleep(500); } catch (InterruptedException ex) { } - + SwingUtilities.invokeLater(new Runnable(){ public void run(){ JPopupMenu.setDefaultLightWeightPopupEnabled(false); createFrame(); - + currentPanel.add(canvas, BorderLayout.CENTER); frame.pack(); startApp();