From 05d9f6a88233931313b9ed09c86227608a676749 Mon Sep 17 00:00:00 2001 From: John McCardle Date: Tue, 12 Mar 2024 22:27:12 -0400 Subject: [PATCH] wow, good test of Key and Click Callable classes. Cleanup, squash, and merge after I give it a lookover in daylight, though. --- src/GameEngine.cpp | 5 ++++- src/McRFPy_API.cpp | 3 +++ src/PyCallable.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++ src/PyCallable.h | 21 ++++++++++++++++-- src/PyScene.cpp | 4 ++++ src/Scene.cpp | 8 ++++++- src/Scene.h | 4 +++- src/UI.cpp | 8 ++++++- src/UI.h | 12 ++++++----- src/UITestScene.cpp | 5 +++-- 10 files changed, 109 insertions(+), 13 deletions(-) diff --git a/src/GameEngine.cpp b/src/GameEngine.cpp index beb2b31..2b62886 100644 --- a/src/GameEngine.cpp +++ b/src/GameEngine.cpp @@ -157,8 +157,10 @@ void GameEngine::sUserInput() std::string name = currentScene()->action(actionCode); currentScene()->doAction(name, actionType); } - else if (currentScene()->key_callable != NULL && currentScene()->key_callable != Py_None) + else if (currentScene()->key_callable) { + currentScene()->key_callable->call(ActionCode::key_str(event.key.code), actionType); + /* PyObject* args = Py_BuildValue("(ss)", ActionCode::key_str(event.key.code).c_str(), actionType.c_str()); PyObject* retval = PyObject_Call(currentScene()->key_callable, args, NULL); if (!retval) @@ -170,6 +172,7 @@ void GameEngine::sUserInput() { std::cout << "key_callable returned a non-None value. It's not an error, it's just not being saved or used." << std::endl; } + */ } else { diff --git a/src/McRFPy_API.cpp b/src/McRFPy_API.cpp index 5aa61e1..113c13a 100644 --- a/src/McRFPy_API.cpp +++ b/src/McRFPy_API.cpp @@ -453,6 +453,7 @@ PyObject* McRFPy_API::_createScene(PyObject* self, PyObject* args) { PyObject* McRFPy_API::_keypressScene(PyObject* self, PyObject* args) { PyObject* callable; if (!PyArg_ParseTuple(args, "O", &callable)) return NULL; + /* if (game->currentScene()->key_callable != NULL and game->currentScene()->key_callable != Py_None) { Py_DECREF(game->currentScene()->key_callable); @@ -460,6 +461,8 @@ PyObject* McRFPy_API::_keypressScene(PyObject* self, PyObject* args) { Py_INCREF(callable); game->currentScene()->key_callable = callable; Py_INCREF(Py_None); + */ + game->currentScene()->key_callable = std::make_unique(callable); return Py_None; } diff --git a/src/PyCallable.cpp b/src/PyCallable.cpp index 5e16884..2226128 100644 --- a/src/PyCallable.cpp +++ b/src/PyCallable.cpp @@ -55,3 +55,55 @@ bool PyTimerCallable::test(int now) } return false; } + +PyClickCallable::PyClickCallable(PyObject* _target) +: PyCallable(_target) +{} + +PyClickCallable::PyClickCallable() +: PyCallable(Py_None) +{} + +void PyClickCallable::call(sf::Vector2f mousepos, std::string button, std::string action) +{ + PyObject* args = Py_BuildValue("(iiss)", (int)mousepos.x, (int)mousepos.y, button.c_str(), action.c_str()); + PyObject* retval = PyCallable::call(args, NULL); + if (!retval) + { + std::cout << "ClickCallable has raised an exception. It's going to STDERR and being dropped:" << std::endl; + PyErr_Print(); + PyErr_Clear(); + } else if (retval != Py_None) + { + std::cout << "ClickCallable returned a non-None value. It's not an error, it's just not being saved or used." << std::endl; + std::cout << PyUnicode_AsUTF8(PyObject_Repr(retval)) << std::endl; + } +} + +PyObject* PyClickCallable::borrow() +{ + return target; +} + +PyKeyCallable::PyKeyCallable(PyObject* _target) +: PyCallable(_target) +{} + +PyKeyCallable::PyKeyCallable() +: PyCallable(Py_None) +{} + +void PyKeyCallable::call(std::string key, std::string action) +{ + PyObject* args = Py_BuildValue("(ss)", key.c_str(), action.c_str()); + PyObject* retval = PyCallable::call(args, NULL); + if (!retval) + { + std::cout << "KeyCallable has raised an exception. It's going to STDERR and being dropped:" << std::endl; + PyErr_Print(); + PyErr_Clear(); + } else if (retval != Py_None) + { + std::cout << "KeyCallable returned a non-None value. It's not an error, it's just not being saved or used." << std::endl; + } +} diff --git a/src/PyCallable.h b/src/PyCallable.h index fd9257d..b59e774 100644 --- a/src/PyCallable.h +++ b/src/PyCallable.h @@ -4,9 +4,8 @@ class PyCallable { -private: - PyObject* target; protected: + PyObject* target; PyCallable(PyObject*); ~PyCallable(); PyObject* call(PyObject*, PyObject*); @@ -24,3 +23,21 @@ public: PyTimerCallable(PyObject*, int, int); PyTimerCallable(); }; + +class PyClickCallable: public PyCallable +{ +public: + void call(sf::Vector2f, std::string, std::string); + PyObject* borrow(); + PyClickCallable(PyObject*); + PyClickCallable(); +}; + +class PyKeyCallable: public PyCallable +{ +public: + void call(std::string, std::string); + //PyObject* borrow(); // not yet implemented + PyKeyCallable(PyObject*); + PyKeyCallable(); +}; diff --git a/src/PyScene.cpp b/src/PyScene.cpp index ab62567..5ed8b74 100644 --- a/src/PyScene.cpp +++ b/src/PyScene.cpp @@ -1,6 +1,7 @@ #include "PyScene.h" #include "ActionCode.h" #include "Resources.h" +#include "PyCallable.h" PyScene::PyScene(GameEngine* g) : Scene(g) { @@ -27,6 +28,7 @@ void PyScene::do_mouse_input(std::string button, std::string type) target = d->click_at(sf::Vector2f(mousepos)); if (target) { + /* PyObject* args = Py_BuildValue("(iiss)", (int)mousepos.x, (int)mousepos.y, button.c_str(), type.c_str()); PyObject* retval = PyObject_Call(target->click_callable, args, NULL); if (!retval) @@ -38,6 +40,8 @@ void PyScene::do_mouse_input(std::string button, std::string type) { std::cout << "click_callable returned a non-None value. It's not an error, it's just not being saved or used." << std::endl; } + */ + target->click_callable->call(mousepos, button, type); } } } diff --git a/src/Scene.cpp b/src/Scene.cpp index 8567e61..d9438e3 100644 --- a/src/Scene.cpp +++ b/src/Scene.cpp @@ -4,7 +4,7 @@ //Scene::Scene() { game = 0; std::cout << "WARN: default Scene constructor called. (game = " << game << ")" << std::endl;}; Scene::Scene(GameEngine* g) { - key_callable = Py_None; + key_callable = std::make_unique(); game = g; ui_elements = std::make_shared>>(); } @@ -43,6 +43,7 @@ bool Scene::unregisterActionInjected(int code, std::string name) void Scene::key_register(PyObject* callable) { + /* if (key_callable) { // decrement reference before overwriting @@ -50,11 +51,16 @@ void Scene::key_register(PyObject* callable) } key_callable = callable; Py_INCREF(key_callable); + */ + key_callable = std::make_unique(callable); } void Scene::key_unregister() { + /* if (key_callable == NULL) return; Py_DECREF(key_callable); key_callable = NULL; + */ + key_callable.reset(); } diff --git a/src/Scene.h b/src/Scene.h index 90b82ef..02931b1 100644 --- a/src/Scene.h +++ b/src/Scene.h @@ -9,6 +9,7 @@ #include "Common.h" #include #include "UI.h" +#include "PyCallable.h" //#include "GameEngine.h" class GameEngine; // forward declare @@ -41,7 +42,8 @@ public: std::shared_ptr>> ui_elements; - PyObject* key_callable; + //PyObject* key_callable; + std::unique_ptr key_callable; void key_register(PyObject*); void key_unregister(); }; diff --git a/src/UI.cpp b/src/UI.cpp index eeb2354..b2447cd 100644 --- a/src/UI.cpp +++ b/src/UI.cpp @@ -56,6 +56,7 @@ UIDrawable* UIGrid::click_at(sf::Vector2f point) void UIDrawable::click_register(PyObject* callable) { + /* if (click_callable) { // decrement reference before overwriting @@ -63,13 +64,18 @@ void UIDrawable::click_register(PyObject* callable) } click_callable = callable; Py_INCREF(click_callable); + */ + click_callable = std::make_unique(callable); } void UIDrawable::click_unregister() { + /* if (click_callable == NULL) return; Py_DECREF(click_callable); click_callable = NULL; + */ + click_callable.reset(); } void UIDrawable::render() @@ -378,7 +384,7 @@ void UIGrid::render(sf::Vector2f) for (auto e : *entities) { // TODO skip out-of-bounds entities (grid square not visible at all, check for partially on visible grid squares / floating point grid position) //auto drawent = e->cGrid->indexsprite.drawable(); - auto drawent = e->sprite; + auto& drawent = e->sprite; //drawent.setScale(zoom, zoom); drawent.setScale(zoom); auto pixel_pos = sf::Vector2f( diff --git a/src/UI.h b/src/UI.h index d6d6ac4..665aa95 100644 --- a/src/UI.h +++ b/src/UI.h @@ -5,6 +5,7 @@ #include "IndexTexture.h" #include "Resources.h" #include +#include "PyCallable.h" enum PyObjectsEnum : int { @@ -27,7 +28,8 @@ public: virtual PyObjectsEnum derived_type() = 0; // Mouse input handling - callable object, methods to find event's destination - PyObject* click_callable; + //PyObject* click_callable; + std::unique_ptr click_callable; virtual UIDrawable* click_at(sf::Vector2f point) = 0; void click_register(PyObject*); void click_unregister(); @@ -322,16 +324,16 @@ static PyObject* PyUIDrawable_get_click(PyUIGridObject* self, void* closure) { switch (objtype) { case PyObjectsEnum::UIFRAME: - ptr = ((PyUIFrameObject*)self)->data->click_callable; + ptr = ((PyUIFrameObject*)self)->data->click_callable->borrow(); break; case PyObjectsEnum::UICAPTION: - ptr = ((PyUICaptionObject*)self)->data->click_callable; + ptr = ((PyUICaptionObject*)self)->data->click_callable->borrow(); break; case PyObjectsEnum::UISPRITE: - ptr = ((PyUISpriteObject*)self)->data->click_callable; + ptr = ((PyUISpriteObject*)self)->data->click_callable->borrow(); break; case PyObjectsEnum::UIGRID: - ptr = ((PyUIGridObject*)self)->data->click_callable; + ptr = ((PyUIGridObject*)self)->data->click_callable->borrow(); break; default: PyErr_SetString(PyExc_TypeError, "no idea how you did that; invalid UIDrawable derived instance for _get_click"); diff --git a/src/UITestScene.cpp b/src/UITestScene.cpp index 656ef84..ff70c53 100644 --- a/src/UITestScene.cpp +++ b/src/UITestScene.cpp @@ -123,8 +123,9 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g) // TODO - reimplement UISprite style rendering within UIEntity class. Entities don't have a screen pixel position, they have a grid position, and grid sets zoom when rendering them. auto e5a = std::make_shared(*e5); // this basic constructor sucks: sprite position + zoom are irrelevant for UIEntity. e5a->grid = e5; - auto e5as = UISprite(indextex, 85, sf::Vector2f(0, 0), 1.0); - e5a->sprite = e5as; // will copy constructor even exist for UISprite...? + //auto e5as = UISprite(indextex, 85, sf::Vector2f(0, 0), 1.0); + //e5a->sprite = e5as; // will copy constructor even exist for UISprite...? + e5a->sprite = UISprite(indextex, 85, sf::Vector2f(0, 0), 1.0); e5a->position = sf::Vector2f(1, 0); e5->entities->push_back(e5a);