hey there. Since I think that enqueuing Callables into the GameTaskQueueManager all over the code when you use StandardGame, I implemented a little Aspect in AspectJ.
Note that you have to set the name of the OpenGL Thread name to "GL" or you can change the static string in the aspect.
The Pointcuts are the calls from the list of calls that have to be done inside the OpenGL thread, as listed in the wiki plus a few I added.
I have not tested the performance loss thoroughly, but it is unnoticable afaik because the code is weaved at load time i guess.
EDIT: changed the code on 12/10/2008
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import com.jme.util.GameTaskQueueManager;
/**
* @author Andreas Grabner
*
*/
public aspect GTQMAspect {
private static final String glName = "GL";
public pointcut openGlMethodExecution():
within(/* yourgamepackage */..*) &&
!within(GTQMAspect) &&
(call(com.jme.renderer.Renderer.Renderer.new(..)) ||
call(* com.jme.renderer.Renderer.clearZBuffer(..)) ||
call(* com.jme.renderer.Renderer.clearColorBuffer(..)) ||
call(* com.jme.renderer.Renderer.clearStencilBuffer(..)) ||
call(* com.jme.renderer.Renderer.clearBuffers(..)) ||
call(* com.jme.renderer.Renderer.clearStrictBuffers(..)) ||
call(* com.jme.renderer.Renderer.displayBackBuffer(..)) ||
call(* com.jme.renderer.Renderer.setOrtho(..)) ||
call(* com.jme.renderer.Renderer.setOrthoCenter(..)) ||
call(* com.jme.renderer.Renderer.unsetOrtho(..)) ||
call(* com.jme.renderer.Renderer.takeScreenshot(..)) ||
call(* com.jme.renderer.Renderer.grabScreenContents(..)) ||
call(* com.jme.renderer.Renderer.draw(..)) ||
call(* com.jme.renderer.Renderer.flush(..)) ||
call(* com.jme.renderer.Renderer.finish(..)) ||
call(* com.jme.renderer.Renderer.createCamera(..)) ||
call(* com.jme.renderer.Renderer.setBackgroundColor(..)) ||
call(* com.jme.renderer.Renderer.createFogState(..)) ||
call(* com.jme.renderer.Camera.setFrustumPerspective(..)) ||
call(* com.jme.input.MouseInput.setCursorVisible(..)) ||
call(* com.jme.scene..lock*(..)) ||
call(* com.jme.scene..lock(..)) ||
call(* com.jme.scene..removeFromParent(..)) ||
call(* com.jme.scene.Skybox.preloadTextures(..)) ||
call(* com.jme.util.TextureManager.loadTexture(..)) ||
call(* com.jme.util.TextureManager.doTextureCleanup(..)) ||
call(* com.jme.util.TextureManager.preloadCache(..)) ||
call(* com.jmex.audio.MusicTrackQueue.play(..)) ||
call(* com.jmex.audio.MusicTrackQueue.setCurrentTrack(..)) ||
call(* com.jmex.audio.MusicTrackQueue.stop(..)) ||
target(com.jmex.effects.water.WaterRenderPass) ||
call(* java.awt.Component.setBackground(..)) ||
call(* java.awt.Component.setSize(..)) ||
call(com.jmex.font2d.Font2D.new(..)) ||
call(com.jmex.font3d.Font3D.new(..)));
Object around(): openGlMethodExecution() {
if (Thread.currentThread().getName().equals(glName)) {
return proceed();
} else {
try {
Signature sig = thisJoinPoint.getSignature();
if (sig instanceof MethodSignature) {
final MethodSignature ms = (MethodSignature) sig;
if (ms.getReturnType().equals(void.class)) {
GameTaskQueueManager.getManager().update(new Callable<Object>() {
public Object call() throws Exception {
proceed();
System.err.println("wrapped with no return value " + ms.toLongString());
return null;
}
});
return null;
} // if
} // if
Future<Object> future = GameTaskQueueManager.getManager().update(new Callable<Object>() {
public Object call() throws Exception {
System.err.println("wrapped with return value " + thisJoinPoint.getSignature().toLongString());
return proceed();
}
});
return future.get();
} catch (InterruptedException ex) {
} catch (ExecutionException ex) {
} // catch
return null; // should not happen
} // else
} // around
} // GTQMAspec
so long,
Andy