mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-12 22:26:56 -04:00
Fix[controls] 1.13+ sticky keys (#4210)
* Fix[controls] 1.13+ sticky keys * Fix[controls]: missing setup phase * Refactor: Use size_t instead of unsigned * Refactor: use size_t instead of unsigned
This commit is contained in:
parent
baeea2916e
commit
7916166795
@ -9,6 +9,9 @@
|
||||
#include <stdatomic.h>
|
||||
#include <jni.h>
|
||||
|
||||
/* How many events can be handled at the same time */
|
||||
#define EVENT_WINDOW_SIZE 8000
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
int i1;
|
||||
@ -32,8 +35,12 @@ struct pojav_environ_s {
|
||||
render_window_t* mainWindowBundle;
|
||||
int config_renderer;
|
||||
bool force_vsync;
|
||||
atomic_size_t eventCounter;
|
||||
GLFWInputEvent events[8000];
|
||||
atomic_size_t eventCounter; // Count the number of events to be pumped out
|
||||
GLFWInputEvent events[EVENT_WINDOW_SIZE];
|
||||
size_t outEventIndex; // Point to the current event that has yet to be pumped out to MC
|
||||
size_t outTargetIndex; // Point to the newt index to stop by
|
||||
size_t inEventIndex; // Point to the next event that has to be filled
|
||||
size_t inEventCount; // Count registered right before pumping OUT events. Used as a cache.
|
||||
double cursorX, cursorY, cLastX, cLastY;
|
||||
jmethodID method_accessAndroidClipboard;
|
||||
jmethodID method_onGrabStateChanged;
|
||||
|
@ -100,10 +100,13 @@ void pojavPumpEvents(void* window) {
|
||||
// prevent further calls until we exit the loop
|
||||
// by spec, they will be called on the same thread so no synchronization here
|
||||
pojav_environ->isPumpingEvents = true;
|
||||
size_t counter = atomic_load_explicit(&pojav_environ->eventCounter, memory_order_acquire);
|
||||
for(size_t i = 0; i < counter; i++) {
|
||||
GLFWInputEvent event = pojav_environ->events[i];
|
||||
switch(event.type) {
|
||||
|
||||
size_t index = pojav_environ->outEventIndex;
|
||||
size_t targetIndex = pojav_environ->outTargetIndex;
|
||||
|
||||
while (targetIndex != index) {
|
||||
GLFWInputEvent event = pojav_environ->events[index];
|
||||
switch (event.type) {
|
||||
case EVENT_TYPE_CHAR:
|
||||
if(pojav_environ->GLFW_invoke_Char) pojav_environ->GLFW_invoke_Char(window, event.i1);
|
||||
break;
|
||||
@ -128,17 +131,41 @@ void pojavPumpEvents(void* window) {
|
||||
if(pojav_environ->GLFW_invoke_WindowSize) pojav_environ->GLFW_invoke_WindowSize(window, event.i1, event.i2);
|
||||
break;
|
||||
}
|
||||
|
||||
index++;
|
||||
if (index >= EVENT_WINDOW_SIZE)
|
||||
index -= EVENT_WINDOW_SIZE;
|
||||
}
|
||||
if((pojav_environ->cLastX != pojav_environ->cursorX || pojav_environ->cLastY != pojav_environ->cursorY) && pojav_environ->GLFW_invoke_CursorPos) {
|
||||
pojav_environ->cLastX = pojav_environ->cursorX;
|
||||
pojav_environ->cLastY = pojav_environ->cursorY;
|
||||
pojav_environ->GLFW_invoke_CursorPos(window, pojav_environ->cursorX, pojav_environ->cursorY);
|
||||
}
|
||||
atomic_store_explicit(&pojav_environ->eventCounter, counter, memory_order_release);
|
||||
|
||||
// The out target index is updated by the rewinder
|
||||
pojav_environ->isPumpingEvents = false;
|
||||
}
|
||||
|
||||
/** Setup the amount of event that will get pumped into each window */
|
||||
void pojavComputeEventTarget() {
|
||||
size_t counter = atomic_load_explicit(&pojav_environ->eventCounter, memory_order_acquire);
|
||||
size_t index = pojav_environ->outEventIndex;
|
||||
|
||||
unsigned targetIndex = index + counter;
|
||||
if (targetIndex >= EVENT_WINDOW_SIZE)
|
||||
targetIndex -= EVENT_WINDOW_SIZE;
|
||||
|
||||
// Only accessed by one unique thread, no need for atomic store
|
||||
pojav_environ->inEventCount = counter;
|
||||
pojav_environ->outTargetIndex = targetIndex;
|
||||
}
|
||||
|
||||
/** Apply index offsets after events have been pumped */
|
||||
void pojavRewindEvents() {
|
||||
atomic_store_explicit(&pojav_environ->eventCounter, 0, memory_order_release);
|
||||
pojav_environ->outEventIndex = pojav_environ->outTargetIndex;
|
||||
|
||||
// New events may have arrived while pumping, so remove only the difference before the start and end of execution
|
||||
atomic_fetch_sub_explicit(&pojav_environ->eventCounter, pojav_environ->inEventCount, memory_order_acquire);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
@ -175,16 +202,17 @@ Java_org_lwjgl_glfw_GLFW_glfwSetCursorPos(__attribute__((unused)) JNIEnv *env, _
|
||||
|
||||
|
||||
void sendData(int type, int i1, int i2, int i3, int i4) {
|
||||
size_t counter = atomic_load_explicit(&pojav_environ->eventCounter, memory_order_acquire);
|
||||
if (counter < 7999) {
|
||||
GLFWInputEvent *event = &pojav_environ->events[counter++];
|
||||
event->type = type;
|
||||
event->i1 = i1;
|
||||
event->i2 = i2;
|
||||
event->i3 = i3;
|
||||
event->i4 = i4;
|
||||
}
|
||||
atomic_store_explicit(&pojav_environ->eventCounter, counter, memory_order_release);
|
||||
GLFWInputEvent *event = &pojav_environ->events[pojav_environ->inEventIndex];
|
||||
event->type = type;
|
||||
event->i1 = i1;
|
||||
event->i2 = i2;
|
||||
event->i3 = i3;
|
||||
event->i4 = i4;
|
||||
|
||||
if (++pojav_environ->inEventIndex >= EVENT_WINDOW_SIZE)
|
||||
pojav_environ->inEventIndex -= EVENT_WINDOW_SIZE;
|
||||
|
||||
atomic_fetch_add_explicit(&pojav_environ->eventCounter, 1, memory_order_acquire);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -617,7 +617,8 @@ public class GLFW
|
||||
SwapBuffers = apiGetFunctionAddress(GLFW, "pojavSwapBuffers"),
|
||||
SwapInterval = apiGetFunctionAddress(GLFW, "pojavSwapInterval"),
|
||||
PumpEvents = apiGetFunctionAddress(GLFW, "pojavPumpEvents"),
|
||||
RewindEvents = apiGetFunctionAddress(GLFW, "pojavRewindEvents");
|
||||
RewindEvents = apiGetFunctionAddress(GLFW, "pojavRewindEvents"),
|
||||
SetupEvents = apiGetFunctionAddress(GLFW, "pojavComputeEventTarget");
|
||||
}
|
||||
|
||||
public static SharedLibrary getLibrary() {
|
||||
@ -1058,7 +1059,7 @@ public class GLFW
|
||||
mGLFWIsInputReady = true;
|
||||
CallbackBridge.nativeSetInputReady(true);
|
||||
}
|
||||
|
||||
callV(Functions.SetupEvents);
|
||||
for (Long ptr : mGLFWWindowMap.keySet()) callJV(ptr, Functions.PumpEvents);
|
||||
callV(Functions.RewindEvents);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user