Mouse Device Implemented

This commit is contained in:
Speiger 2024-05-16 21:26:49 +02:00
parent d7fbc6e93b
commit 5540f1c042
5 changed files with 165 additions and 27 deletions

View File

@ -43,8 +43,9 @@ public abstract class AbstractDevice<T, E> implements InputDevice {
protected abstract T createData(long windowId);
protected abstract void process(E task);
protected void pushEvent(Event event) {
protected boolean pushEvent(Event event) {
bus.post(event);
return event.isCancelable() && event.isCanceled();
}
protected void push(long windowId, E task) {
@ -63,7 +64,7 @@ public abstract class AbstractDevice<T, E> implements InputDevice {
}
}
protected T getData(long windowId) {
public T get(long windowId) {
return windowData.get(windowId);
}
}

View File

@ -5,4 +5,5 @@ import speiger.src.coreengine.rendering.input.window.Window;
public interface InputDevice {
public void register(Window window);
public void processInput(long windowId);
public void reset(long windowId);
}

View File

@ -7,12 +7,16 @@ import speiger.src.collections.ints.sets.IntSet;
import speiger.src.coreengine.math.vector.ints.Vec2i;
import speiger.src.coreengine.rendering.input.divices.Mouse.MouseData;
import speiger.src.coreengine.rendering.input.divices.Mouse.MouseTask;
import speiger.src.coreengine.rendering.input.events.MouseEvent;
import speiger.src.coreengine.rendering.input.window.Window;
public class Mouse extends AbstractDevice<MouseData, MouseTask> {
public static final Mouse INSTANCE = new Mouse();
@Override
protected MouseData createData(long windowId) { return new MouseData(); }
@Override
public void reset(long windowId) { get(windowId).reset(); }
protected void process(MouseTask task) { task.process(this); }
@Override
@ -43,9 +47,46 @@ public class Mouse extends AbstractDevice<MouseData, MouseTask> {
public static class MouseData {
IntSet buttons = new IntOpenHashSet();
Vec2i position = Vec2i.mutable();
Vec2i movement = Vec2i.mutable();
Vec2i motion = Vec2i.mutable();
Vec2i scroll = Vec2i.mutable();
boolean active = true;
void reset() {
motion.negate();
position.negate();
scroll.negate();
}
public int x() { return position.x(); }
public int y() { return position.y(); }
public boolean pressed(int button) { return buttons.contains(button); }
public Vec2i motion() { return motion; }
public Vec2i scroll() { return scroll; }
}
public int x(long windowId) {
MouseData data = get(windowId);
return data == null ? 0 : data.position.x();
}
public int y(long windowId) {
MouseData data = get(windowId);
return data == null ? 0 : data.position.y();
}
public boolean pressed(long windowId, int button) {
MouseData data = get(windowId);
return data != null && data.pressed(button);
}
public Vec2i motion(long windowId) {
MouseData data = get(windowId);
return data == null ? Vec2i.ZERO : data.motion();
}
public Vec2i scroll(long windowId) {
MouseData data = get(windowId);
return data == null ? Vec2i.ZERO : data.scroll();
}
public interface MouseTask {
@ -55,48 +96,47 @@ public class Mouse extends AbstractDevice<MouseData, MouseTask> {
private record Move(long window, double x, double y) implements MouseTask {
@Override
public void process(Mouse mouse) {
MouseData data = mouse.getData(window);
MouseData data = mouse.get(window);
int xOff = (int)(x - data.position.x());
int yOff = (int)(y - data.position.y());
data.position.set((int)x, (int)y);
//TODO Post event!
if(!mouse.pushEvent(new MouseEvent.Move(window, (int)x, (int)y, xOff, yOff))) {
data.motion.add(xOff, yOff);
}
}
}
}
private record Click(long window, int button, int action, int mods) implements MouseTask {
@Override
public void process(Mouse mouse) {
MouseData data = mouse.getData(window);
MouseData data = mouse.get(window);
if(action == GLFW.GLFW_PRESS) data.buttons.add(action);
else if(action == GLFW.GLFW_RELEASE) data.buttons.remove(action);
//TODO post event
mouse.pushEvent(new MouseEvent.Click(window, data.position.x(), data.position.y(), button, action == GLFW.GLFW_PRESS));
}
}
}
private record Scroll(long window, double xoffset, double yoffset) implements MouseTask {
private record Scroll(long window, double x, double y) implements MouseTask {
@Override
public void process(Mouse mouse) {
//TODO post event
MouseData data = mouse.get(window);
if(!mouse.pushEvent(new MouseEvent.Scroll(window, data.position.x(), data.position.y(), (int)x, (int)y))) {
data.scroll.add((int)x, (int)y);
}
}
}
}
private record Enter(long window, boolean enter) implements MouseTask {
@Override
public void process(Mouse mouse) {
MouseData data = mouse.getData(window);
MouseData data = mouse.get(window);
data.active = enter;
if(!enter) {
//TODO decide if this should also push phantom events clearing the pressed keys?
data.buttons.clear();
data.movement.negate();
data.position.negate();
data.scroll.negate();
data.reset();
}
}
}
}

View File

@ -0,0 +1,78 @@
package speiger.src.coreengine.rendering.input.events;
import speiger.src.coreengine.utils.eventbus.Event;
public abstract class MouseEvent extends Event {
final long window;
int x;
int y;
final int originX;
final int originY;
public MouseEvent(long window, int x, int y) {
this.window = window;
this.originX = this.x = x;
this.originY = this.y = y;
}
public long windowId() { return window; }
public int x() { return x; }
public void x(int x) { this.x = x; }
public int y() { return y; }
public void y(int y) { this.y = y; }
public int originX() { return originX; }
public int originY() { return originY; }
public void reset() {
x = originX;
y = originY;
}
@Override
public boolean isCancelable() { return true; }
public boolean isForced() { return false; }
public static class Click extends MouseEvent {
final int button;
final boolean press;
public Click(long window, int x, int y, int button, boolean press) {
super(window, x, y);
this.button = button;
this.press = press;
}
@Override
public boolean isForced() { return !press; }
public int button() { return button; }
public boolean press() { return press; }
}
public static class Move extends MouseEvent {
final int xMove;
final int yMove;
public Move(long window, int x, int y, int xMove, int yMove) {
super(window, x, y);
this.xMove = xMove;
this.yMove = yMove;
}
public int xMove() { return xMove; }
public int yMove() { return yMove; }
}
public static class Scroll extends MouseEvent {
final int scrollX;
final int scrollY;
public Scroll(long window, int x, int y, int scrollX, int scrollY) {
super(window, x, y);
this.scrollX = scrollX;
this.scrollY = scrollY;
}
public int scrollX() { return scrollX; }
public int scrollY() { return scrollY; }
}
}

View File

@ -1,5 +1,6 @@
package speiger.src.coreengine.rendering.input.window;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
@ -8,6 +9,8 @@ import org.lwjgl.system.Callback;
import speiger.src.collections.longs.maps.impl.concurrent.Long2ObjectConcurrentOpenHashMap;
import speiger.src.collections.longs.maps.interfaces.Long2ObjectMap;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.input.divices.InputDevice;
public class WindowManager {
Long2ObjectMap<Monitor> monitors;
@ -15,6 +18,7 @@ public class WindowManager {
Window activeWindow;
Window primaryWindow;
Callback monitorTracker;
List<InputDevice> devices = new ObjectArrayList<>();
public void initialize() {
monitors = Monitor.createMonitors();
@ -34,6 +38,20 @@ public class WindowManager {
return new Window(builder);
}
public void addDevice(InputDevice device) {
devices.add(device);
}
public void processDevices(long windowId) {
for(int i = 0,m=devices.size();i<m;i++) {
devices.get(i).processInput(windowId);
}
}
public void removeDevice(InputDevice device) {
devices.remove(device);
}
void addWindow(Window window) {
windows.put(window.id(), window);
}