From 92a96b64d77914b07932827d26949c7b5d778535 Mon Sep 17 00:00:00 2001 From: "nor..67" Date: Fri, 18 Jan 2013 21:12:54 +0000 Subject: [PATCH] SDK: - Improvements to FakeApp lifecycle and cleanup - Use main rootNode for FakeApp - Improve "Run AppState" integration slightly git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10099 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../AppStateExplorerTopComponent.java | 19 +++++-- .../gde/core/appstates/RunAppStateAction.java | 7 +-- .../jme3/gde/core/scene/FakeApplication.java | 26 +++++++++- .../jme3/gde/core/scene/SceneApplication.java | 50 ++++++++++--------- 4 files changed, 70 insertions(+), 32 deletions(-) diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateExplorerTopComponent.java b/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateExplorerTopComponent.java index c4986ecc5..704cc5126 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateExplorerTopComponent.java +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateExplorerTopComponent.java @@ -31,14 +31,14 @@ */ package com.jme3.gde.core.appstates; -import com.jme3.asset.AssetManager; import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.core.scene.FakeApplication; import com.jme3.gde.core.scene.PreviewRequest; import com.jme3.gde.core.scene.SceneApplication; import com.jme3.gde.core.scene.SceneListener; import com.jme3.gde.core.scene.SceneRequest; -import com.jme3.renderer.Camera; import com.jme3.scene.Spatial; +import java.util.Iterator; import javax.swing.ActionMap; import org.netbeans.api.settings.ConvertAsProperties; import org.openide.awt.ActionID; @@ -85,7 +85,8 @@ public final class AppStateExplorerTopComponent extends TopComponent implements return; } mgr = request.getManager(); - final AppStateManagerNode nod = new AppStateManagerNode(request.getFakeApp().getStateManager()); + FakeApplication app = request.getFakeApp(); + final AppStateManagerNode nod = new AppStateManagerNode(app.getStateManager()); jButton1.setEnabled(true); explorerManager.setRootContext(nod); setActivatedNodes(new Node[]{nod}); @@ -93,7 +94,6 @@ public final class AppStateExplorerTopComponent extends TopComponent implements public void sceneClosed(SceneRequest request) { currentRequest = null; - SceneApplication.getApplication().setFakeApp(null); mgr = null; jButton1.setEnabled(false); explorerManager.setRootContext(Node.EMPTY); @@ -121,6 +121,17 @@ public final class AppStateExplorerTopComponent extends TopComponent implements SceneApplication.getApplication().addSceneListener(listener); } + public static void openExplorer() { + for (Iterator it = TopComponent.getRegistry().getOpened().iterator(); it.hasNext();) { + TopComponent topComponent = it.next(); + if (topComponent instanceof AppStateExplorerTopComponent) { + AppStateExplorerTopComponent explorer = (AppStateExplorerTopComponent) topComponent; + explorer.requestVisible(); + return; + } + } + } + /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/RunAppStateAction.java b/sdk/jme3-core/src/com/jme3/gde/core/appstates/RunAppStateAction.java index 8b100e1f2..e3c24cf65 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/appstates/RunAppStateAction.java +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/RunAppStateAction.java @@ -119,13 +119,14 @@ public class RunAppStateAction implements ContextAwareAction { } public void actionPerformed(ActionEvent e) { - //TODO: better way to access scene request + //TODO: better way to access scene request SceneRequest req = SceneApplication.getApplication().getCurrentSceneRequest(); if (req != null) { FakeApplication app = req.getFakeApp(); try { AppState state = (AppState) app.getClassByName(className).newInstance(); app.getStateManager().attach(state); + AppStateExplorerTopComponent.openExplorer(); } catch (InstantiationException ex) { DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Error creating AppState, make sure it has an empty constructor!\n" + ex.getMessage())); Exceptions.printStackTrace(ex); @@ -141,8 +142,8 @@ public class RunAppStateAction implements ContextAwareAction { logger.log(Level.INFO, "No Scene Request available"); } } - - public void checkData(Lookup actionContext, final String name) { + + private void checkData(Lookup actionContext, final String name) { source = null; className = null; try { diff --git a/sdk/jme3-core/src/com/jme3/gde/core/scene/FakeApplication.java b/sdk/jme3-core/src/com/jme3/gde/core/scene/FakeApplication.java index dcb5d4ef8..290b34fcb 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/scene/FakeApplication.java +++ b/sdk/jme3-core/src/com/jme3/gde/core/scene/FakeApplication.java @@ -46,6 +46,7 @@ import com.jme3.renderer.RenderManager; import com.jme3.renderer.Renderer; import com.jme3.renderer.ViewPort; import com.jme3.scene.Node; +import com.jme3.scene.UserData; import com.jme3.scene.control.Control; import com.jme3.system.AppSettings; import com.jme3.system.JmeContext; @@ -56,6 +57,7 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.concurrent.Callable; @@ -392,13 +394,26 @@ public class FakeApplication extends SimpleApplication { */ private ScheduledThreadPoolExecutor fakeAppThread = new ScheduledThreadPoolExecutor(1); - public void setRootNode(Node rootNode) { - this.rootNode = rootNode; + public void cleanupFakeApp() { + if (rootNode == null) { + return; + } + clearNode(rootNode); + appStateManager = new FakeAppStateManager(this); + } + + public void startFakeApp(){ + fakeAppThread = new ScheduledThreadPoolExecutor(1); } public void stopFakeApp() { + cleanupFakeApp(); fakeAppThread.shutdown(); } + + public void newAssetManager(AssetManager manager){ + this.assetManager = manager; + } private void defaultFakeError() { defaultFakeError(false); @@ -594,5 +609,12 @@ public class FakeApplication extends SimpleApplication { } control = externalNode.getControl(Control.class); } + Collection keys = externalNode.getUserDataKeys(); + if (keys != null) { + for (Iterator it = keys.iterator(); it.hasNext();) { + String string = it.next(); + externalNode.setUserData(string, null); + } + } } } diff --git a/sdk/jme3-core/src/com/jme3/gde/core/scene/SceneApplication.java b/sdk/jme3-core/src/com/jme3/gde/core/scene/SceneApplication.java index 201559f34..ad8b175b6 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/scene/SceneApplication.java +++ b/sdk/jme3-core/src/com/jme3/gde/core/scene/SceneApplication.java @@ -26,6 +26,7 @@ package com.jme3.gde.core.scene; import com.jme3.app.Application; import com.jme3.app.StatsView; +import com.jme3.asset.AssetManager; import com.jme3.bullet.BulletAppState; import com.jme3.font.BitmapFont; import com.jme3.font.BitmapText; @@ -91,7 +92,13 @@ public class SceneApplication extends Application implements LookupProvider { } return application; } - protected Node rootNode = new Node("Root Node"); + protected Node rootNode = new Node("Root Node") { + @Override + public boolean removeFromParent() { + DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Trying to remove main RootNode!")); + return false; + } + }; protected Node guiNode = new Node("Gui Node"); private Node statsGuiNode = new Node("Stats Gui Node"); protected Node toolsNode = new Node("Tools Node"); @@ -141,6 +148,7 @@ public class SceneApplication extends Application implements LookupProvider { createCanvas(); startCanvas(true); } + fakeApp = new FakeApplication(rootNode, guiNode, assetManager, cam); nodeSync = new NodeSyncAppState(); stateManager.attach(nodeSync); progressHandle.progress("initialize Base Application", 1); @@ -205,6 +213,7 @@ public class SceneApplication extends Application implements LookupProvider { @Override public void initialize() { thread = Thread.currentThread(); + fakeApp.startFakeApp(); try { super.initialize(); { @@ -261,6 +270,12 @@ public class SceneApplication extends Application implements LookupProvider { } } + @Override + public void destroy() { + fakeApp.stopFakeApp(); + super.destroy(); + } + @Override public void update() { if (speed == 0) { @@ -309,6 +324,8 @@ public class SceneApplication extends Application implements LookupProvider { handleError(e.getMessage(), e); } } + + //TODO: Lookup for Application public Lookup createAdditionalLookup(Lookup baseContext) { @@ -378,26 +395,20 @@ public class SceneApplication extends Application implements LookupProvider { } else { camController.disable(); } - //TODO: reuse fakeapp - fakeApp = new FakeApplication(rootNode, guiNode, request.getManager(), cam); + final AssetManager manager = request.getManager(); request.setFakeApp(fakeApp); enqueue(new Callable() { public Object call() throws Exception { - if (request.getManager() != null) { - assetManager = request.getManager(); + if (manager != null) { + assetManager = manager; + fakeApp.newAssetManager(manager); } Spatial model = request.getRootNode(); if (model == null) { StatusDisplayer.getDefault().setStatusText("could not load Spatial from request: " + getCurrentSceneRequest().getWindowTitle()); return null; } - //TODO: bit dangerous, setting rootNode late - // still it should only be accessed from the - // update loop and be set until then. - - if (model instanceof Node) { - fakeApp.setRootNode((Node) model); - } + //TODO: use FakeApp internal root node rootNode.attachChild(model); if (request.getToolNode() != null) { toolsNode.attachChild(request.getToolNode()); @@ -442,10 +453,6 @@ public class SceneApplication extends Application implements LookupProvider { if (oldRequest.getRequester() instanceof SceneApplication) { camController.disable(); } - if (fakeApp != null) { - fakeApp.stopFakeApp(); - } - fakeApp = null; enqueue(new Callable() { public Object call() throws Exception { if (physicsState != null) { @@ -453,6 +460,10 @@ public class SceneApplication extends Application implements LookupProvider { getStateManager().detach(physicsState); physicsState = null; } + //TODO: possibly dangerous (new var is created in EDT + if (fakeApp != null) { + fakeApp.cleanupFakeApp(); + } toolsNode.detachAllChildren(); rootNode.detachAllChildren(); // resetCam(); @@ -645,11 +656,4 @@ public class SceneApplication extends Application implements LookupProvider { return java.awt.EventQueue.isDispatchThread(); } - public FakeApplication getFakeApp() { - return fakeApp; - } - - public void setFakeApp(FakeApplication fakeApp) { - this.fakeApp = fakeApp; - } }