1/* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32package com.jme3.scene.control; 33 34import com.jme3.app.AppTask; 35import com.jme3.renderer.RenderManager; 36import com.jme3.renderer.ViewPort; 37import com.jme3.scene.Spatial; 38import java.util.concurrent.Callable; 39import java.util.concurrent.ConcurrentLinkedQueue; 40import java.util.concurrent.Future; 41 42/** 43 * Allows for enqueueing tasks onto the update loop / rendering thread. 44 * 45 * Usage: 46 * mySpatial.addControl(new UpdateControl()); // add it once 47 * mySpatial.getControl(UpdateControl.class).enqueue(new Callable() { 48 * public Object call() throws Exception { 49 * // do stuff here 50 * return null; 51 * } 52 * }); 53 * 54 * @author Brent Owens 55 */ 56public class UpdateControl extends AbstractControl { 57 58 private final ConcurrentLinkedQueue<AppTask<?>> taskQueue = new ConcurrentLinkedQueue<AppTask<?>>(); 59 60 /** 61 * Enqueues a task/callable object to execute in the jME3 62 * rendering thread. 63 */ 64 public <V> Future<V> enqueue(Callable<V> callable) { 65 AppTask<V> task = new AppTask<V>(callable); 66 taskQueue.add(task); 67 return task; 68 } 69 70 @Override 71 protected void controlUpdate(float tpf) { 72 AppTask<?> task = taskQueue.poll(); 73 toploop: do { 74 if (task == null) break; 75 while (task.isCancelled()) { 76 task = taskQueue.poll(); 77 if (task == null) break toploop; 78 } 79 task.invoke(); 80 } while (((task = taskQueue.poll()) != null)); 81 } 82 83 @Override 84 protected void controlRender(RenderManager rm, ViewPort vp) { 85 86 } 87 88 public Control cloneForSpatial(Spatial newSpatial) { 89 UpdateControl control = new UpdateControl(); 90 control.setSpatial(newSpatial); 91 control.setEnabled(isEnabled()); 92 control.taskQueue.addAll(taskQueue); 93 return control; 94 } 95 96} 97