Key is binding only one time

framework->define_key("a-repeat", ...);
framework->define_key("b-repeat", ...);

And when pressing “A” it works, but when pressing “B” there is nothing happening.

As this test shows, this is not the case.

#include "pandaFramework.h"
#include "pandaSystem.h"
#include <stdio.h>

void test_a(const Event * theEvent, void * data) {
  printf("a\n");
}

void test_b(const Event * theEvent, void * data) {
  printf("b\n");
}

int main(int argc, char *argv[]) {
  // Open a new window framework
  PandaFramework framework;
  framework.open_framework(argc, argv);

  // Set the window title and open the window
  framework.set_window_title("My Panda3D Window");
  WindowFramework *window = framework.open_window();
  
  window->enable_keyboard();

  framework.define_key("a-repeat", "spam a", test_a, nullptr);
  framework.define_key("b-repeat", "spam b", test_b, nullptr);

  // Do the main loop, equal to run() in python
  framework.main_loop();
  framework.close_framework();
  return (0);
}

Note the use of the function name, not the pointer.

Is there a method to get all defined keys?

I do not know any way. I wrote a simple replacement for the PandaFramework class and use it.

void Keyboard::onKey(void (*handler) (), const std::string& key, const Window &window) {
    static auto __hf = handler;

    window.p_framework->define_key(key, "on_key_" + key, [] (const Event *, void *) { __hf(); }, nullptr);
}

void Keyboard::onKeyUp(void (*handler) (), const std::string &key, const Window &window) {
    static auto __hf = handler;

    window.p_framework->define_key(key + "-up", "on_key_up_" + key, [] (const Event *, void *) { __hf(); }, nullptr);
}

void Keyboard::onKeyDown(void (*handler) (), const std::string &key, const Window &window) {
    static auto __hf = handler;

    window.p_framework->define_key(key + "-repeat", "on_key_repeat(down)_" + key, [] (const Event *, void *) { __hf(); }, nullptr);
}

Basically when calling onKeyDown with key “a”, and after calling onKeyDown with key “b”, and after running the game after pressing “b” or “a” whatever, it calls handler of “A” key.

That’s because you use the static keyword, which means there is only one instance of that variable which gets initialized the first time you use this function.

So in your code, __hf will always contain the handler you passed in the first time you called that function.

Use the extra void * argument to pass in the handler instead:

void Keyboard::onKey(void (*handler) (), const std::string& key, const Window &window) {
    window.p_framework->define_key(key, "on_key_" + key, [] (const Event *, void *extra) { ((void (*)())extra)(); }, handler);
}
1 Like

Thanks!