When to use GameTaskQueManager?

Hi!



Can somepne please tell me which methods must inside a GameTaskQueManager? If I undersatnd it correctly the methods which only define a "state" (not necessarily RenderState but also Geometric states, positions locations etc.) save the data locally in memory. Only if I call a GL method directly (of course, using one of the JME wrapper class methods) GameTaskQueManager has to be used.



I asked due to the fact that I don't get any error messages but sometimes I see no graphics output in the window. Sometimes it works, sometimes not. I must say that I love the engine but the tutorial about creating a running application from the scratch is rather poor. The tutorials only deal with BaseSimpleGame, SimopleGame etc classes. I have included the JME within my NetBeans framework, i.e. a Swing application and find it very hard to implement everything correctly. If someone could give me a hint or even a process flow in which row to call the necessary methods to get a minimum JMECanvasImplementation to run insight a Swing application I would be very grateful.



Thanks a lot in advance,



Regards,

Equilibrium

Use GameTaskQueueManager whenever you need to use a method that needs to be implimented within the OpenGL thread. There is no definite way of telling whether a call needs to be done in the openGL thread or not; however, if your messing with rendering or context, then it is a most likely a openGL call. This is a list of some of the most commonly used methods that needs to access OpenGL HERE.



You’ll always know its a openGL call if you get an odd error that references it, otherwise if it compiles and runs fine without any errors then it is probably not a openGL thing.



As for your meshes not showing up if your running jME or jME2, remember to always call .updateRenderState(); anytime you make changes to the geometry

I'm writing a Swing-JME application (with SimplePassCanvasImpl) and i found that everything runs inside the EDT so, in practice, there is no need to use GameTaskQueueManager.



In theory JME could use a dedicated thread to manage the scene graph so GameTaskQueueManager is the way to go if you have to alter the scene.



Unfortunately the GameTaskQueueManager API doesn't state (or i don't see it) that an happens-before relationship exists between actions prior to the update invocation and the call of the given Callable (but this relationship seems to exist in the implementation because GameTaskQueue uses a ConcurrentLinkedQueue) so you have to enforce an HB for the values created in the EDT and passed to the JME-Thread.

Thank you so much for SimplePassCanvasImpl hint. I didn't know this. class. I'll look for it…



Regards,

Equilibrium

Be careful, i didn't meant to say that SimplePassCanvasImpl enforces everything to run inside the edt.



Maybe it is just a side effect of the way i use the jme api and it can be wrong. What i do is simply pack stuff.



The Canvas3D (in the project it is not a standalone class but there's no difference) is something like this:


package it.tukano.jupiter.test;

import com.jme.input.KeyInput;
import com.jme.renderer.Camera;
import com.jme.scene.Node;
import com.jme.system.DisplaySystem;
import com.jme.system.canvas.CanvasConstructor;
import com.jme.system.canvas.JMECanvas;
import com.jme.system.canvas.SimplePassCanvasImpl;
import com.jme.system.lwjgl.LWJGLSystemProvider;
import com.jme.util.GameTaskQueueManager;
import com.jmex.awt.input.AWTMouseInput;
import com.jmex.awt.lwjgl.LWJGLAWTCanvasConstructor;
import java.awt.Canvas;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyListener;
import java.util.concurrent.Callable;
import javax.swing.JPanel;

public class Canvas3D extends JPanel {
    private final String DISPLAY_SYSTEM_ID = LWJGLSystemProvider.LWJGL_SYSTEM_IDENTIFIER;
    private final Class<? extends CanvasConstructor> CANVAS_CONSTRUCTOR_CLASS = LWJGLAWTCanvasConstructor.class;
    private SimplePassCanvasImpl CANVAS_IMPL;
    private JMECanvas canvas;
    private final int MIN_WIDTH = 64;
    private final int MIN_HEIGHT = 64;

    public Canvas3D() {
        super(new GridLayout(1, 1));
    }

    public void addNotify() {
        super.addNotify();
        initializeJME();
    }

    public Camera getCamera() {
        return CANVAS_IMPL.getCamera();
    }

    public Node getSceneRoot() {
        return CANVAS_IMPL.getRootNode();
    }

    public int getWidth() {
        return Math.max(super.getWidth(), MIN_WIDTH);
    }

    public int getHeight() {
        return Math.max(super.getHeight(), MIN_HEIGHT);
    }

    private void initializeJME() {
        CANVAS_IMPL = new SimplePassCanvasImpl(getWidth(), getHeight()) {};
        KeyInput.setProvider(KeyInput.INPUT_AWT);
        DisplaySystem display = DisplaySystem.getDisplaySystem(DISPLAY_SYSTEM_ID);
        display.registerCanvasConstructor("AWT", CANVAS_CONSTRUCTOR_CLASS);
        canvas = display.createCanvas(getWidth(), getHeight());
        canvas.setUpdateInput(true);
        canvas.setTargetRate(15);
        final Canvas awtCanvas = (Canvas) canvas;
        awtCanvas.setPreferredSize(new Dimension(getWidth(), getHeight()));
        awtCanvas.addComponentListener(new ComponentAdapter() {

            @Override
            public void componentResized(ComponentEvent e) {
                Component component = e.getComponent();
                CANVAS_IMPL.resizeCanvas(getWidth(), getHeight());
                updateCameraPerspective();
            }
        });

        KeyListener kl = (KeyListener) KeyInput.get();
        awtCanvas.addKeyListener(kl);
        AWTMouseInput.setup(awtCanvas, false);
        canvas.setImplementor(CANVAS_IMPL);
        add(awtCanvas);
    }

    private void updateCameraPerspective() {
        final float RATIO = (float) getWidth() / (float) getHeight();
        GameTaskQueueManager.getManager().update(new Callable<Void>() {

            public Void call() {
                System.out.println("IS THIS THE EDT? " + java.awt.EventQueue.isDispatchThread());
                if(getCamera() != null) {
                    getCamera().setFrustumPerspective(45.0f, RATIO, 1, 250);
                    getCamera().update();
                }
                return null;
            }
        });
    }
}



This is a simple test class:

package it.tukano.jupiter.test;

import javax.swing.JFrame;

public class TestCanvas3D {

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                Canvas3D canvas = new Canvas3D();
                JFrame window = new JFrame("Canvas3D Test");
                window.add(canvas);
                window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                window.setSize(640, 480);
                window.setVisible(true);
            }
        });
    }
}

No. Everything is ok and works fine. thanks a lot for the hint.