Added ThreadSensitive, InputBus cleanup

This commit is contained in:
493msi 2020-09-24 02:34:33 +02:00
parent 9c06c47ffc
commit 93ef85f804
7 changed files with 106 additions and 84 deletions

View File

@ -13,6 +13,9 @@
* Renamed `VertexArray#getVertexAttribs` to `VertexArray#getVertexAttributes`
* `[PlutoCore]` Made `PlutoApplication.StartupConfig` fields private, options
can now only be modified only through public setters
* `[PlutoLib]` Added the `ThreadSensitive` annotation
* `[PlutoCore]` Refactored `InputBus` and added several convenience methods
* `[PlutoCore]` Refactored input callbacks
## 20.2.0.0-alpha.1
* `[PlutoLib#cz.tefek.pluto.io.logger]` Refactored the Logger subsystem

View File

@ -2,156 +2,157 @@ package cz.tefek.pluto.engine.input;
import org.lwjgl.glfw.GLFW;
import javax.annotation.concurrent.ThreadSafe;
import cz.tefek.pluto.annotation.ThreadSensitive;
import cz.tefek.pluto.engine.display.Display;
@ThreadSafe
@ThreadSensitive(localContexts = true)
public class InputBus
{
private static ThreadLocal<KeyboardInputCallback> keyboard = new ThreadLocal<>();
private static ThreadLocal<MouseButtonCallback> mouseButton = new ThreadLocal<>();
private static ThreadLocal<CursorPositionCallback> cursorPosition = new ThreadLocal<>();
private static ThreadLocal<ScrollInputCallback> scroll = new ThreadLocal<>();
private static ThreadLocal<KeyboardCharInput> charInput = new ThreadLocal<>();
private static final ThreadLocal<InputBus> INSTANCE = new ThreadLocal<>();
private final KeyboardInputCallback keyboard = new KeyboardInputCallback();
private final MouseButtonCallback mouseButton = new MouseButtonCallback();
private final CursorPositionCallback cursorPosition = new CursorPositionCallback();
private final ScrollInputCallback scroll = new ScrollInputCallback();
private final KeyboardCharInput charInput = new KeyboardCharInput();
private InputBus()
{
}
public static void init(Display display)
{
keyboard.set(new KeyboardInputCallback());
GLFW.glfwSetKeyCallback(display.getWindowPointer(), keyboard.get());
mouseButton.set(new MouseButtonCallback());
GLFW.glfwSetMouseButtonCallback(display.getWindowPointer(), mouseButton.get());
cursorPosition.set(new CursorPositionCallback());
GLFW.glfwSetCursorPosCallback(display.getWindowPointer(), cursorPosition.get());
scroll.set(new ScrollInputCallback());
GLFW.glfwSetScrollCallback(display.getWindowPointer(), scroll.get());
charInput.set(new KeyboardCharInput());
GLFW.glfwSetCharCallback(display.getWindowPointer(), charInput.get());
var instance = new InputBus();
GLFW.glfwSetKeyCallback(display.getWindowPointer(), instance.keyboard);
GLFW.glfwSetMouseButtonCallback(display.getWindowPointer(), instance.mouseButton);
GLFW.glfwSetCursorPosCallback(display.getWindowPointer(), instance.cursorPosition);
GLFW.glfwSetScrollCallback(display.getWindowPointer(), instance.scroll);
GLFW.glfwSetCharCallback(display.getWindowPointer(), instance.charInput);
}
public static void destroy()
{
scroll.get().free();
scroll.remove();
var instance = INSTANCE.get();
mouseButton.get().free();
mouseButton.remove();
keyboard.get().free();
keyboard.remove();
cursorPosition.get().free();
cursorPosition.remove();
charInput.get().free();
charInput.remove();
instance.scroll.free();
instance.mouseButton.free();
instance.keyboard.free();
instance.cursorPosition.free();
instance.charInput.free();
}
public static KeyboardInputCallback keyboard()
{
return keyboard.get();
return INSTANCE.get().keyboard;
}
public static MouseButtonCallback mouseButtons()
{
return mouseButton.get();
return INSTANCE.get().mouseButton;
}
public static ScrollInputCallback scroll()
{
return scroll.get();
return INSTANCE.get().scroll;
}
public static CursorPositionCallback cursorPosition()
{
return cursorPosition.get();
return INSTANCE.get().cursorPosition;
}
public static KeyboardCharInput charInput()
{
return INSTANCE.get().charInput;
}
public static void resetStates()
{
keyboard.get().resetPressed();
mouseButton.get().reset();
scroll.get().reset();
cursorPosition.get().reset();
charInput.get().reset();
var instance = INSTANCE.get();
instance.keyboard.resetPressed();
instance.mouseButton.reset();
instance.scroll.reset();
instance.cursorPosition.reset();
instance.charInput.reset();
}
@ThreadSensitive(localContexts = true)
public static class Mouse
{
public static boolean clicked(int button)
{
var mb = mouseButton.get();
return mb.buttonClicked[button];
return INSTANCE.get().mouseButton.buttonClicked[button];
}
public static boolean released(int button)
{
var mb = mouseButton.get();
return mb.buttonReleased[button];
return INSTANCE.get().mouseButton.buttonReleased[button];
}
public static boolean isButtonDown(int button)
{
var mb = mouseButton.get();
return mb.buttonDown[button];
return INSTANCE.get().mouseButton.buttonDown[button];
}
public static double getX()
{
return cursorPosition.get().getX();
return INSTANCE.get().cursorPosition.getX();
}
public static double getY()
{
return cursorPosition.get().getY();
return INSTANCE.get().cursorPosition.getY();
}
public static boolean isInside(int x1, int y1, int x2, int y2)
{
return INSTANCE.get().cursorPosition.isInside(x1, y1, x2, y2);
}
public static double getDX()
{
return cursorPosition.get().getDeltaX();
return INSTANCE.get().cursorPosition.getDeltaX();
}
public static double getDY()
{
return cursorPosition.get().getDeltaY();
return INSTANCE.get().cursorPosition.getDeltaY();
}
public static double getScrollX()
{
return scroll.get().getXScroll();
return INSTANCE.get().scroll.getXScroll();
}
public static double getScrollY()
{
return scroll.get().getYScroll();
return INSTANCE.get().scroll.getYScroll();
}
}
@ThreadSensitive(localContexts = true)
public static class Keyboard
{
public static boolean pressed(int key)
{
return keyboard.get().hasBeenPressed(key);
return INSTANCE.get().keyboard.hasBeenPressed(key);
}
public static boolean released(int key)
{
return keyboard.get().hasBeenReleased(key);
return INSTANCE.get().keyboard.hasBeenReleased(key);
}
public static boolean isKeyDown(int key)
{
return keyboard.get().isKeyDown(key);
return INSTANCE.get().keyboard.isKeyDown(key);
}
public static String getTypedText()
{
return charInput.get().getTypedText();
return INSTANCE.get().charInput.getTypedText();
}
}
}

View File

@ -4,7 +4,7 @@ import org.lwjgl.glfw.GLFWCharCallback;
public class KeyboardCharInput extends GLFWCharCallback
{
private StringBuilder typedText = new StringBuilder();
private final StringBuilder typedText = new StringBuilder();
@Override
public void invoke(long window, int codepoint)

View File

@ -1,16 +1,16 @@
package cz.tefek.pluto.engine.input;
import static org.lwjgl.glfw.GLFW.GLFW_PRESS;
import static org.lwjgl.glfw.GLFW.GLFW_RELEASE;
import org.lwjgl.glfw.GLFWKeyCallback;
import java.util.HashSet;
import java.util.Set;
import org.lwjgl.glfw.GLFWKeyCallback;
import static org.lwjgl.glfw.GLFW.GLFW_PRESS;
import static org.lwjgl.glfw.GLFW.GLFW_RELEASE;
public class KeyboardInputCallback extends GLFWKeyCallback
{
private Set<Integer> keyPressed = new HashSet<>();
private final Set<Integer> keyPressed = new HashSet<>();
private Set<Integer> keyDown = new HashSet<>();
private Set<Integer> keyReleased = new HashSet<>();

View File

@ -3,6 +3,8 @@ package cz.tefek.pluto.engine.input;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWMouseButtonCallback;
import java.util.Arrays;
public class MouseButtonCallback extends GLFWMouseButtonCallback
{
public boolean[] buttonClicked = new boolean[32];
@ -19,15 +21,8 @@ public class MouseButtonCallback extends GLFWMouseButtonCallback
public void reset()
{
for (int i = 0; i < this.buttonClicked.length; i++)
{
this.buttonClicked[i] = false;
}
for (int i = 0; i < this.buttonClicked.length; i++)
{
this.buttonReleased[i] = false;
}
Arrays.fill(this.buttonClicked, false);
Arrays.fill(this.buttonReleased, false);
}
}

View File

@ -29,18 +29,8 @@ public class ScrollInputCallback extends GLFWScrollCallback
return yScroll;
}
public void setYScroll(double yScroll)
{
this.yScroll = yScroll;
}
public double getXScroll()
{
return xScroll;
}
public void setXScroll(double xScroll)
{
this.xScroll = xScroll;
}
}

View File

@ -0,0 +1,33 @@
package cz.tefek.pluto.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Marks a type as a thread-sensitive unit. Accesses from other threads
* other than the original one may result in undesirable behaviour (see below for exceptions).
* </p>
*
* <p>
* Types can opt in to set the {@link ThreadSensitive#localContexts} field to <tt>true</tt>,
* committing to support per-thread local contexts.
* </p>
*
* @author 493msi
*
* @since 20.2.0.0-alpha.2
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface ThreadSensitive
{
/**
* When <tt>true</tt>, the annotated type commits to support thread-local contexts.
*
* @since 20.2.0.0-alpha.2
* */
boolean localContexts() default false;
}