|
@@ -29,7 +29,7 @@
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
*/
|
|
-package com.jme3.gde.core.appstates;
|
|
|
|
|
|
+package com.jme3.gde.core.scene;
|
|
|
|
|
|
import com.jme3.app.Application;
|
|
import com.jme3.app.Application;
|
|
import com.jme3.app.SimpleApplication;
|
|
import com.jme3.app.SimpleApplication;
|
|
@@ -38,6 +38,7 @@ import com.jme3.app.state.AppStateManager;
|
|
import com.jme3.asset.AssetManager;
|
|
import com.jme3.asset.AssetManager;
|
|
import com.jme3.audio.AudioRenderer;
|
|
import com.jme3.audio.AudioRenderer;
|
|
import com.jme3.audio.Listener;
|
|
import com.jme3.audio.Listener;
|
|
|
|
+import com.jme3.gde.core.appstates.AppStateManagerNode;
|
|
import com.jme3.input.FlyByCamera;
|
|
import com.jme3.input.FlyByCamera;
|
|
import com.jme3.input.InputManager;
|
|
import com.jme3.input.InputManager;
|
|
import com.jme3.renderer.Camera;
|
|
import com.jme3.renderer.Camera;
|
|
@@ -45,6 +46,7 @@ import com.jme3.renderer.RenderManager;
|
|
import com.jme3.renderer.Renderer;
|
|
import com.jme3.renderer.Renderer;
|
|
import com.jme3.renderer.ViewPort;
|
|
import com.jme3.renderer.ViewPort;
|
|
import com.jme3.scene.Node;
|
|
import com.jme3.scene.Node;
|
|
|
|
+import com.jme3.scene.control.Control;
|
|
import com.jme3.system.AppSettings;
|
|
import com.jme3.system.AppSettings;
|
|
import com.jme3.system.JmeContext;
|
|
import com.jme3.system.JmeContext;
|
|
import com.jme3.system.JmeContext.Type;
|
|
import com.jme3.system.JmeContext.Type;
|
|
@@ -54,9 +56,14 @@ import java.io.ByteArrayOutputStream;
|
|
import java.io.PrintStream;
|
|
import java.io.PrintStream;
|
|
import java.io.UnsupportedEncodingException;
|
|
import java.io.UnsupportedEncodingException;
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
|
+import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
import java.util.concurrent.Callable;
|
|
import java.util.concurrent.Callable;
|
|
|
|
+import java.util.concurrent.ExecutionException;
|
|
import java.util.concurrent.Future;
|
|
import java.util.concurrent.Future;
|
|
|
|
+import java.util.concurrent.ScheduledThreadPoolExecutor;
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
+import java.util.concurrent.TimeoutException;
|
|
import org.openide.DialogDisplayer;
|
|
import org.openide.DialogDisplayer;
|
|
import org.openide.NotifyDescriptor;
|
|
import org.openide.NotifyDescriptor;
|
|
import org.openide.util.Exceptions;
|
|
import org.openide.util.Exceptions;
|
|
@@ -332,9 +339,60 @@ public class FakeApplication extends SimpleApplication {
|
|
//TODO: also nice messages
|
|
//TODO: also nice messages
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public static class FakeAppStateManager extends AppStateManager {
|
|
|
|
+
|
|
|
|
+ private AppStateManagerNode node;
|
|
|
|
+ ArrayList<AppState> states = new ArrayList<AppState>();
|
|
|
|
+
|
|
|
|
+ public FakeAppStateManager(Application app) {
|
|
|
|
+ super(app);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public List<AppState> getAddedStates() {
|
|
|
|
+ return states;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public boolean attach(AppState state) {
|
|
|
|
+ boolean ret = super.attach(state);
|
|
|
|
+ if (ret) {
|
|
|
|
+ states.add(state);
|
|
|
|
+ }
|
|
|
|
+ if (node != null) {
|
|
|
|
+ node.refresh();
|
|
|
|
+ }
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public boolean detach(AppState state) {
|
|
|
|
+ boolean ret = super.detach(state);
|
|
|
|
+ if (ret) {
|
|
|
|
+ states.remove(state);
|
|
|
|
+ }
|
|
|
|
+ if (node != null) {
|
|
|
|
+ node.refresh();
|
|
|
|
+ }
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void setNode(AppStateManagerNode node) {
|
|
|
|
+ this.node = node;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
/*
|
|
/*
|
|
* Internal
|
|
* Internal
|
|
*/
|
|
*/
|
|
|
|
+ private ScheduledThreadPoolExecutor fakeAppThread;
|
|
|
|
+
|
|
|
|
+ public void startFakeApp() {
|
|
|
|
+ fakeAppThread = new ScheduledThreadPoolExecutor(1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void stopFakeApp() {
|
|
|
|
+ fakeAppThread.shutdown();
|
|
|
|
+ }
|
|
|
|
+
|
|
private void defaultFakeError() {
|
|
private void defaultFakeError() {
|
|
defaultFakeError(false);
|
|
defaultFakeError(false);
|
|
}
|
|
}
|
|
@@ -366,60 +424,129 @@ public class FakeApplication extends SimpleApplication {
|
|
NotifyDescriptor.WARNING_MESSAGE));
|
|
NotifyDescriptor.WARNING_MESSAGE));
|
|
}
|
|
}
|
|
|
|
|
|
- public void updateFake(float tpf) {
|
|
|
|
-// System.out.println("UPDATE");
|
|
|
|
- appStateManager.update(tpf);
|
|
|
|
|
|
+ private void removeAllStates() {
|
|
|
|
+ for (Iterator<AppState> it = new ArrayList(appStateManager.getAddedStates()).iterator(); it.hasNext();) {
|
|
|
|
+ AppState appState = it.next();
|
|
|
|
+ appStateManager.detach(appState);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- public void renderFake() {
|
|
|
|
- appStateManager.render(renderManager);
|
|
|
|
|
|
+ public boolean updateFake(final float tpf) {
|
|
|
|
+ Future fut = fakeAppThread.submit(new Callable<Void>() {
|
|
|
|
+ public Void call() throws Exception {
|
|
|
|
+ appStateManager.update(tpf);
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ try {
|
|
|
|
+ fut.get(1, TimeUnit.MINUTES);
|
|
|
|
+ } catch (InterruptedException ex) {
|
|
|
|
+ Exceptions.printStackTrace(ex);
|
|
|
|
+ } catch (ExecutionException ex) {
|
|
|
|
+ removeAllStates();
|
|
|
|
+ DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Exception in AppState, all AppStates removed."));
|
|
|
|
+ return false;
|
|
|
|
+ } catch (TimeoutException ex) {
|
|
|
|
+ fut.cancel(true);
|
|
|
|
+ removeAllStates();
|
|
|
|
+ DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Update loop was blocked for too long, all AppStates removed."));
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
- public static class FakeAppStateManager extends AppStateManager {
|
|
|
|
-
|
|
|
|
- private AppStateManagerNode node;
|
|
|
|
- ArrayList<AppState> states = new ArrayList<AppState>();
|
|
|
|
|
|
+ public boolean renderFake() {
|
|
|
|
+ Future fut = fakeAppThread.submit(new Callable<Void>() {
|
|
|
|
+ public Void call() throws Exception {
|
|
|
|
+ appStateManager.render(renderManager);
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ try {
|
|
|
|
+ fut.get(1, TimeUnit.MINUTES);
|
|
|
|
+ } catch (InterruptedException ex) {
|
|
|
|
+ Exceptions.printStackTrace(ex);
|
|
|
|
+ } catch (ExecutionException ex) {
|
|
|
|
+ removeAllStates();
|
|
|
|
+ DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Exception in AppState, all AppStates removed."));
|
|
|
|
+ return false;
|
|
|
|
+ } catch (TimeoutException ex) {
|
|
|
|
+ fut.cancel(true);
|
|
|
|
+ removeAllStates();
|
|
|
|
+ DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Render loop was blocked for too long, all AppStates removed."));
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
|
|
- public FakeAppStateManager(Application app) {
|
|
|
|
- super(app);
|
|
|
|
|
|
+ public boolean updateExternalLogicalState(final Node externalNode, final float tpf) {
|
|
|
|
+ Future fut = fakeAppThread.submit(new Callable<Void>() {
|
|
|
|
+ public Void call() throws Exception {
|
|
|
|
+ externalNode.updateLogicalState(tpf);
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ try {
|
|
|
|
+ fut.get(1, TimeUnit.MINUTES);
|
|
|
|
+ } catch (InterruptedException ex) {
|
|
|
|
+ Exceptions.printStackTrace(ex);
|
|
|
|
+ } catch (ExecutionException ex) {
|
|
|
|
+ clearNode(externalNode);
|
|
|
|
+ DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Exception in Control, scene content removed.\n" + ex.getMessage()));
|
|
|
|
+ return false;
|
|
|
|
+ } catch (TimeoutException ex) {
|
|
|
|
+ fut.cancel(true);
|
|
|
|
+ clearNode(externalNode);
|
|
|
|
+ DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Render loop was blocked for too long, scene content removed."));
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
|
|
- public List<AppState> getAddedStates() {
|
|
|
|
- return states;
|
|
|
|
|
|
+ public boolean updateExternalGeometricState(final Node externalNode) {
|
|
|
|
+ Future fut = fakeAppThread.submit(new Callable<Void>() {
|
|
|
|
+ public Void call() throws Exception {
|
|
|
|
+ externalNode.updateGeometricState();
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ try {
|
|
|
|
+ fut.get(1, TimeUnit.MINUTES);
|
|
|
|
+ } catch (InterruptedException ex) {
|
|
|
|
+ Exceptions.printStackTrace(ex);
|
|
|
|
+ } catch (ExecutionException ex) {
|
|
|
|
+ clearNode(externalNode);
|
|
|
|
+ DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Exception in Control, scene content removed.\n" + ex.getMessage()));
|
|
|
|
+ return false;
|
|
|
|
+ } catch (TimeoutException ex) {
|
|
|
|
+ fut.cancel(true);
|
|
|
|
+ clearNode(externalNode);
|
|
|
|
+ DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Render loop was blocked for too long, scene content removed."));
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
|
|
- @Override
|
|
|
|
- public boolean attach(AppState state) {
|
|
|
|
- boolean ret = super.attach(state);
|
|
|
|
|
|
+ private void clearNode(final Node externalNode) {
|
|
|
|
+ while (!externalNode.getChildren().isEmpty()) {
|
|
try {
|
|
try {
|
|
- states.add(state);
|
|
|
|
|
|
+ externalNode.detachAllChildren();
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
Exceptions.printStackTrace(e);
|
|
Exceptions.printStackTrace(e);
|
|
|
|
+ } catch (Error e) {
|
|
|
|
+ Exceptions.printStackTrace(e);
|
|
}
|
|
}
|
|
-// DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(
|
|
|
|
-// "attach state",
|
|
|
|
-// NotifyDescriptor.WARNING_MESSAGE));
|
|
|
|
- if (node != null) {
|
|
|
|
-// DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(
|
|
|
|
-// "refresh node",
|
|
|
|
-// NotifyDescriptor.WARNING_MESSAGE));
|
|
|
|
- node.refresh();
|
|
|
|
- }
|
|
|
|
- return ret;
|
|
|
|
}
|
|
}
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public boolean detach(AppState state) {
|
|
|
|
|
|
+ Control control = externalNode.getControl(Control.class);
|
|
|
|
+ while (control != null) {
|
|
try {
|
|
try {
|
|
- states.remove(state);
|
|
|
|
|
|
+ externalNode.removeControl(control);
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
Exceptions.printStackTrace(e);
|
|
Exceptions.printStackTrace(e);
|
|
|
|
+ } catch (Error e) {
|
|
|
|
+ Exceptions.printStackTrace(e);
|
|
}
|
|
}
|
|
- return super.detach(state);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void setNode(AppStateManagerNode node) {
|
|
|
|
- this.node = node;
|
|
|
|
|
|
+ control = externalNode.getControl(Control.class);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|