diff --git a/src/main/java/speiger/src/coreengine/rendering/input/divices/AbstractDevice.java b/src/main/java/speiger/src/coreengine/rendering/input/divices/AbstractDevice.java index 3bf83ef..03505f1 100644 --- a/src/main/java/speiger/src/coreengine/rendering/input/divices/AbstractDevice.java +++ b/src/main/java/speiger/src/coreengine/rendering/input/divices/AbstractDevice.java @@ -43,8 +43,9 @@ public abstract class AbstractDevice 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 implements InputDevice { } } - protected T getData(long windowId) { + public T get(long windowId) { return windowData.get(windowId); } } diff --git a/src/main/java/speiger/src/coreengine/rendering/input/divices/InputDevice.java b/src/main/java/speiger/src/coreengine/rendering/input/divices/InputDevice.java index 8608f92..1f490f7 100644 --- a/src/main/java/speiger/src/coreengine/rendering/input/divices/InputDevice.java +++ b/src/main/java/speiger/src/coreengine/rendering/input/divices/InputDevice.java @@ -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); } diff --git a/src/main/java/speiger/src/coreengine/rendering/input/divices/Mouse.java b/src/main/java/speiger/src/coreengine/rendering/input/divices/Mouse.java index 370fe4b..bb35e96 100644 --- a/src/main/java/speiger/src/coreengine/rendering/input/divices/Mouse.java +++ b/src/main/java/speiger/src/coreengine/rendering/input/divices/Mouse.java @@ -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 { + 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 { 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 { 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); - if(action == GLFW.GLFW_PRESS) data.buttons.add(action); - else if(action == GLFW.GLFW_RELEASE) data.buttons.remove(action); - //TODO post event - } - } - private record Scroll(long window, double xoffset, double yoffset) implements MouseTask { - + private record Click(long window, int button, int action, int mods) implements MouseTask { @Override public void process(Mouse mouse) { - //TODO post event + MouseData data = mouse.get(window); + if(action == GLFW.GLFW_PRESS) data.buttons.add(action); + else if(action == GLFW.GLFW_RELEASE) data.buttons.remove(action); + mouse.pushEvent(new MouseEvent.Click(window, data.position.x(), data.position.y(), button, action == GLFW.GLFW_PRESS)); } - } - private record Enter(long window, boolean enter) implements MouseTask { - + + private record Scroll(long window, double x, double y) implements MouseTask { @Override public void process(Mouse mouse) { - MouseData data = mouse.getData(window); + 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.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(); } } - } } \ No newline at end of file diff --git a/src/main/java/speiger/src/coreengine/rendering/input/events/MouseEvent.java b/src/main/java/speiger/src/coreengine/rendering/input/events/MouseEvent.java new file mode 100644 index 0000000..fdfd70a --- /dev/null +++ b/src/main/java/speiger/src/coreengine/rendering/input/events/MouseEvent.java @@ -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; } + } +} diff --git a/src/main/java/speiger/src/coreengine/rendering/input/window/WindowManager.java b/src/main/java/speiger/src/coreengine/rendering/input/window/WindowManager.java index 49843fe..5ccbaea 100644 --- a/src/main/java/speiger/src/coreengine/rendering/input/window/WindowManager.java +++ b/src/main/java/speiger/src/coreengine/rendering/input/window/WindowManager.java @@ -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 monitors; @@ -15,6 +18,7 @@ public class WindowManager { Window activeWindow; Window primaryWindow; Callback monitorTracker; + List 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