diff --git a/src/PyColor.cpp b/src/PyColor.cpp index 9d001df..434a963 100644 --- a/src/PyColor.cpp +++ b/src/PyColor.cpp @@ -8,149 +8,46 @@ PyGetSetDef PyColor::getsetters[] = { {NULL} }; -PyColor::PyColor(_PyColorData d) -{ - data = d; - if (data.index == PyColor::SELF_OWNED) data.index = PyColor::BORROWED; // I think this is a bad idea, but the alternatives come with their own mess -} - -PyColor::PyColor(sf::Color* target, std::weak_ptr parent, int index) -{ - data.index = index; - data.parent = parent; - data.target = target; - data.setter = NULL; - data.getter = NULL; -} - PyColor::PyColor(sf::Color target) -{ - data.index = PyColor::SELF_OWNED; - data.parent = std::weak_ptr(); - data.target = new sf::Color; - data.setter = NULL; - data.getter = NULL; -} - -PyColor::PyColor(sf::Color (*getter)(), void (*setter)(sf::Color), std::weak_ptr parent, int index) -{ - data.index = index; - data.parent = parent; - data.target = NULL; - data.setter = setter; - data.getter = getter; - -} - -PyColor::~PyColor() -{ - if (data.index == PyColor::SELF_OWNED) - delete data.target; -} +:data(target) {} PyObject* PyColor::pyObject() { PyObject* obj = PyType_GenericAlloc(&mcrfpydef::PyColorType, 0); PyColorObject* self = (PyColorObject*)obj; self->data = data; - if (data.index == PyColor::SELF_OWNED) self->data.index = PyColor::BORROWED; return obj; } -PyColor PyColor::fromPy(PyObject* obj) +sf::Color PyColor::fromPy(PyObject* obj) { PyColorObject* self = (PyColorObject*)obj; - return PyColor(self->data); + return self->data; } -PyColor PyColor::fromPy(PyColorObject* self) +sf::Color PyColor::fromPy(PyColorObject* self) { - return PyColor(self->data); + return self->data; } void PyColor::set(sf::Color color) { - auto ptr = data.parent.lock(); - if (ptr || data.index == PyColor::SELF_OWNED) - { - if (data.setter) - data.setter(color); - else - *data.target = color; - } + data = color; } sf::Color PyColor::get() { - auto ptr = data.parent.lock(); - if (ptr || data.index == PyColor::SELF_OWNED) - { - if (data.getter) - return data.getter(); - else - return *(data.target); - } - return sf::Color(0, 0, 0, 0); -} - -bool PyColor::alive() -{ - if (data.index == PyColor::SELF_OWNED) return true; - return !data.parent.lock(); -} - -std::string PyColor::field() -{ - switch (data.index) - { - case PyColor::SELF_OWNED: - return "None"; - break; - case 0: - return "fill"; - break; - case 1: - return "outline"; - break; - case 2: - return "background"; - break; - default: - return "unknown"; - break; - } -} - -std::string PyColor::mode() -{ - if (data.index == PyColor::SELF_OWNED) return "self-owned value"; - else if (data.index == PyColor::BORROWED) return "self-owned value (borrowed)"; - else if (data.getter || data.setter) - { - if (alive()) return "callback passthrough"; - else return "callback passthrough (dangling; parent dead)"; - } - else if (alive()) return "linked pointer"; - else return "linked pointer (dangling; parent dead)"; + return data; } Py_hash_t PyColor::hash(PyObject* obj) { auto self = (PyColorObject*)obj; Py_hash_t value = 0; - auto ptr = self->data.parent.lock(); - if (ptr || self->data.index == PyColor::SELF_OWNED) - { - value += self->data.target->r; - value << 8; value += self->data.target->g; - value << 8; value += self->data.target->b; - value << 8; value += self->data.target->a; - } - if (ptr) - { - //value << (sizeof(*UIDrawable) * 8); - value += reinterpret_cast(&ptr); - } + value += self->data.r; + value << 8; value += self->data.g; + value << 8; value += self->data.b; + value << 8; value += self->data.a; return value; } @@ -159,9 +56,8 @@ PyObject* PyColor::repr(PyObject* obj) { PyColorObject* self = (PyColorObject*)obj; std::ostringstream ss; - PyColor color = PyColor(self->data); - sf::Color c = color.get(); - ss << ""; + sf::Color c = self->data; + ss << ""; std::string repr_str = ss.str(); return PyUnicode_DecodeUTF8(repr_str.c_str(), repr_str.size(), "replace"); @@ -171,6 +67,7 @@ PyObject* PyColor::repr(PyObject* obj) int PyColor::init(PyColorObject* self, PyObject* args, PyObject* kwds) { static const char* keywords[] = { "r", "g", "b", "a", nullptr }; + // TODO return 0; } diff --git a/src/PyColor.h b/src/PyColor.h index 6d0d35a..a111b89 100644 --- a/src/PyColor.h +++ b/src/PyColor.h @@ -5,41 +5,22 @@ class PyColor; class UIDrawable; // forward declare for pointer -typedef struct { - sf::Color* target; // color target to set/get - std::weak_ptr parent; // lifetime management: parent must still exist - int index; // specific to the parent class, which color is it? - sf::Color(*getter)(); - void(*setter)(sf::Color); -} _PyColorData; - typedef struct { PyObject_HEAD - _PyColorData data; + sf::Color data; } PyColorObject; class PyColor { private: - _PyColorData data; - static const int SELF_OWNED = -1; - static const int BORROWED = -2; - PyColor(_PyColorData); // private constructor / for operations transferring between C++ and Python - public: - PyColor(sf::Color* target, std::weak_ptr parent, int index); // linked constructor - PyColor(sf::Color target); // simple color container - PyColor(sf::Color (*)(), void (*)(sf::Color), std::weak_ptr, int); - ~PyColor(); - void set(sf::Color); // change target value, behavior determined by the mode - sf::Color get(); // retrieve target value, behavior determined by the mode - PyObject* pyParent(); // UIDrawable derived parent object or None - std::string field(); // interpret the index as a field's name on UIDrawable - std::string mode(); // "value" for SELF_OWNED, "linked" for pointer, and "passthrough" for callbacks - bool alive(); // true if SELF_OWNED or parent still exists + sf::Color data; + PyColor(sf::Color); + void set(sf::Color); + sf::Color get(); PyObject* pyObject(); - static PyColor fromPy(PyObject*); - static PyColor fromPy(PyColorObject*); + static sf::Color fromPy(PyObject*); + static sf::Color fromPy(PyColorObject*); static PyObject* repr(PyObject*); static Py_hash_t hash(PyObject*); static int init(PyColorObject*, PyObject*, PyObject*); @@ -48,47 +29,8 @@ public: static int set_member(PyObject*, PyObject*, void*); static PyGetSetDef getsetters[]; - /*static PyGetSetDef getsetters[] = { - {"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 = { -// //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(); -// return (PyObject*)self; -// } -// }; - namespace mcrfpydef { static PyTypeObject PyColorType = { .tp_name = "mcrfpy.Color", diff --git a/src/PyLinkedColor.cpp b/src/PyLinkedColor.cpp index d509ab8..cc0b02d 100644 --- a/src/PyLinkedColor.cpp +++ b/src/PyLinkedColor.cpp @@ -1,10 +1,12 @@ #include "PyLinkedColor.h" +#include "PyColor.h" PyGetSetDef PyLinkedColor::getsetters[] = { {"r", (getter)PyLinkedColor::get_member, (setter)PyLinkedColor::set_member, "Red component", (void*)0}, {"g", (getter)PyLinkedColor::get_member, (setter)PyLinkedColor::set_member, "Green component", (void*)1}, {"b", (getter)PyLinkedColor::get_member, (setter)PyLinkedColor::set_member, "Blue component", (void*)2}, {"a", (getter)PyLinkedColor::get_member, (setter)PyLinkedColor::set_member, "Alpha component", (void*)3}, + {"color", (getter)PyLinkedColor::get_member, (setter)PyLinkedColor::set_member, "RGBA as mcrfpy.Color", (void*)4}, {NULL} }; @@ -116,19 +118,34 @@ PyObject* PyLinkedColor::repr(PyObject* obj) std::ostringstream ss; PyLinkedColor color = PyLinkedColor(self->data); sf::Color c = color.get(); - ss << ""; + ss << "data.parent.lock(); + if (!ptr) + { + ss << " [dead link]"; + } + else + { + switch (ptr->derived_type()) + { + case PyObjectsEnum::UIFRAME: + break; + } + } + ss << ">"; std::string repr_str = ss.str(); return PyUnicode_DecodeUTF8(repr_str.c_str(), repr_str.size(), "replace"); } - +/* int PyLinkedColor::init(PyLinkedColorObject* self, PyObject* args, PyObject* kwds) { // TODO static const char* keywords[] = { "r", "g", "b", "a", nullptr }; return 0; } +*/ PyObject* PyLinkedColor::pynew(PyTypeObject* type, PyObject* args, PyObject* kwds) { @@ -137,10 +154,56 @@ PyObject* PyLinkedColor::pynew(PyTypeObject* type, PyObject* args, PyObject* kwd PyObject* PyLinkedColor::get_member(PyObject* obj, void* closure) { - return Py_None; // TODO + PyLinkedColorObject* self = (PyLinkedColorObject*)obj; + PyLinkedColor color = PyLinkedColor(self->data); + sf::Color c = color.get(); + auto var = reinterpret_cast(closure); + + if (var == 0) + return PyLong_FromLong(c.r); + else if (var == 1) + return PyLong_FromLong(c.g); + else if (var == 2) + return PyLong_FromLong(c.b); + else if (var == 3) + return PyLong_FromLong(c.a); + else if (var == 4) + return PyColor(c).pyObject(); + return Py_None; } int PyLinkedColor::set_member(PyObject* obj, PyObject* value, void* closure) { - return 0; // TODO + PyLinkedColorObject* self = (PyLinkedColorObject*)obj; + PyLinkedColor color = PyLinkedColor(self->data); + sf::Color c = color.get(); + auto var = reinterpret_cast(closure); + + if (var == 4) + { + // cheat - call mcrfpy.Color __init__ on the value (don't duplicate arg parsing code) + PyObject* newcolor = PyType_GenericAlloc(&mcrfpydef::PyColorType, 0); + mcrfpydef::PyColorType.tp_init(newcolor, value, NULL); + if (PyErr_Occurred()) return -1; + auto newc = PyColor::fromPy(newcolor); + color.set(newc); + Py_DECREF(newcolor); + } + + long val = PyLong_AsLong(value); + if (PyErr_Occurred()) return -1; + if (val > 255 || val < 0) + { + PyErr_SetString(PyExc_ValueError, "Color values must be between 0 and 255"); + return -1; + } + if (var == 0) + color.set(sf::Color(val, c.g, c.b, c.a)); + else if (var == 1) + color.set(sf::Color(c.r, val, c.b, c.a)); + else if (var == 2) + color.set(sf::Color(c.r, c.g, val, c.a)); + else if (var == 3) + color.set(sf::Color(c.r, c.g, c.b, val)); + return 0; } diff --git a/src/PyLinkedColor.h b/src/PyLinkedColor.h index f41331e..e629c27 100644 --- a/src/PyLinkedColor.h +++ b/src/PyLinkedColor.h @@ -4,7 +4,34 @@ #include class PyLinkedColor; -class UIDrawable; // forward declare for pointer +//class UIDrawable; // forward declare for pointer +class PyClickCallable; + +// TODO - after UI.h gets broken up, this can go into a separate base class, since only derived classes use PyLinkedColor +#ifndef ui_h +enum PyObjectsEnum : int +{ + UIFRAME = 1, + UICAPTION, + UISPRITE, + UIGRID +}; + +class UIDrawable +{ +public: + void render(); + virtual void render(sf::Vector2f) = 0; + virtual PyObjectsEnum derived_type() = 0; + + std::unique_ptr click_callable; + virtual UIDrawable* click_at(sf::Vector2f point) = 0; + void click_register(PyObject*); + void click_unregister(); + + UIDrawable(); +}; +#endif typedef struct { std::weak_ptr parent; // lifetime management: parent must still exist @@ -56,7 +83,7 @@ namespace mcrfpydef { .tp_flags = Py_TPFLAGS_DEFAULT, .tp_doc = PyDoc_STR("SFML Color Object - Linked to UIDrawable Field"), .tp_getset = PyLinkedColor::getsetters, - .tp_init = (initproc)PyLinkedColor::init, + //.tp_init = (initproc)PyLinkedColor::init, .tp_new = PyLinkedColor::pynew, }; } diff --git a/src/UI.h b/src/UI.h index 82610f0..384cfda 100644 --- a/src/UI.h +++ b/src/UI.h @@ -5,6 +5,9 @@ #include "IndexTexture.h" #include "Resources.h" #include + +#define ui_h + #include "PyCallable.h" #include "PyTexture.h" #include "PyColor.h" @@ -929,9 +932,10 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c // initialize new mcrfpy.Color instance //pyColorObj->data = std::make_shared(color); - PyColor::fromPy(pyColorObj).set(color); + //PyColor::fromPy(pyColorObj).set(color); - return pyColor; + // TODO - supposed to return Linked + return PyColor(color).pyObject(); } static int PyUIFrame_set_color_member(PyUIFrameObject* self, PyObject* value, void* closure) @@ -950,7 +954,7 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c a = color->data->a; std::cout << "using color: " << r << " " << g << " " << b << " " << a << std::endl; */ - sf::Color c = PyColor::fromPy(value).get(); + sf::Color c = ((PyColorObject*)value)->data; r = c.r; g = c.g; b = c.b; a = c.a; } else if (!PyTuple_Check(value) || PyTuple_Size(value) < 3 || PyTuple_Size(value) > 4) diff --git a/src/scripts/game.py b/src/scripts/game.py index c022aca..2975588 100644 --- a/src/scripts/game.py +++ b/src/scripts/game.py @@ -130,7 +130,7 @@ logo_sprite = mcrfpy.Sprite(50, 50, logo_texture, 0, 0.5) ui.append(logo_sprite) logo_sprite.click = lambda *args: mcrfpy.setScene("menu") logo_caption = mcrfpy.Caption(70, 600, "Click to Proceed", font, (255, 0, 0, 255), (0, 0, 0, 255)) -logo_caption.fill_color =(255, 0, 0, 255) +#logo_caption.fill_color =(255, 0, 0, 255) ui.append(logo_caption) @@ -186,7 +186,7 @@ mcrfpy.createScene("settings") window_scaling = 1.0 scale_caption = mcrfpy.Caption(180, 70, "1.0x", font, (255, 255, 255), (0, 0, 0)) -scale_caption.fill_color = (255, 255, 255) # TODO - mcrfpy.Caption.__init__ is not setting colors +#scale_caption.fill_color = (255, 255, 255) # TODO - mcrfpy.Caption.__init__ is not setting colors for e in [ mcrfpy.Caption(10, 10, "Settings", font, (255, 255, 255), (0, 0, 0)), mcrfpy.Frame(15, 70, 150, 60, fill_color=(64, 64, 128)), # +