Listeners dont fire, controls dont update?

I just discovered that if you hold the mouse button down on the viewport frame (as if you were going to drag the window) that the game will basically pause until released.

I have a rotating cube that does continue its movement (i.e. releasing the mouse updates the cube to the position it would of rotated to) but if a character is moving it will not update the position until you release the mouse.

The update loops of controls do not update while mouse pressed on the frame.

If the window is out of focus it still updates to the correct position things would of been at while out of focus when focus is regained, as it should.

How do you prevent this behavior? Only rendering to the window should be stopped while mouse is pressed not the control updates right?

1 Like

You might try setting this to false:
http://javadoc.jmonkeyengine.org/com/jme3/app/Application.html#setPauseOnLostFocus-boolean-

1 Like

The update loops do work when out of focus, just not the rendering, as they should.

When out of focus, this setting does allow rendering for things like mouseover of a minimized game to run in the thumbnail and all my controls work properly whether or not setPauseOnFocus is disabled.

The simple control that merely rotates a cube does work as expected, which is it updates the position and doesn’t render, whether or not the setPauseOnFocus is disabled.

This still did not work for the other controls when the mouse button is kept pressed on the window frame though.

How can one update work and not the others? I can see how the animation update loop would not render but the movement and character controls should since there is nothing to render, they are pure data.

1 Like

Is this Windows or Linux? Is it set to allow updates on window movement or to freeze the window?

JME can’t do much if the OS is blocking the render… thus blocking the whole update loop.

1 Like

Character Controls might do something in ControlRender to be run After all Controls had the chance to set a velocity. You can Check that easily with the Source though

1 Like

Windows

I wasn’t aware of any setting that would allow me to stop this.

What I am reading is that window dragging is Modal so that why its happening.

I wrote a small test case but if its a setting on my side that only affects me it wont be of use.

1 Like

Everything works as expected with LostFocusBehavior.Disabled except window drag part.

1 Like

Used to be there was a setting in Windows to allow the window to continue painting while dragging. But my memory goes back as far as Windows NT 3.52 or whatever… so who knows when/if they stopped that.

1 Like

Yes there is a setting… hope you will find it although the screenshot is in german language…

1 Like

Well I had high hopes but that setting is already set.

From what I have read there is no solution except from within the program affected or the main solution,

The only way to solve this problem is the obvious one: don’t spend too long processing any one message.

ie, don’t hold the mouse down.

1 Like

Correction: “ie: don’t hold the mouse down on the title bar”

Correct?

1 Like

Yes, title bar.

1 Like

Do note: in a real game where model (as in MVC) and view have been properly separated then this shouldn’t matter, I guess.

I think things like Bullet still update correctly even if no frames are rendered. At least I’d hope so (else it’s broken).

1 Like

Ill be using client server so it should not be a problem, at least server side, unless they hold it to long and get booted because it looks like a dropped connection.[quote=“pspeed, post:13, topic:39003”]

I think things like Bullet still update correctly even if no frames are rendered. At least I’d hope so (else it’s broken).
[/quote]
This does happen for everything else like minimize, just not when pressing the title bar. I know the update loops and listeners don’t fire so I think the entire program is frozen until key release. It starts up right where it stopped processing input.

This is the test case I wrote. If you click-hold the title bar, program will freeze and when released the ball will restart from right where it stopped. At least for me it does.

package mygame;

import com.jme3.app.LostFocusBehavior;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.input.controls.ActionListener;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;

/**
 * This is the Main Class of your Game. You should only do initialization here.
 * Move your Logic into AppStates or Controls
 *
 * @author normenhansen
 */
public class Main extends SimpleApplication {

    private final float moveSpeed = 3f;

    public static void main(String[] args) {
        Main app = new Main();
        app.setLostFocusBehavior(LostFocusBehavior.Disabled);
        app.start();
    }

    @Override
    public void simpleInitApp() {
        BulletAppState bas = new BulletAppState();
        getStateManager().attach(bas);
        flyCam.setEnabled(false);

        Sphere sphere = new Sphere(32, 32, 1f);
        Geometry geom = new Geometry("Sphere", sphere);
        geom.setLocalTranslation(new Vector3f(-4f, .0f, 0f));
        Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat2.setColor("Color", ColorRGBA.Yellow);
        geom.setMaterial(mat2);
        geom.addControl(new SphereCharControl(1f, 2f, 1f));
        bas.getPhysicsSpace().add(geom);
        geom.addControl(new MoveSphereControl());
        geom.getControl(MoveSphereControl.class).moveTo(new Vector3f(4f, 0f, 0f));
        rootNode.attachChild(geom);

        Box boxMesh = new Box(10f, 0f, 10f);
        Geometry boxGeo = new Geometry("Box", boxMesh);
        boxGeo.setLocalTranslation(new Vector3f(0f, 0f, 0f));
        Material boxMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        boxMat.setColor("Color", ColorRGBA.Green);
        boxGeo.setMaterial(boxMat);
        boxGeo.addControl(new RigidBodyControl(0f));
        bas.getPhysicsSpace().add(boxGeo);
        rootNode.attachChild(boxGeo);
    }

    @Override
    public void simpleUpdate(float tpf) {
        //TODO: add update code
    }

    @Override
    public void simpleRender(RenderManager rm) {
        //TODO: add render code
    }

    private class SphereCharControl extends BetterCharacterControl implements ActionListener {

        private boolean forward;

        public SphereCharControl(float radius, float height, float mass) {
            super(radius, height, mass);
        }

        @Override
        public void update(float tpf) {
            super.update(tpf);
            Vector3f modelForwardDir = spatial.getWorldRotation().mult(Vector3f.UNIT_Z);
            walkDirection.set(0, 0, 0);
            if (forward) {
                walkDirection.addLocal(modelForwardDir.mult(moveSpeed));
            }
            setWalkDirection(walkDirection);
        }

        @Override
        public void onAction(String name, boolean isPressed, float tpf) {
            if (name.equals("MoveForward")) {
                forward = isPressed;
            }
        }
    }

    private class MoveSphereControl extends AbstractControl {

        private Vector3f target;

        @Override
        protected void controlUpdate(float tpf) {
            Vector3f spatialPosition = spatial.getWorldTranslation();
            Vector3f distance = spatialPosition.subtract(target);

            if (distance.length() > 1) {
                Vector3f direction = target.subtract(spatialPosition);
                direction.mult(tpf);
                spatial.getControl(SphereCharControl.class).setViewDirection(new Vector3f(direction).normalize());
                spatial.getControl(SphereCharControl.class).onAction("MoveForward", true, 1);
            } else {
                target.negateLocal();
                this.moveTo(target);
            }
        }

        @Override
        protected void controlRender(RenderManager rm, ViewPort vp) {

        }

        public void moveTo(Vector3f target) {
            this.target = target;
        }
    }

}
1 Like

It may have to do with how bullet is configured and how big of a time step gap is allowed. I think the bullet app state syncs to the main thread but runs on a separate thread… so it is lock-stepped.

A client server app with physics on the server might not have that issue. For example, the sim-eth examples should run just fine if you hold the title bar forever. There is (as far as I know) no blocking sync between the networking threads and the UI because the UI is purely view.

1 Like

Just out of curiosity, does Linux have this issue?

Im kicking windows to the curb for my next system.

1 Like

I’m about 99% sure the answer is no, but when I get off work I’ll test it on my Mint 18 system.[quote=“mitm, post:16, topic:39003”]
Im kicking windows to the curb for my next system.
[/quote]

Good move. :slight_smile:

1 Like