简体   繁体   中英

KeyJustDown implementation in emscripten using GLFW3

I want to implement KeyJustDown function which checks, if given key was just pressed down. Key was just pressed down, if it is down in the current state and was up in the previous state.

int isKeyJustDown(int key) {
    return !inputState.keysPrev[key] && inputState.keysCurr[key];
}

At the beginning of the frame I also update the input state like so:

struct InputState {
    char keysPrev[256];
    char keysCurr[256];
} inputState;

void updateInput() {
    memcpy(inputState.keysPrev, inputState.keysCurr, 256);

    glfwPollEvents();
}

This works fine with glfw3 application on desktop. Callbacks are dispatched when glfwPollEvents function is called. However this does not apply when using emscripten.

I have two questions. When exactly are callbacks dispatched when using emscripten (do they happen as soon as event occurs or is there a certain point in the loop it happens)? And how can I achieve the same behaviour as on desktop when using emscripten?

Here is the full example:

#include <GLFW/glfw3.h>
#include <memory.h>
#include <stdio.h>

#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif

GLFWwindow *window;

struct InputState {
    char keysPrev[256];
    char keysCurr[256];
} inputState;

void updateInput() {
    memcpy(inputState.keysPrev, inputState.keysCurr, 256);

    glfwPollEvents();
}

int isKeyJustDown(int key) {
    return !inputState.keysPrev[key] && inputState.keysCurr[key];
}

void update() {
    updateInput();

    if (isKeyJustDown(GLFW_KEY_E)) {
        printf("Key E\n");
    }

    glfwSwapBuffers(window);
}

void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) {
    if (key < 0) return;

    inputState.keysCurr[key] = action != GLFW_RELEASE;
}

int main() {
    if (!glfwInit()) return 1;

    window = glfwCreateWindow(1280, 720, "Input test", NULL, NULL);
    if (!window) return 1;
    glfwSetKeyCallback(window, keyCallback);

#ifdef __EMSCRIPTEN__
    emscripten_set_main_loop(update, 0, 1);
#else
    while (!glfwWindowShouldClose(window)) {
        update();
    }

    glfwTerminate();
#endif

    return 0;
}

It looks like glfwPollInput does nothing in the emscripten implementation. The actual event callbacks can happen at any time. To solve my problem I moved updateInput function after checking for input:

void update() {
    if (isKeyJustDown(GLFW_KEY_E)) {
        printf("Key E\n");
    }

    glfwSwapBuffers(window);
    updateInput();
}

Relevant links:

https://github.com/raysan5/raylib/pull/2380

https://github.com/raysan5/raylib/issues/2379

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM