Home | History | Annotate | Download | only in control
      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  */
     32 package com.jme3.scene.control;
     33 
     34 import com.jme3.app.AppTask;
     35 import com.jme3.renderer.RenderManager;
     36 import com.jme3.renderer.ViewPort;
     37 import com.jme3.scene.Spatial;
     38 import java.util.concurrent.Callable;
     39 import java.util.concurrent.ConcurrentLinkedQueue;
     40 import 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  */
     56 public 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