From 1b6e2a709bfa3adc38183e30f1cc999efd7ef7c9 Mon Sep 17 00:00:00 2001 From: John McCardle Date: Tue, 9 Apr 2024 22:42:02 -0400 Subject: [PATCH] Still not quite compiling; as predicted, a lot of interdependency and definition order bugs to untangle --- src/UIBase.h | 32 +++++++++++++++++++++ src/UICaption.cpp | 1 + src/UICaption.h | 14 +++++---- src/UIDrawable.cpp | 65 +++++++++++++++++++++++++++++++++++++++++ src/UIDrawable.h | 15 +++++++--- src/UIEntity.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++ src/UIEntity.h | 24 +++++++++------- src/UIFrame.cpp | 10 +++++++ src/UIFrame.h | 21 ++++++++------ src/UIGrid.h | 13 +++++---- src/UIGridPoint.h | 2 ++ src/UISprite.h | 10 +++---- 12 files changed, 240 insertions(+), 39 deletions(-) create mode 100644 src/UIBase.h diff --git a/src/UIBase.h b/src/UIBase.h new file mode 100644 index 0000000..70a5872 --- /dev/null +++ b/src/UIBase.h @@ -0,0 +1,32 @@ +#pragma once + +class UIEntity; +typedef struct { + PyObject_HEAD + std::shared_ptr data; +} PyUIEntityObject; + +class UIFrame; +typedef struct { + PyObject_HEAD + std::shared_ptr data; +} PyUIFrameObject; + +class UICaption; +typedef struct { + PyObject_HEAD + std::shared_ptr data; + PyObject* font; +} PyUICaptionObject; + +class UIGrid; +typedef struct { + PyObject_HEAD + std::shared_ptr data; +} PyUIGridObject; + +class UISprite; +typedef struct { + PyObject_HEAD + std::shared_ptr data; +} PyUISpriteObject; diff --git a/src/UICaption.cpp b/src/UICaption.cpp index aa53a8a..68f74ab 100644 --- a/src/UICaption.cpp +++ b/src/UICaption.cpp @@ -1,4 +1,5 @@ #include "UICaption.h" +#include "GameEngine.h" UIDrawable* UICaption::click_at(sf::Vector2f point) { diff --git a/src/UICaption.h b/src/UICaption.h index ee37e1c..f403813 100644 --- a/src/UICaption.h +++ b/src/UICaption.h @@ -12,6 +12,7 @@ #include "PyVector.h" #include "PyFont.h" #include "UIDrawable.h" +#include "UIBase.h" class UICaption: public UIDrawable { @@ -22,11 +23,12 @@ public: virtual UIDrawable* click_at(sf::Vector2f point) override final; }; -typedef struct { - PyObject_HEAD - std::shared_ptr data; - PyObject* font; -} PyUICaptionObject; +//class UICaption; +//typedef struct { +// PyObject_HEAD +// std::shared_ptr data; +// PyObject* font; +//} PyUICaptionObject; namespace mcrfpydef { //TODO: add this method to class scope; move implementation to .cpp file @@ -205,7 +207,7 @@ namespace mcrfpydef { //{"children", (getter)PyUIFrame_get_children, NULL, "UICollection of objects on top of this one", NULL}, {"text", (getter)PyUICaption_get_text, (setter)PyUICaption_set_text, "The text displayed", NULL}, {"size", (getter)PyUICaption_get_float_member, (setter)PyUICaption_set_float_member, "Text size (integer) in points", (void*)5}, - {"click", (getter)PyUIDrawable_get_click, (setter)PyUIDrawable_set_click, "Object called with (x, y, button) when clicked", (void*)PyObjectsEnum::UICAPTION}, + {"click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click, "Object called with (x, y, button) when clicked", (void*)PyObjectsEnum::UICAPTION}, {NULL} }; diff --git a/src/UIDrawable.cpp b/src/UIDrawable.cpp index 7cd1178..cd898c4 100644 --- a/src/UIDrawable.cpp +++ b/src/UIDrawable.cpp @@ -1,4 +1,8 @@ #include "UIDrawable.h" +#include "UIFrame.h" +#include "UICaption.h" +#include "UISprite.h" +#include "UIGrid.h" UIDrawable::UIDrawable() { click_callable = NULL; } @@ -11,3 +15,64 @@ void UIDrawable::render() { render(sf::Vector2f()); } + +PyObject* UIDrawable::get_click(PyObject* self, void* closure) { + PyObjectsEnum objtype = static_cast(reinterpret_cast(closure)); // trust me bro, it's an Enum + PyObject* ptr; + + switch (objtype) + { + case PyObjectsEnum::UIFRAME: + ptr = ((PyUIFrameObject*)self)->data->click_callable->borrow(); + break; + case PyObjectsEnum::UICAPTION: + ptr = ((PyUICaptionObject*)self)->data->click_callable->borrow(); + break; + case PyObjectsEnum::UISPRITE: + ptr = ((PyUISpriteObject*)self)->data->click_callable->borrow(); + break; + case PyObjectsEnum::UIGRID: + 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"); + return NULL; + } + if (ptr && ptr != Py_None) + return ptr; + else + return Py_None; +} + +int UIDrawable::set_click(PyObject* self, PyObject* value, void* closure) { + PyObjectsEnum objtype = static_cast(reinterpret_cast(closure)); // trust me bro, it's an Enum + UIDrawable* target; + switch (objtype) + { + case PyObjectsEnum::UIFRAME: + target = (((PyUIFrameObject*)self)->data.get()); + break; + case PyObjectsEnum::UICAPTION: + target = (((PyUICaptionObject*)self)->data.get()); + break; + case PyObjectsEnum::UISPRITE: + target = (((PyUISpriteObject*)self)->data.get()); + break; + case PyObjectsEnum::UIGRID: + target = (((PyUIGridObject*)self)->data.get()); + break; + default: + PyErr_SetString(PyExc_TypeError, "no idea how you did that; invalid UIDrawable derived instance for _set_click"); + return -1; + } + + if (value == Py_None) + { + target->click_unregister(); + } else { + target->click_register(value); + } + return 0; +} + + diff --git a/src/UIDrawable.h b/src/UIDrawable.h index 5fb01e1..640437f 100644 --- a/src/UIDrawable.h +++ b/src/UIDrawable.h @@ -12,6 +12,8 @@ #include "PyVector.h" #include "PyFont.h" +#include "Resources.h" + class UIFrame; class UICaption; class UISprite; class UIEntity; class UIGrid; enum PyObjectsEnum : int @@ -36,6 +38,9 @@ public: void click_unregister(); UIDrawable(); + + static PyObject* get_click(PyObject* self, void* closure); + static int set_click(PyObject* self, PyObject* value, void* closure); }; typedef struct { @@ -99,7 +104,8 @@ switch (target->derived_type()) \ // end macro definition //TODO: add this method to class scope; move implementation to .cpp file -static PyObject* PyUIDrawable_get_click(PyUIGridObject* self, void* closure) { +/* +static PyObject* PyUIDrawable_get_click(PyObject* self, void* closure) { PyObjectsEnum objtype = static_cast(reinterpret_cast(closure)); // trust me bro, it's an Enum PyObject* ptr; @@ -125,10 +131,11 @@ static PyObject* PyUIDrawable_get_click(PyUIGridObject* self, void* closure) { return ptr; else return Py_None; -} +}*/ //TODO: add this method to class scope; move implementation to .cpp file -static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* closure) { +/* +static int PyUIDrawable_set_click(PyObject* self, PyObject* value, void* closure) { PyObjectsEnum objtype = static_cast(reinterpret_cast(closure)); // trust me bro, it's an Enum UIDrawable* target; switch (objtype) @@ -158,5 +165,5 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c } return 0; } - +*/ } diff --git a/src/UIEntity.cpp b/src/UIEntity.cpp index 96738d7..9e21eaf 100644 --- a/src/UIEntity.cpp +++ b/src/UIEntity.cpp @@ -7,3 +7,75 @@ UIEntity::UIEntity(UIGrid& grid) { } +PyObject* UIEntity::at(PyUIEntityObject* self, PyObject* o) { + int x, y; + if (!PyArg_ParseTuple(o, "ii", &x, &y)) { + PyErr_SetString(PyExc_TypeError, "UIEntity.at requires two integer arguments: (x, y)"); + return NULL; + } + + if (self->data->grid == NULL) { + PyErr_SetString(PyExc_ValueError, "Entity cannot access surroundings because it is not associated with a grid"); + return NULL; + } + + PyUIGridPointStateObject* obj = (PyUIGridPointStateObject*)((&PyUIGridPointStateType)->tp_alloc(&PyUIGridPointStateType, 0)); + //auto target = std::static_pointer_cast(target); + obj->data = &(self->data->gridstate[y + self->data->grid->grid_x * x]); + obj->grid = self->data->grid; + obj->entity = self->data; + return (PyObject*)obj; + +} + +int PyUIEntity::init(PyUIEntityObject* self, PyObject* args, PyObject* kwds) { + static const char* keywords[] = { "x", "y", "texture", "sprite_index", "grid", nullptr }; + float x = 0.0f, y = 0.0f, scale = 1.0f; + int sprite_index = -1; + PyObject* texture = NULL; + PyObject* grid = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "ffOi|O", + const_cast(keywords), &x, &y, &texture, &sprite_index, &grid)) + { + return -1; + } + + // check types for texture + // + // Set Texture + // + if (texture != NULL && !PyObject_IsInstance(texture, (PyObject*)&mcrfpydef::PyTextureType)){ + PyErr_SetString(PyExc_TypeError, "texture must be a mcrfpy.Texture instance"); + return -1; + } /*else if (texture != NULL) // this section needs to go; texture isn't optional and isn't managed by the UI objects anymore + { + self->texture = texture; + Py_INCREF(texture); + } else + { + // default tex? + }*/ + + if (grid != NULL && !PyObject_IsInstance(grid, (PyObject*)&PyUIGridType)) { + PyErr_SetString(PyExc_TypeError, "grid must be a mcrfpy.Grid instance"); + return -1; + } + + auto pytexture = (PyTextureObject*)texture; + if (grid == NULL) + self->data = std::make_shared(); + else + self->data = std::make_shared(*((PyUIGridObject*)grid)->data); + + // TODO - PyTextureObjects and IndexTextures are a little bit of a mess with shared/unshared pointers + self->data->sprite = UISprite(pytexture->data, sprite_index, sf::Vector2f(0,0), 1.0); + self->data->position = sf::Vector2f(x, y); + if (grid != NULL) { + PyUIGridObject* pygrid = (PyUIGridObject*)grid; + self->data->grid = pygrid->data; + // todone - on creation of Entity with Grid assignment, also append it to the entity list + pygrid->data->entities->push_back(self->data); + } + return 0; +} diff --git a/src/UIEntity.h b/src/UIEntity.h index edf06b1..8088aff 100644 --- a/src/UIEntity.h +++ b/src/UIEntity.h @@ -14,9 +14,15 @@ #include "UIGridPoint.h" #include "UIDrawable.h" - +#include "UIBase.h" class UIGrid; +//class UIEntity; +//typedef struct { +// PyObject_HEAD +// std::shared_ptr data; +//} PyUIEntityObject; + // TODO: make UIEntity a drawable class UIEntity//: public UIDrawable { @@ -31,14 +37,10 @@ public: UIEntity(); UIEntity(UIGrid&); + static PyObject* at(PyUIEntityObject* self, PyObject* o); + static int init(PyUIEntityObject* self, PyObject* args, PyObject* kwds); }; -typedef struct { - PyObject_HEAD - std::shared_ptr data; - //PyObject* texture; -} PyUIEntityObject; - namespace mcrfpydef { //TODO: add this method to class scope; move implementation to .cpp file; reconsider for moving to "UIBase.h/.cpp" // TODO: sf::Vector2f convenience functions here might benefit from a PyVectorObject much like PyColorObject @@ -124,6 +126,7 @@ static int PyUIEntity_set_spritenumber(PyUIEntityObject* self, PyObject* value, } //TODO: add this method to class scope; move implementation to .cpp file +/* static PyObject* PyUIEntity_at(PyUIEntityObject* self, PyObject* o) { int x, y; @@ -144,10 +147,11 @@ static PyObject* PyUIEntity_at(PyUIEntityObject* self, PyObject* o) obj->entity = self->data; return (PyObject*)obj; } +*/ //TODO: add this static array to class scope; move implementation to .cpp file static PyMethodDef PyUIEntity_methods[] = { - {"at", (PyCFunction)PyUIEntity_at, METH_O}, + {"at", (PyCFunction)UIEntity::at, METH_O}, {NULL, NULL, 0, NULL} }; @@ -161,7 +165,7 @@ static PyGetSetDef PyUIEntity_getsetters[] = { }; //TODO: add this method to class scope; forward declaration not required after .h/.cpp split -static int PyUIEntity_init(PyUIEntityObject*, PyObject*, PyObject*); // forward declare +//static int PyUIEntity_init(PyUIEntityObject*, PyObject*, PyObject*); // forward declare // Define the PyTypeObject for UIEntity @@ -175,7 +179,7 @@ static PyTypeObject PyUIEntityType = { .tp_doc = "UIEntity objects", .tp_methods = PyUIEntity_methods, .tp_getset = PyUIEntity_getsetters, - .tp_init = (initproc)PyUIEntity_init, + .tp_init = (initproc)UIEntity::init, .tp_new = PyType_GenericNew, }; } diff --git a/src/UIFrame.cpp b/src/UIFrame.cpp index 6cebd9a..c9f42e8 100644 --- a/src/UIFrame.cpp +++ b/src/UIFrame.cpp @@ -54,6 +54,16 @@ void UIFrame::render(sf::Vector2f offset) } } +PyObject* PyUIFrame::get_children(PyUIFrameObject* self, void* closure) +{ + // create PyUICollection instance pointing to self->data->children + PyUICollectionObject* o = (PyUICollectionObject*)PyUICollectionType.tp_alloc(&PyUICollectionType, 0); + if (o) + o->data = self->data->children; + return (PyObject*)o; +} + + namespace mcrfpydef { // TODO: move to class scope; but this should at least get us compiling diff --git a/src/UIFrame.h b/src/UIFrame.h index c51f042..356f0cb 100644 --- a/src/UIFrame.h +++ b/src/UIFrame.h @@ -10,6 +10,14 @@ #include "PyColor.h" #include "PyVector.h" #include "UIDrawable.h" +#include "UIBase.h" + +//class UIFrame; +// +//typedef struct { +// PyObject_HEAD +// std::shared_ptr data; +//} PyUIFrameObject; class UIFrame: public UIDrawable { @@ -24,12 +32,9 @@ public: void move(sf::Vector2f); PyObjectsEnum derived_type() override final; virtual UIDrawable* click_at(sf::Vector2f point) override final; -}; -typedef struct { - PyObject_HEAD - std::shared_ptr data; -} PyUIFrameObject; + static PyObject* get_children(PyUIFrameObject* self, void* closure); +}; namespace mcrfpydef { //TODO: add this method to class scope; move implementation to .cpp file @@ -173,7 +178,7 @@ namespace mcrfpydef { } //TODO: add this method to class scope; move implementation to .cpp file - static PyObject* PyUIFrame_get_children(PyUIFrameObject*, void*); // forward declaration until UICollection is defined + //static PyObject* PyUIFrame_get_children(PyUIFrameObject*, void*); // forward declaration until UICollection is defined // implementation after the PyUICollectionType definition //TODO: add this static array to class scope; move implementation to .cpp file @@ -185,8 +190,8 @@ namespace mcrfpydef { {"outline", (getter)PyUIFrame_get_float_member, (setter)PyUIFrame_set_float_member, "Thickness of the border", (void*)4}, {"fill_color", (getter)PyUIFrame_get_color_member, (setter)PyUIFrame_set_color_member, "Fill color of the rectangle", (void*)0}, {"outline_color", (getter)PyUIFrame_get_color_member, (setter)PyUIFrame_set_color_member, "Outline color of the rectangle", (void*)1}, - {"children", (getter)PyUIFrame_get_children, NULL, "UICollection of objects on top of this one", NULL}, - {"click", (getter)PyUIDrawable_get_click, (setter)PyUIDrawable_set_click, "Object called with (x, y, button) when clicked", (void*)PyObjectsEnum::UIFRAME}, + {"children", (getter)UIFrame::get_children, NULL, "UICollection of objects on top of this one", NULL}, + {"click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click, "Object called with (x, y, button) when clicked", (void*)PyObjectsEnum::UIFRAME}, {NULL} }; diff --git a/src/UIGrid.h b/src/UIGrid.h index e55026b..a67fc2a 100644 --- a/src/UIGrid.h +++ b/src/UIGrid.h @@ -15,6 +15,7 @@ #include "UIGridPoint.h" #include "UIEntity.h" #include "UIDrawable.h" +#include "UIBase.h" class UIGrid: public UIDrawable { @@ -43,11 +44,11 @@ public: std::shared_ptr>> entities; }; -typedef struct { - PyObject_HEAD - std::shared_ptr data; - //PyObject* texture; -} PyUIGridObject; +//typedef struct { +// PyObject_HEAD +// std::shared_ptr data; +// //PyObject* texture; +//} PyUIGridObject; namespace mcrfpydef { //TODO: add this method to class scope; move implementation to .cpp file @@ -257,7 +258,7 @@ static PyGetSetDef PyUIGrid_getsetters[] = { {"center_y", (getter)PyUIGrid_get_float_member, (setter)PyUIGrid_set_float_member, "center of the view Y-coordinate", (void*)5}, {"zoom", (getter)PyUIGrid_get_float_member, (setter)PyUIGrid_set_float_member, "zoom factor for displaying the Grid", (void*)6}, - {"click", (getter)PyUIDrawable_get_click, (setter)PyUIDrawable_set_click, "Object called with (x, y, button) when clicked", (void*)PyObjectsEnum::UIGRID}, + {"click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click, "Object called with (x, y, button) when clicked", (void*)PyObjectsEnum::UIGRID}, {"texture", (getter)PyUIGrid_get_texture, NULL, "Texture of the grid", NULL}, //TODO 7DRL-day2-item5 {NULL} /* Sentinel */ diff --git a/src/UIGridPoint.h b/src/UIGridPoint.h index e611ff7..147f0d9 100644 --- a/src/UIGridPoint.h +++ b/src/UIGridPoint.h @@ -29,6 +29,8 @@ public: bool visible, discovered; }; +class UIGrid; + typedef struct { PyObject_HEAD UIGridPoint* data; diff --git a/src/UISprite.h b/src/UISprite.h index 4397c2c..dc9faf8 100644 --- a/src/UISprite.h +++ b/src/UISprite.h @@ -42,10 +42,10 @@ public: PyObjectsEnum derived_type() override final; }; -typedef struct { - PyObject_HEAD - std::shared_ptr data; -} PyUISpriteObject; +//typedef struct { +// PyObject_HEAD +// std::shared_ptr data; +//} PyUISpriteObject; namespace mcrfpydef { //TODO: add this method to class scope; move implementation to .cpp file @@ -143,7 +143,7 @@ namespace mcrfpydef { {"scale", (getter)PyUISprite_get_float_member, (setter)PyUISprite_set_float_member, "Size factor", (void*)2}, {"sprite_number", (getter)PyUISprite_get_int_member, (setter)PyUISprite_set_int_member, "Which sprite on the texture is shown", NULL}, {"texture", (getter)PyUISprite_get_texture, (setter)PyUISprite_set_texture, "Texture object", NULL}, - {"click", (getter)PyUIDrawable_get_click, (setter)PyUIDrawable_set_click, "Object called with (x, y, button) when clicked", (void*)PyObjectsEnum::UISPRITE}, + {"click", (getter)UIDrawable::get_click, (setter)UIDrawable::set_click, "Object called with (x, y, button) when clicked", (void*)PyObjectsEnum::UISPRITE}, {NULL} };