Finished Input Devices

This commit is contained in:
Speiger 2024-05-17 18:46:56 +02:00
parent 52fcac6fe9
commit 61d48be579
9 changed files with 125 additions and 9 deletions

View File

@ -2,13 +2,18 @@ package speiger.src.coreengine;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import speiger.src.coreengine.rendering.input.devices.FileDrop;
import speiger.src.coreengine.rendering.input.devices.Joystick; import speiger.src.coreengine.rendering.input.devices.Joystick;
import speiger.src.coreengine.rendering.input.devices.Joystick.ButtonData; import speiger.src.coreengine.rendering.input.devices.Keyboard;
import speiger.src.coreengine.rendering.input.devices.Mouse;
import speiger.src.coreengine.rendering.input.window.Window;
import speiger.src.coreengine.rendering.input.window.WindowManager;
import speiger.src.coreengine.utils.eventbus.EventBus; import speiger.src.coreengine.utils.eventbus.EventBus;
public class NewInputTest { public class NewInputTest {
EventBus bus = new EventBus(); EventBus bus = new EventBus();
WindowManager manager = new WindowManager();
public static void main(String[] args) { public static void main(String[] args) {
new NewInputTest().run(); new NewInputTest().run();
@ -16,10 +21,21 @@ public class NewInputTest {
public void run() { public void run() {
GLFW.glfwInit(); GLFW.glfwInit();
Joystick.INSTANCE.init(bus); manager.initialize();
ButtonData data = new ButtonData(); Mouse.INSTANCE.init(bus);
Keyboard.INSTANCE.init(bus);
Joystick.INSTANCE.init(manager, bus);
FileDrop.INSTANCE.init(bus);
manager.addDevices(Mouse.INSTANCE, Keyboard.INSTANCE, Joystick.INSTANCE, FileDrop.INSTANCE);
Window window = manager.builder().title("Testing Engine").build();
window.visible(true);
//TODO implement window close requests
while(true) { while(true) {
Joystick.INSTANCE.handleJoystick(0, GLFW.GLFW_JOYSTICK_1, data); GLFW.glfwPollEvents();
window.update();
window.handleInput();
window.finishFrame();
try { try {
Thread.sleep(100); Thread.sleep(100);
} }

View File

@ -0,0 +1,47 @@
package speiger.src.coreengine.rendering.input.devices;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWDropCallback;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.input.devices.FileDrop.DropTask;
import speiger.src.coreengine.rendering.input.events.FileEvents;
import speiger.src.coreengine.rendering.input.window.Window;
public class FileDrop extends AbstractDevice<Void, DropTask> {
public static final FileDrop INSTANCE = new FileDrop();
@Override
protected void registerCallbacks(Window window) {
super.registerCallbacks(window);
window.addCallback(this::drop, GLFW::glfwSetDropCallback);
}
private void drop(long windowId, int count, long names) {
List<Path> paths = new ObjectArrayList<>();
for(int i = 0;i<count;i++) {
Path path = Path.of(GLFWDropCallback.getName(names, i));
if(Files.notExists(path)) continue;
paths.add(path);
}
if(paths.isEmpty()) return;
push(windowId, new DropTask(windowId, paths.toArray(Path[]::new)));
}
@Override
public void reset(long windowId) {}
@Override
protected Void createData(long windowId) { return null; }
@Override
protected void process(DropTask task) {
int x = Mouse.INSTANCE.x(task.windowId());
int y = Mouse.INSTANCE.y(task.windowId());
pushEvent(new FileEvents.Drop(task.windowId(), x, y, task.files()));
}
public record DropTask(long windowId, Path[] files) {}
}

View File

@ -11,6 +11,7 @@ import speiger.src.coreengine.rendering.input.events.KeyEvent.Key;
import speiger.src.coreengine.rendering.input.window.Window; import speiger.src.coreengine.rendering.input.window.Window;
public class Keyboard extends AbstractDevice<KeyData, KeyTask> { public class Keyboard extends AbstractDevice<KeyData, KeyTask> {
public static final Keyboard INSTANCE = new Keyboard();
@Override @Override
public void reset(long windowId) {} public void reset(long windowId) {}
@Override @Override

View File

@ -59,12 +59,12 @@ public class Mouse extends AbstractDevice<MouseData, MouseTask> {
public int x(long windowId) { public int x(long windowId) {
MouseData data = get(windowId); MouseData data = get(windowId);
return data == null ? 0 : data.position.x(); return data == null ? 0 : data.x();
} }
public int y(long windowId) { public int y(long windowId) {
MouseData data = get(windowId); MouseData data = get(windowId);
return data == null ? 0 : data.position.y(); return data == null ? 0 : data.y();
} }
public boolean pressed(long windowId, int button) { public boolean pressed(long windowId, int button) {

View File

@ -0,0 +1,28 @@
package speiger.src.coreengine.rendering.input.events;
import java.nio.file.Path;
public class FileEvents {
public static class Drop extends MouseEvent {
Path[] files;
String[] extension;
String[] name;
public Drop(long window, int x, int y, Path[] files) {
super(window, x, y);
this.files = files;
this.extension = new String[files.length];
this.name = new String[files.length];
for(int i = 0,m=files.length;i<m;i++) {
String name = files[i].getFileName().toString();
this.name[i] = name;
this.extension[i] = name.substring(name.lastIndexOf(".")+1);
}
}
public int size() { return files.length; }
public Path file(int index) { return files[index]; }
public String extension(int index) { return extension[index]; }
public String name(int index) { return name[index]; }
}
}

View File

@ -28,6 +28,8 @@ public abstract class MouseEvent extends Event {
y = originY; y = originY;
} }
//TODO implement support for Scaling
@Override @Override
public boolean isCancelable() { return true; } public boolean isCancelable() { return true; }
public boolean isForced() { return false; } public boolean isForced() { return false; }

View File

@ -142,6 +142,10 @@ public class Window {
if(flags.isFlagSet(WINDOW_CHANGE)) updateViewport(); if(flags.isFlagSet(WINDOW_CHANGE)) updateViewport();
} }
public void handleInput() {
manager.processDevices(id);
}
public void finishFrame() { public void finishFrame() {
GLFW.glfwSwapBuffers(id); GLFW.glfwSwapBuffers(id);
} }

View File

@ -38,7 +38,13 @@ public class WindowManager {
public WindowBuilder builder() { return new WindowBuilder(this); } public WindowBuilder builder() { return new WindowBuilder(this); }
private Window create(WindowBuilder builder) { return new Window(builder); } private Window create(WindowBuilder builder) { return new Window(builder); }
public void addDevice(InputDevice device) { devices.add(device); } public void addDevices(InputDevice...devices) {
for(InputDevice device : devices) addDevice(device);
}
public void addDevice(InputDevice device) {
devices.add(device);
windows.values().forEach(device::register);
}
public void removeDevice(InputDevice device) { devices.remove(device); } public void removeDevice(InputDevice device) { devices.remove(device); }
public void processDevices(long windowId) { public void processDevices(long windowId) {
for(int i = 0,m=devices.size();i<m;i++) { for(int i = 0,m=devices.size();i<m;i++) {
@ -62,6 +68,9 @@ public class WindowManager {
void addWindow(Window window) { void addWindow(Window window) {
windows.put(window.id(), window); windows.put(window.id(), window);
for(int i = 0,m=devices.size();i<m;i++) {
devices.get(i).register(window);
}
} }
void updateWindow(long oldId) { void updateWindow(long oldId) {
@ -75,6 +84,14 @@ public class WindowManager {
else if(activeWindow == window) activeWindow = null; else if(activeWindow == window) activeWindow = null;
} }
void updateInputs(long windowId) {
for(int i = 0,m=devices.size();i<m;i++) {
InputDevice device = devices.get(i);
device.reset(windowId);
device.processInput(windowId);
}
}
public void destroy() { public void destroy() {
callbacks.forEach(WindowCallback::destroy); callbacks.forEach(WindowCallback::destroy);
callbacks.clear(); callbacks.clear();

View File

@ -5,19 +5,19 @@ import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodHandles.Lookup;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import speiger.src.collections.objects.lists.ObjectArrayList; import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.maps.impl.concurrent.Object2ObjectConcurrentOpenHashMap; import speiger.src.collections.objects.maps.impl.concurrent.Object2ObjectConcurrentOpenHashMap;
import speiger.src.collections.objects.maps.impl.hash.Object2ObjectOpenHashMap;
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap; import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap;
import speiger.src.collections.objects.utils.ObjectLists; import speiger.src.collections.objects.utils.ObjectLists;
public class EventBus public class EventBus
{ {
private static final Lookup LOOKUP = MethodHandles.lookup(); private static final Lookup LOOKUP = MethodHandles.lookup();
Map<Class<? extends Event>, Listeners> listeners = new ConcurrentHashMap<>(); Map<Class<? extends Event>, Listeners> listeners = new Object2ObjectOpenHashMap<Class<? extends Event>, Listeners>().synchronize();
Object2ObjectMap<Object, List<EventListener>> instances = new Object2ObjectConcurrentOpenHashMap<>(); Object2ObjectMap<Object, List<EventListener>> instances = new Object2ObjectConcurrentOpenHashMap<>();
public <T extends Event> void register(Class<T> event, Consumer<T> listener) { public <T extends Event> void register(Class<T> event, Consumer<T> listener) {
@ -86,6 +86,7 @@ public class EventBus
public void post(Event event) { public void post(Event event) {
Consumer<Event>[] listeners = getListeners(event.getClass()).getListeners(); Consumer<Event>[] listeners = getListeners(event.getClass()).getListeners();
System.out.println("Event: "+event);
if(listeners.length <= 0) return; if(listeners.length <= 0) return;
int index = 0; int index = 0;
try { try {