From e85861cbb237ffc70650b2ecb80d1e78c7203829 Mon Sep 17 00:00:00 2001 From: John McCardle Date: Sun, 16 Jul 2023 23:30:00 -0400 Subject: [PATCH] I've worked keybinding functionality into Python, but there are some workarounds and notes (See the Jankfile) --- JANKFILE.md | 12 ++++++++++-- src/GameEngine.cpp | 2 +- src/McRFPy_API.cpp | 2 ++ src/PythonScene.cpp | 8 +++++--- src/PythonScene.h | 4 ++-- src/Scene.cpp | 1 + src/scripts/TestScene.py | 20 +++++++++++++++++++- 7 files changed, 40 insertions(+), 9 deletions(-) diff --git a/JANKFILE.md b/JANKFILE.md index 4e7d593..eaa6944 100644 --- a/JANKFILE.md +++ b/JANKFILE.md @@ -75,10 +75,18 @@ More ideas: * Need to call a Python update function when C++ events cause camera following to change: UI is only updating after player input -Tomorrow, start with: +Continue with: * implement checks in PythonScene::registerActionInjected - Save injected actions, don't let regular actions be overwritten, return success * Remove PythonScene key definitions and McRFPy_API::player_input * re-implement walking via keyboard input in Python * Find a good spot for camera following to update Python immediately -* Find a good spot for grid updates to redraw TCOD line of sight immediately \ No newline at end of file +* Find a good spot for grid updates to redraw TCOD line of sight immediately + +## Notes 16 July + +Main problem that came up today: all Python code is executed at the moment the GameEngine instantiates the PythonScene, which is actually when the game starts up. The active scene at that point is the MenuScene, so the Python code registers events against that scene (which rejects injected event binding and has no API functionality). + +Workaround: There's a clickable button that performs the input registration. This is good for working out the behavior, but doesn't really allow Python scripts to properly control and set up their own environment. + +The module name is passed to the PythonScene constructor, and the `start()` method is called to set up class objects. Can I add more methods that are called on this module to swap scenes? diff --git a/src/GameEngine.cpp b/src/GameEngine.cpp index 260200a..e9d5df4 100644 --- a/src/GameEngine.cpp +++ b/src/GameEngine.cpp @@ -32,7 +32,7 @@ GameEngine::GameEngine() } Scene* GameEngine::currentScene() { return scenes[scene]; } -void GameEngine::changeScene(std::string s) { scene = s; } +void GameEngine::changeScene(std::string s) { std::cout << "Current scene is now '" << s << "'\n"; scene = s; } void GameEngine::quit() { running = false; } void GameEngine::setPause(bool p) { paused = p; } sf::Font & GameEngine::getFont() { return font; } diff --git a/src/McRFPy_API.cpp b/src/McRFPy_API.cpp index cb09dff..e759fdd 100644 --- a/src/McRFPy_API.cpp +++ b/src/McRFPy_API.cpp @@ -558,8 +558,10 @@ PyObject* McRFPy_API::_registerInputAction(PyObject *self, PyObject *args) bool success; if (actionstr == NULL) { // Action provided is None, i.e. unregister + std::cout << "Unregistering\n"; success = game->currentScene()->unregisterActionInjected(action_code, std::string(actionstr) + "_py"); } else { + std::cout << "Registering" << actionstr << "_py to " << action_code << "\n"; success = game->currentScene()->registerActionInjected(action_code, std::string(actionstr) + "_py"); } diff --git a/src/PythonScene.cpp b/src/PythonScene.cpp index 29ed9c3..1122606 100644 --- a/src/PythonScene.cpp +++ b/src/PythonScene.cpp @@ -187,7 +187,7 @@ void PythonScene::doAction(std::string name, std::string type) { auto mousepos = sf::Mouse::getPosition(game->getWindow()); //std::cout << "name: " << name << ", type: " << type << std::endl; if (ACTIONPY) { - McRFPy_API::doAction(name); + McRFPy_API::doAction(name.substr(0, name.size() - 3)); } else if (ACTIONONCE("click")) { // left click start @@ -241,8 +241,10 @@ void PythonScene::doAction(std::string name, std::string type) { } bool PythonScene::registerActionInjected(int code, std::string name) { - return false; - + std::cout << "Registering injected action (PythonScene): " << code << " (" << ActionCode::KEY + code << ")\n"; + registerAction(ActionCode::KEY + code, name); + //return false; + return true; } bool PythonScene::unregisterActionInjected(int code, std::string name) { diff --git a/src/PythonScene.h b/src/PythonScene.h index 0133ea9..587367f 100644 --- a/src/PythonScene.h +++ b/src/PythonScene.h @@ -24,6 +24,6 @@ public: void update() override final; void doAction(std::string, std::string) override final; void sRender() override final; - bool registerActionInjected(int, std::string) override final; - bool unregisterActionInjected(int, std::string) override final; + bool registerActionInjected(int, std::string) override; + bool unregisterActionInjected(int, std::string) override; }; diff --git a/src/Scene.cpp b/src/Scene.cpp index 7b5bac6..61afda5 100644 --- a/src/Scene.cpp +++ b/src/Scene.cpp @@ -26,6 +26,7 @@ std::string Scene::action(int code) bool Scene::registerActionInjected(int code, std::string name) { + std::cout << "Inject registered action - default implementation\n"; return false; } diff --git a/src/scripts/TestScene.py b/src/scripts/TestScene.py index 214f137..05296d6 100644 --- a/src/scripts/TestScene.py +++ b/src/scripts/TestScene.py @@ -257,6 +257,10 @@ class TestScene: mcrfpy.createMenu("o", 540 + (80 * 4), 540, 80, 80) #10 mcrfpy.createSprite("o", 4, 4, 10, 10, 1.0) + + mcrfpy.createMenu("p", 20, 20, 40, 40) #11 + mcrfpy.createButton("p", 0, 0, 130, 40, DARKGREEN, (0, 0, 0), "Register", "keyregistration") + mcrfpy.registerPyAction("keyregistration", keyregistration) #print("Make UIs visible") self.menus = mcrfpy.listMenus() self.menus[0].visible = True @@ -273,6 +277,9 @@ class TestScene: self.menus[mn].bgcolor = BLACK self.menus[mn].visible = False mcrfpy.modMenu(self.menus[mn]) + + self.menus[11].visible=True + mcrfpy.modMenu(self.menus[11]) #self.menus[2].bgcolor = BLACK #self.menus[3].visible = True @@ -536,10 +543,21 @@ class TestScene: False, [0, 1, 2, 1, 2, 0] ) - + +def keytest(): + print("Key tested.") + +def keyregistration(): + print("Registering 'keytest'") + mcrfpy.registerPyAction("keytest", keytest) + print("Registering input") + print(mcrfpy.registerInputAction(15, "keytest")) + def start(): global scene #print("TestScene.start called") scene = TestScene() mcrfpy.refreshFov() + + scene.updatehints()