Converted Application to an interface and renamed the old Application to

LegacyApplication.  This is a breaking change for any class extending Application
directly.
And regardless, if you refer to Application then you will need to clean build
your app... and any of your dependencies that also refer to Application.  Basically,
anything using an AppState will need to be clean built against the next alpha.
cleanup_build_scripts v3.1.0-alpha4
Paul Speed 9 years ago
parent ab6fb03171
commit 3c56afeae6
  1. 6
      jme3-android/src/main/java/com/jme3/app/AndroidHarness.java
  2. 4
      jme3-android/src/main/java/com/jme3/app/AndroidHarnessFragment.java
  3. 621
      jme3-core/src/main/java/com/jme3/app/Application.java
  4. 774
      jme3-core/src/main/java/com/jme3/app/LegacyApplication.java
  5. 34
      jme3-core/src/main/java/com/jme3/app/SimpleApplication.java
  6. 60
      jme3-core/src/main/java/com/jme3/app/StatsAppState.java
  7. 8
      jme3-desktop/src/main/java/com/jme3/app/AppletHarness.java
  8. 10
      jme3-examples/src/main/java/jme3test/app/TestApplication.java
  9. 6
      jme3-examples/src/main/java/jme3test/app/TestBareBonesApp.java
  10. 4
      jme3-examples/src/main/java/jme3test/app/TestContextRestart.java
  11. 6
      jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java
  12. 14
      jme3-examples/src/main/java/jme3test/awt/AppHarness.java
  13. 8
      jme3-examples/src/main/java/jme3test/awt/TestApplet.java
  14. 42
      jme3-examples/src/main/java/jme3test/awt/TestCanvas.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<? extends Application> clazz = (Class<? extends Application>) Class.forName(appClass);
Class<? extends LegacyApplication> clazz = (Class<? extends LegacyApplication>) Class.forName(appClass);
app = clazz.newInstance();
}

@ -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<? extends Application> clazz = (Class<? extends Application>) Class.forName(appClass);
Class<? extends LegacyApplication> clazz = (Class<? extends LegacyApplication>) Class.forName(appClass);
app = clazz.newInstance();
}

@ -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 <code>Application</code> class represents an instance of a
* real-time 3D rendering jME application.
*
* An <code>Application</code> provides all the tools that are commonly used in jME3
* applications.
*
* jME3 applications *SHOULD NOT EXTEND* this class but extend {@link com.jme3.app.SimpleApplication} instead.
*
* The <code>Application</code> 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<AppTask<?>> taskQueue = new ConcurrentLinkedQueue<AppTask<?>>();
/**
* Create a new instance of <code>Application</code>.
*/
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.
* <p>
* After calling this method, cast the {@link #getContext() context} to
* {@link JmeCanvasContext},
* then acquire the canvas with {@link JmeCanvasContext#getCanvas() }
* and attach it to an AWT/Swing Frame.
* The rendering thread will start when the canvas becomes visible on
* screen, however if you wish to start the context immediately you
* may call {@link #startCanvas() } to force the rendering thread
* to start.
*
* @see JmeCanvasContext
* @see Type#Canvas
*/
public void createCanvas(){
if (context != null && context.isCreated()){
logger.warning("createCanvas() called when application already created!");
return;
}
if (settings == null){
settings = new AppSettings(true);
}
logger.log(Level.FINE, "Starting application: {0}", getClass().getName());
context = JmeSystem.newContext(settings, JmeContext.Type.Canvas);
context.setSystemListener(this);
}
/**
* Starts the rendering thread after createCanvas() has been called.
* <p>
* Same as calling startCanvas(false)
*
* @see #startCanvas(boolean)
*/
public void startCanvas(){
startCanvas(false);
}
/**
* Starts the rendering thread after createCanvas() has been called.
* <p>
* Calling this method is optional, the canvas will start automatically
* when it becomes visible.
*
* @param waitFor If true, the current thread will block until the
* rendering thread is running
*/
public void startCanvas(boolean waitFor){
context.create(waitFor);
}
/**
* Internal use only.
* 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.
* <p>
* Initializes the <code>Application</code>, by creating a display and
* default camera. If display settings are not specified, a default
* 640x480 display is created. Default values are used for the camera;
* perspective projection with 45° field of view, with near
* and far values 1 and 1000 units respectively.
*/
public void initialize(){
if (assetManager == null){
initAssetManager();
}
initDisplay();
initCamera();
if (inputEnabled){
initInput();
}
initAudio();
// update timer so that the next delta is not too large
// timer.update();
timer.reset();
// user code here..
}
/**
* Internal use only.
*/
public void handleError(String errMsg, Throwable t){
// Print error to log.
logger.log(Level.SEVERE, errMsg, t);
// Display error message on screen if 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 <V> Future<V> enqueue(Callable<V> callable) {
AppTask<V> task = new AppTask<V>(callable);
taskQueue.add(task);
return task;
}
public <V> Future<V> enqueue(Callable<V> 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();
}

@ -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 <code>LegacyApplication</code> class represents an instance of a
* real-time 3D rendering jME application.
*
* An <code>LegacyApplication</code> provides all the tools that are commonly used in jME3
* applications.
*
* jME3 applications *SHOULD NOT EXTEND* this class but extend {@link com.jme3.app.SimpleApplication} instead.
*
*/
public class 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<AppTask<?>> taskQueue = new ConcurrentLinkedQueue<AppTask<?>>();
/**
* Create a new instance of <code>LegacyApplication</code>.
*/
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.
* <p>
* By default, pause on lost focus is enabled.
* If enabled, the application will stop updating
* when it loses focus or becomes inactive (e.g. alt-tab).
* For online or real-time applications, this might not be preferable,
* so this feature should be set to disabled. For other applications,
* it is best to keep it on so that CPU usage is not used when
* not necessary.
*
* @param pauseOnLostFocus True to enable pause on lost focus, false
* otherwise.
*
* @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.
* <p>
* Examples of display parameters include display pixel width and height,
* color bit depth, z-buffer bits, anti-aliasing samples, and update frequency.
* If this method is called while the application is already running, then
* {@link #restart() } must be called to apply the settings to the display.
*
* @param settings The settings to set.
*/
public void setSettings(AppSettings settings){
this.settings = settings;
if (context != null && settings.useInput() != inputEnabled){
// may need to create or destroy input based
// on settings change
inputEnabled = !inputEnabled;
if (inputEnabled){
initInput();
}else{
destroyInput();
}
}else{
inputEnabled = settings.useInput();
}
}
/**
* Sets the Timer implementation that will be used for calculating
* frame times. By default, Application will use the Timer as returned
* by the current JmeContext implementation.
*/
public void setTimer(Timer timer){
this.timer = timer;
if (timer != null) {
timer.reset();
}
if (renderManager != null) {
renderManager.setTimer(timer);
}
}
public Timer getTimer(){
return timer;
}
private void initDisplay(){
// aquire important objects
// from the context
settings = context.getSettings();
// Only reset the timer if a user has not already provided one
if (timer == null) {
timer = context.getTimer();
}
renderer = context.getRenderer();
}
private void initAudio(){
if (settings.getAudioRenderer() != null && context.getType() != Type.Headless){
audioRenderer = JmeSystem.newAudioRenderer(settings);
audioRenderer.initialize();
AudioContext.setAudioRenderer(audioRenderer);
listener = new Listener();
audioRenderer.setListener(listener);
}
}
/**
* Creates the camera to use for rendering. Default values are perspective
* projection with 45° field of view, with near and far values 1 and 1000
* units respectively.
*/
private void initCamera(){
cam = new Camera(settings.getWidth(), settings.getHeight());
cam.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f);
cam.setLocation(new Vector3f(0f, 0f, 10f));
cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);
renderManager = new RenderManager(renderer);
//Remy - 09/14/2010 setted the timer in the renderManager
renderManager.setTimer(timer);
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.
* <p>
* After calling this method, cast the {@link #getContext() context} to
* {@link JmeCanvasContext},
* then acquire the canvas with {@link JmeCanvasContext#getCanvas() }
* and attach it to an AWT/Swing Frame.
* The rendering thread will start when the canvas becomes visible on
* screen, however if you wish to start the context immediately you
* may call {@link #startCanvas() } to force the rendering thread
* to start.
*
* @see JmeCanvasContext
* @see Type#Canvas
*/
public void createCanvas(){
if (context != null && context.isCreated()){
logger.warning("createCanvas() called when application already created!");
return;
}
if (settings == null){
settings = new AppSettings(true);
}
logger.log(Level.FINE, "Starting application: {0}", getClass().getName());
context = JmeSystem.newContext(settings, JmeContext.Type.Canvas);
context.setSystemListener(this);
}
/**
* Starts the rendering thread after createCanvas() has been called.
* <p>
* Same as calling startCanvas(false)
*
* @see #startCanvas(boolean)
*/
public void startCanvas(){
startCanvas(false);
}
/**
* Starts the rendering thread after createCanvas() has been called.
* <p>
* Calling this method is optional, the canvas will start automatically
* when it becomes visible.
*
* @param waitFor If true, the current thread will block until the
* rendering thread is running
*/
public void startCanvas(boolean waitFor){
context.create(waitFor);
}
/**
* Internal use only.
*/
public void reshape(int w, int h){
renderManager.notifyReshape(w, h);
}
/**
* Restarts the context, applying any changed settings.
* <p>
* Changes to the {@link AppSettings} of this Application are not
* applied immediately; calling this method forces the context
* to restart, applying the new settings.
*/
public void restart(){
context.setSettings(settings);
context.restart();
}
/**
* Requests the context to close, shutting down the main loop
* and making necessary cleanup operations.
*
* Same as calling stop(false)
*
* @see #stop(boolean)
*/
public void stop(){
stop(false);
}
/**
* Requests the context to close, shutting down the main loop
* and making necessary cleanup operations.
* After the application has stopped, it cannot be used anymore.
*/
public void stop(boolean waitFor){
logger.log(Level.FINE, "Closing application: {0}", getClass().getName());
context.destroy(waitFor);
}
/**
* Do not call manually.
* Callback from ContextListener.
* <p>
* Initializes the <code>Application</code>, by creating a display and
* default camera. If display settings are not specified, a default
* 640x480 display is created. Default values are used for the camera;
* perspective projection with 45° field of view, with near
* and far values 1 and 1000 units respectively.
*/
public void initialize(){
if (assetManager == null){
initAssetManager();
}
initDisplay();
initCamera();
if (inputEnabled){
initInput();
}
initAudio();
// update timer so that the next delta is not too large
// timer.update();
timer.reset();
// user code here..
}
/**
* Internal use only.
*/
public void handleError(String errMsg, Throwable t){
// Print error to log.
logger.log(Level.SEVERE, errMsg, t);
// Display error message on screen if 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.
* <p>
* Callables are executed right at the beginning of the main loop.
* They are executed even if the application is currently paused
* or out of focus.
*
* @param callable The callable to run in the main jME3 thread
*/
public <V> Future<V> enqueue(Callable<V> callable) {
AppTask<V> task = new AppTask<V>(callable);
taskQueue.add(task);
return task;
}
/**
* Enqueues a runnable object to execute in the jME3
* rendering thread.
* <p>
* 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;
}
}
}

@ -59,17 +59,17 @@ import com.jme3.system.JmeSystem;
* <tr><td>C</td><td>- Display the camera position and rotation in the console.</td></tr>
* <tr><td>M</td><td>- Display memory usage in the console.</td></tr>
* </table>
*
*
* A {@link com.jme3.app.FlyCamAppState} is by default attached as well and can
* be removed by calling <code>stateManager.detach( stateManager.getState(FlyCamAppState.class) );</code>
*/
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);
}

@ -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);

@ -50,12 +50,12 @@ import javax.swing.SwingUtilities;
*/
public class AppletHarness extends Applet {
public static final HashMap<Application, Applet> appToApplet
= new HashMap<Application, Applet>();
public static final HashMap<LegacyApplication, Applet> appToApplet
= new HashMap<LegacyApplication, Applet>();
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<? extends Application> clazz = (Class<? extends Application>) Class.forName(appClass);
Class<? extends LegacyApplication> clazz = (Class<? extends LegacyApplication>) Class.forName(appClass);
app = clazz.newInstance();
}catch (ClassNotFoundException ex){
ex.printStackTrace();

@ -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");

@ -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();

@ -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();

@ -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);
}

@ -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<? extends Application> clazz = (Class<? extends Application>) Class.forName(appClass);
Class<? extends LegacyApplication> clazz = (Class<? extends LegacyApplication>) 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");
}

@ -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<? extends Application> clazz = (Class<? extends Application>) Class.forName(appClass);
Class<? extends LegacyApplication> clazz = (Class<? extends LegacyApplication>) 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());

@ -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<? extends Application> clazz = (Class<? extends Application>) Class.forName(appClass);
Class<? extends LegacyApplication> clazz = (Class<? extends LegacyApplication>) 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();

Loading…
Cancel
Save