wow, good test of Key and Click Callable classes. Cleanup, squash, and merge after I give it a lookover in daylight, though.

This commit is contained in:
John McCardle 2024-03-12 22:27:12 -04:00
parent 972768eb26
commit 05d9f6a882
10 changed files with 109 additions and 13 deletions

View File

@ -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
{

View File

@ -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<PyKeyCallable>(callable);
return Py_None;
}

View File

@ -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;
}
}

View File

@ -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();
};

View File

@ -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);
}
}
}

View File

@ -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<PyKeyCallable>();
game = g;
ui_elements = std::make_shared<std::vector<std::shared_ptr<UIDrawable>>>();
}
@ -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<PyKeyCallable>(callable);
}
void Scene::key_unregister()
{
/*
if (key_callable == NULL) return;
Py_DECREF(key_callable);
key_callable = NULL;
*/
key_callable.reset();
}

View File

@ -9,6 +9,7 @@
#include "Common.h"
#include <list>
#include "UI.h"
#include "PyCallable.h"
//#include "GameEngine.h"
class GameEngine; // forward declare
@ -41,7 +42,8 @@ public:
std::shared_ptr<std::vector<std::shared_ptr<UIDrawable>>> ui_elements;
PyObject* key_callable;
//PyObject* key_callable;
std::unique_ptr<PyKeyCallable> key_callable;
void key_register(PyObject*);
void key_unregister();
};

View File

@ -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<PyClickCallable>(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(

View File

@ -5,6 +5,7 @@
#include "IndexTexture.h"
#include "Resources.h"
#include <list>
#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<PyClickCallable> 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");

View File

@ -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<UIEntity>(*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);