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 81fdb6d3b..9688a5d1e 100644 --- a/jme3-core/src/main/java/com/jme3/app/Application.java +++ b/jme3-core/src/main/java/com/jme3/app/Application.java @@ -650,12 +650,28 @@ 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; } + + /** + * 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)} @@ -740,4 +756,19 @@ public class Application implements SystemListener { 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-examples/src/main/java/jme3test/app/TestEnqueueRunnable.java b/jme3-examples/src/main/java/jme3test/app/TestEnqueueRunnable.java new file mode 100644 index 000000000..88ce27732 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/app/TestEnqueueRunnable.java @@ -0,0 +1,72 @@ +package jme3test.app; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; + +/** + * @author john01dav + */ +public class TestEnqueueRunnable extends SimpleApplication{ + private ExampleAsyncTask exampleAsyncTask; + + public static void main(String[] args){ + new TestEnqueueRunnable().start(); + } + + @Override + public void simpleInitApp(){ + Geometry geom = new Geometry("Box", new Box(1, 1, 1)); + Material material = new Material(getAssetManager(), "/Common/MatDefs/Misc/Unshaded.j3md"); + material.setColor("Color", ColorRGBA.Blue); //a color is needed to start with + geom.setMaterial(material); + getRootNode().attachChild(geom); + + exampleAsyncTask = new ExampleAsyncTask(material); + exampleAsyncTask.getThread().start(); + } + + @Override + public void destroy(){ + exampleAsyncTask.endTask(); + super.destroy(); + } + + private class ExampleAsyncTask implements Runnable{ + private final Thread thread; + private final Material material; + private volatile boolean running = true; + + public ExampleAsyncTask(Material material){ + this.thread = new Thread(this); + this.material = material; + } + + public Thread getThread(){ + return thread; + } + + public void run(){ + while(running){ + enqueue(new Runnable(){ //primary usage of this in real applications would use lambda expressions which are unavailable at java 6 + public void run(){ + material.setColor("Color", ColorRGBA.randomColor()); + } + }); + + try{ + Thread.sleep(1000); + }catch(InterruptedException e){} + } + } + + public void endTask(){ + running = false; + thread.interrupt(); + } + + } + +}