Aug 30/31 updates. Tinkering with shared_ptr. Working towards exposing UI objects to Python UI. Color object updated for shared_ptr structure that will be repeated for the rest of the UI objects. Still a lot of open questions, but committing here to get back on track after a few hours wasted trying to solve this problem too generally via templates.

This commit is contained in:
John McCardle 2023-08-31 13:51:56 -04:00
commit 50d926fe37
11 changed files with 293 additions and 137 deletions

226
src/UI.h
View file

@ -1,3 +1,4 @@
#pragma once
#include "Common.h"
#include "Python.h"
#include "structmember.h"
@ -14,12 +15,18 @@ public:
std::string action;
};
//PyColorObject struct required to embed Python colors into UIFrame
//Python object types & forward declarations
/*
typedef struct {
PyObject_HEAD
sf::Color color;
} PyColorObject;
*/
typedef struct {
PyObject_HEAD
std::shared_ptr<sf::Color> data;
} PyColorObject;
class UIFrame: public UIDrawable
{
@ -27,14 +34,15 @@ public:
UIFrame(float, float, float, float);
UIFrame();
~UIFrame();
//sf::RectangleShape box;
sf::RectangleShape box;
//Simulate RectangleShape
float x, y, w, h, outline;
std::vector<UIDrawable*> children;
std::vector<std::shared_ptr<UIDrawable>> children;
void render(sf::Vector2f) override final;
void move(sf::Vector2f);
/*
sf::Color fillColor(); // getter
void fillColor(sf::Color c); // C++ setter
void fillColor(PyColorObject* pyColor); // Python setter
@ -42,10 +50,14 @@ public:
sf::Color outlineColor(); // getter
void outlineColor(sf::Color c); // C++ setter
void outlineColor(PyColorObject* pyColor); // Python setter
*/
private:
//std::shared_ptr<sf::Color> fillColor, outlineColor;
/*
sf::Color *_fillColor, *_outlineColor;
PyColorObject *pyFillColor, *pyOutlineColor;
*/
};
class UICaption: public UIDrawable
@ -64,45 +76,72 @@ public:
sf::Sprite sprite;
};
/*
template<typename T>
struct CPythonSharedObject {
PyObject_HEAD
std::shared_ptr<T> data;
};
typedef CPythonSharedObject<UIFrame> PyUIFrameObject;
*/
//equivalent
/*
typedef struct {
PyObject_HEAD
std::shared_ptr<UIFrame> data;
} PyUIFrameObject;
*/
typedef struct {
PyObject_HEAD
std::shared_ptr<UICaption> data;
} PyUICaptionObject;
typedef struct {
PyObject_HEAD
std::shared_ptr<UISprite> data;
} PyUISpriteObject;
namespace mcrfpydef {
// Color Definitions
// struct, members, new, set_member, PyTypeObject
/* for reference: the structs to implement
typedef struct {
PyObject_HEAD
std::shared_ptr<sf::Color> data;
} PyColorObject;
static PyMemberDef PyColor_members[]
{
{"r", T_BYTE, offsetof(PyColorObject, color.r), 0},
{"g", T_BYTE, offsetof(PyColorObject, color.g), 0},
{"b", T_BYTE, offsetof(PyColorObject, color.b), 0},
{"a", T_BYTE, offsetof(PyColorObject, color.a), 0},
{NULL}
};
typedef struct {
PyObject_HEAD
std::shared_ptr<UIFrame> data;
} PyUIFrameObject;
static PyObject* PyColor_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
{
PyColorObject* self = (PyColorObject*)type->tp_alloc(type, 0);
if (self != NULL)
{
self->color.r = 0;
self->color.g = 0;
self->color.b = 0;
self->color.a = 255;
}
return (PyObject*) self;
}
typedef struct {
PyObject_HEAD
std::shared_ptr<UICaption> data;
} PyUICaptionObject;
typedef struct {
PyObject_HEAD
std::shared_ptr<UISprite> data;
} PyUISpriteObject;
*/
static PyObject* PyColor_get_member(PyColorObject* self, void* closure)
{
auto member_ptr = reinterpret_cast<long>(closure);
if (member_ptr == offsetof(PyColorObject, color.r))
return PyLong_FromLong(self->color.r);
else if (member_ptr == offsetof(PyColorObject, color.g))
return PyLong_FromLong(self->color.g);
else if (member_ptr == offsetof(PyColorObject, color.b))
return PyLong_FromLong(self->color.b);
else if (member_ptr == offsetof(PyColorObject, color.a))
return PyLong_FromLong(self->color.a);
if (member_ptr == 0)
return PyLong_FromLong(self->data->r);
else if (member_ptr == 1)
return PyLong_FromLong(self->data->g);
else if (member_ptr == 2)
return PyLong_FromLong(self->data->b);
else if (member_ptr == 3)
return PyLong_FromLong(self->data->a);
else
{
PyErr_SetString(PyExc_AttributeError, "Invalid attribute");
@ -120,14 +159,14 @@ namespace mcrfpydef {
else if (int_val > 255)
int_val = 255;
auto member_ptr = reinterpret_cast<long>(closure);
if (member_ptr == offsetof(PyColorObject, color.r))
self->color.r = static_cast<sf::Uint8>(int_val);
else if (member_ptr == offsetof(PyColorObject, color.g))
self->color.g = static_cast<sf::Uint8>(int_val);
else if (member_ptr == offsetof(PyColorObject, color.b))
self->color.b = static_cast<sf::Uint8>(int_val);
else if (member_ptr == offsetof(PyColorObject, color.a))
self->color.a = static_cast<sf::Uint8>(int_val);
if (member_ptr == 0)
self->data->r = static_cast<sf::Uint8>(int_val);
else if (member_ptr == 1)
self->data->g = static_cast<sf::Uint8>(int_val);
else if (member_ptr == 2)
self->data->b = static_cast<sf::Uint8>(int_val);
else if (member_ptr == 3)
self->data->a = static_cast<sf::Uint8>(int_val);
}
else
{
@ -138,18 +177,67 @@ namespace mcrfpydef {
}
static PyGetSetDef PyColor_getsetters[] = {
{"r", (getter)PyColor_get_member, (setter)PyColor_set_member, "Red component", (void*)offsetof(PyColorObject, color.r)},
{"g", (getter)PyColor_get_member, (setter)PyColor_set_member, "Green component", (void*)offsetof(PyColorObject, color.g)},
{"b", (getter)PyColor_get_member, (setter)PyColor_set_member, "Blue component", (void*)offsetof(PyColorObject, color.b)},
{"a", (getter)PyColor_get_member, (setter)PyColor_set_member, "Alpha component", (void*)offsetof(PyColorObject, color.a)},
{"r", (getter)PyColor_get_member, (setter)PyColor_set_member, "Red component", (void*)0},
{"g", (getter)PyColor_get_member, (setter)PyColor_set_member, "Green component", (void*)1},
{"b", (getter)PyColor_get_member, (setter)PyColor_set_member, "Blue component", (void*)2},
{"a", (getter)PyColor_get_member, (setter)PyColor_set_member, "Alpha component", (void*)3},
{NULL}
};
static PyTypeObject PyColorType = {
static PyTypeObject PyColorType = {
//PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mcrfpy.Color",
.tp_basicsize = sizeof(PyColorObject),
.tp_itemsize = 0,
.tp_dealloc = (destructor)[](PyObject* self)
{
PyColorObject* obj = (PyColorObject*)self;
obj->data.reset();
Py_TYPE(self)->tp_free(self);
},
//.tp_repr = (reprfunc)PyUIFrame_repr,
//.tp_hash = NULL,
//.tp_iter
//.tp_iternext
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = PyDoc_STR("SFML Color object (RGBA)"),
//.tp_methods = PyUIFrame_methods,
//.tp_members = PyColor_members,
.tp_getset = PyColor_getsetters,
//.tp_base = NULL,
//.tp_init = (initproc)PyUIFrame_init,
.tp_new = [](PyTypeObject* type, PyObject* args, PyObject* kwds) -> PyObject*
{
PyColorObject* self = (PyColorObject*)type->tp_alloc(type, 0);
if (self) self->data = std::make_shared<sf::Color>();
return (PyObject*)self;
}
};
/*
static PyTypeObject PyUIFrameType = {
.tp_name = "mcrfpy.Frame",
.tp_basicsize = sizeof(PyUIFrameObject),
.tp_itemsize = 0,
.tp_dealloc = (destructor)[](PyObject* self) {
PyUIFrameObject* obj = (PyUIFrameObject*)self;
obj->data.reset();
Py_TYPE(self)->tp_free(self);
},
//.tp_init = (initproc)PyUIFrame_init, // needs implementation
//.tp_new = PyUIFrame_new, // needs implementation
};
*/
/*
static PyTypeObject PyUIFrameType = {
//PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mcrfpy.Frame",
.tp_basicsize = sizeof(PyColorObject),
.tp_itemsize = 0,
//.tp_dealloc = [](PyObject* obj) { Py_TYPE(obj)->tp_free(obj); },
//.tp_repr = (reprfunc)PyUIFrame_repr,
//.tp_hash = NULL,
@ -165,10 +253,50 @@ namespace mcrfpydef {
.tp_new = PyColor_new, //PyType_GenericNew ?
};
static PyTypeObject PyCaptionType = {
//PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mcrfpy.Caption",
.tp_basicsize = sizeof(PyColorObject),
.tp_itemsize = 0,
//.tp_dealloc = [](PyObject* obj) { Py_TYPE(obj)->tp_free(obj); },
//.tp_repr = (reprfunc)PyUIFrame_repr,
//.tp_hash = NULL,
//.tp_iter
//.tp_iternext
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = PyDoc_STR("SFML Color object (RGBA)"),
//.tp_methods = PyUIFrame_methods,
//.tp_members = PyColor_members,
.tp_getset = PyColor_getsetters,
//.tp_base = NULL,
//.tp_init = (initproc)PyUIFrame_init,
.tp_new = PyColor_new, //PyType_GenericNew ?
};
static PyTypeObject PySpriteType = {
//PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mcrfpy.Sprite",
.tp_basicsize = sizeof(PyColorObject),
.tp_itemsize = 0,
//.tp_dealloc = [](PyObject* obj) { Py_TYPE(obj)->tp_free(obj); },
//.tp_repr = (reprfunc)PyUIFrame_repr,
//.tp_hash = NULL,
//.tp_iter
//.tp_iternext
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = PyDoc_STR("SFML Color object (RGBA)"),
//.tp_methods = PyUIFrame_methods,
//.tp_members = PyColor_members,
.tp_getset = PyColor_getsetters,
//.tp_base = NULL,
//.tp_init = (initproc)PyUIFrame_init,
.tp_new = PyColor_new, //PyType_GenericNew ?
};
*/
// UIFrame Definitions
// new, init, repr, set_size, methods, members, PyTypeObject
/*
static PyObject* PyUIFrame_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
{
std::cout << "New called\n";
@ -221,6 +349,7 @@ namespace mcrfpydef {
"Set the width and height of the UIFrame's visible box"},
{NULL, NULL, 0, NULL}
};
*/
/*
static PyMemberDef PyUIFrame_members[] = {
@ -228,7 +357,8 @@ namespace mcrfpydef {
{NULL}
};
*/
/*
static PyTypeObject PyUIFrameType = {
//PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mcrfpy.UIFrame",
@ -247,6 +377,6 @@ namespace mcrfpydef {
.tp_init = (initproc)PyUIFrame_init,
.tp_new = PyUIFrame_new, //PyType_GenericNew ?
};
*/
}