checkpoint: found that py_instance causes segfaults when called separately, but the same exact code inside of the _getitem method works fine. I can't explain that. I guess I'll turn it into a macro so the actions are inline and I can move on to finishing the other UI classes.

This commit is contained in:
John McCardle 2023-09-03 12:46:23 -04:00
parent b8af8bc870
commit 5267287b05
3 changed files with 187 additions and 22 deletions

View File

@ -131,6 +131,8 @@ PyObject* PyInit_mcrfpy()
Py_DECREF(&mcrfpydef::PyUIFrameType); Py_DECREF(&mcrfpydef::PyUIFrameType);
return NULL; return NULL;
} }
PyModule_AddType(m, &mcrfpydef::PyUICollectionType);
PyModule_AddType(m, &mcrfpydef::PyUICollectionIterType);
return m; return m;
@ -1124,11 +1126,21 @@ PyObject* McRFPy_API::_camFollow(PyObject* self, PyObject* args) {
//McRFPy_API::_sceneUI //McRFPy_API::_sceneUI
PyObject* McRFPy_API::_sceneUI(PyObject* self, PyObject* args) { PyObject* McRFPy_API::_sceneUI(PyObject* self, PyObject* args) {
using namespace mcrfpydef;
const char *scene_cstr; const char *scene_cstr;
if (!PyArg_ParseTuple(args, "s", &scene_cstr)) return NULL; if (!PyArg_ParseTuple(args, "s", &scene_cstr)) return NULL;
auto ui = Resources::game->scene_ui("uitest"); auto ui = Resources::game->scene_ui(scene_cstr);
if(ui) std::cout << "vector returned has size=" << ui->size() << std::endl; if(!ui)
Py_INCREF(Py_None); {
return Py_None; PyErr_SetString(PyExc_RuntimeError, "No scene found by that name");
return NULL;
}
//std::cout << "vector returned has size=" << ui->size() << std::endl;
//Py_INCREF(Py_None);
//return Py_None;
PyUICollectionObject* o = (PyUICollectionObject*)PyUICollectionType.tp_alloc(&PyUICollectionType, 0);
if (o)
o->data = ui;
return (PyObject*)o;
} }

View File

@ -101,33 +101,101 @@ PyObjectsEnum UISprite::derived_type()
return PyObjectsEnum::UISPRITE; return PyObjectsEnum::UISPRITE;
} }
PyObject* py_instance(std::shared_ptr<UIDrawable> source) PyObject* mcrfpydef::py_instance(std::shared_ptr<UIDrawable> source)
{ {
// takes a UI drawable, calls its derived_type virtual function, and builds a Python object based on the return value. // takes a UI drawable, calls its derived_type virtual function, and builds a Python object based on the return value.
using namespace mcrfpydef; //using namespace mcrfpydef;
PyObject* newobj;
PyTypeObject* colorType = &PyColorType;
PyObject* pyColor = colorType->tp_alloc(colorType, 0);
if (pyColor == NULL)
{
std::cout << "failure to allocate mcrfpy.Color / PyColorType" << std::endl;
return NULL;
}
PyColorObject* pyColorObj = reinterpret_cast<PyColorObject*>(pyColor);
pyColorObj->data = std::make_shared<sf::Color>();
pyColorObj->data-> r = 255;
return (PyObject*)pyColorObj;
PyObject* newobj = NULL;
std::cout << "py_instance called\n";
switch (source->derived_type()) switch (source->derived_type())
{ {
case PyObjectsEnum::UIFRAME: case PyObjectsEnum::UIFRAME:
{
std::cout << "UIFRAME case\n" << std::flush;
PyTypeObject* UIFrameType = &PyUIFrameType;
//std::cout << "tp_alloc\n" << std::flush;
//PyObject* _o = UIFrameType->tp_alloc(UIFrameType, 0);
//std::cout << "reinterpret_cast\n" << std::flush;
//auto o = reinterpret_cast<PyUICollectionObject*>(_o);
//PyUIFrameObject* o = (PyUIFrameObject*)PyObject_New(PyUIFrameObject, UIFrameType);
PyUIFrameObject* o = (PyUIFrameObject*)(UIFrameType->tp_alloc(UIFrameType, 0));
//PyUIFrameObject* o = PyObject_New(PyUIFrameObject, UIFrameType);
/*
// backtracking the problem: instantiate a PyColor of (255, 0, 0) for testing
PyTypeObject* colorType = &PyColorType;
PyObject* pyColor = colorType->tp_alloc(colorType, 0);
if (pyColor == NULL)
{ {
PyUIFrameObject* o = (PyUIFrameObject*)PyUIFrameType.tp_alloc(&PyUIFrameType, 0); std::cout << "failure to allocate mcrfpy.Color / PyColorType" << std::endl;
if (o) return NULL;
o->data = std::static_pointer_cast<UIFrame>(source);
newobj = (PyObject*)o;
break;
} }
/* not yet implemented PyColorObject* pyColorObj = reinterpret_cast<PyColorObject*>(pyColor);
pyColorObj->data = std::make_shared<sf::Color>();
pyColorObj->data-> r = 255;
return (PyObject*)pyColorObj;
*/
std::cout << "pointer check: " << o << "\n" << std::flush;
if (o)
{
std::cout << "Casting data...\n" << std::flush;
auto p = std::static_pointer_cast<UIFrame>(source);
std::cout << "casted. Assigning...\n" << std::flush;
//o->data = std::make_shared<UIFrame>();
o->data = p;
//std::cout << "assigned.\n" << std::flush;
auto usource = o->data; //(UIFrame*)source.get();
std::cout << "Loaded data into object. " << usource->box.getPosition().x << " " << usource->box.getPosition().y << " " <<
usource->box.getSize().x << " " << usource->box.getSize().y << std::endl;
}
else
{
std::cout << "Allocation failed.\n" << std::flush;
}
newobj = (PyObject*)o;
break;
}
case PyObjectsEnum::UICAPTION: case PyObjectsEnum::UICAPTION:
{
std::cout << "UICAPTION case\n";
PyErr_SetString(PyExc_NotImplementedError, "UICaption class not implemented in Python yet.");
/* not yet implemented
PyUICaptionObject* o = (PyUICaptionObject*)PyUICaptionType.tp_alloc(&PyUICaptionType, 0); PyUICaptionObject* o = (PyUICaptionObject*)PyUICaptionType.tp_alloc(&PyUICaptionType, 0);
if (o) if (o)
o->data = std::static_pointer_cast<UICaption>(source); o->data = std::static_pointer_cast<UICaption>(source);
*/
break; break;
}
case PyObjectsEnum::UISPRITE: case PyObjectsEnum::UISPRITE:
{
std::cout << "UISPRITE case\n";
PyErr_SetString(PyExc_NotImplementedError, "UISprite class not implemented in Python yet.");
/*
PyUISpriteObject* o = (PyUISpriteObject*)PyUISpriteType.tp_alloc(&PyUISpriteType, 0); PyUISpriteObject* o = (PyUISpriteObject*)PyUISpriteType.tp_alloc(&PyUISpriteType, 0);
if (o) if (o)
o->data = std::static_pointer_cast<UISprite>(source); o->data = std::static_pointer_cast<UISprite>(source);
*/
break; break;
*/ }
default: default:
return NULL; return NULL;
break; break;

101
src/UI.h
View File

@ -113,9 +113,9 @@ typedef struct {
std::shared_ptr<UISprite> data; std::shared_ptr<UISprite> data;
} PyUISpriteObject; } PyUISpriteObject;
PyObject* py_instance(std::shared_ptr<UIDrawable> source);
namespace mcrfpydef { namespace mcrfpydef {
PyObject* py_instance(std::shared_ptr<UIDrawable> source);
// Color Definitions // Color Definitions
// struct, members, new, set_member, PyTypeObject // struct, members, new, set_member, PyTypeObject
@ -373,11 +373,8 @@ namespace mcrfpydef {
return 0; return 0;
} }
static PyObject* PyUIFrame_get_children(PyUIFrameObject* self, void* closure) static PyObject* PyUIFrame_get_children(PyUIFrameObject*, void*);
{ // implementation after the PyUICollectionType definition
// create PyUICollection instance pointing to self->data->children
return NULL;
}
static PyGetSetDef PyUIFrame_getsetters[] = { static PyGetSetDef PyUIFrame_getsetters[] = {
{"x", (getter)PyUIFrame_get_float_member, (setter)PyUIFrame_set_float_member, "X coordinate of top-left corner", (void*)0}, {"x", (getter)PyUIFrame_get_float_member, (setter)PyUIFrame_set_float_member, "X coordinate of top-left corner", (void*)0},
@ -424,6 +421,8 @@ namespace mcrfpydef {
//self->data->x = x; //self->data->x = x;
//self->data->y = y; //self->data->y = y;
self->data->box.setFillColor(sf::Color(0,0,0,255));
self->data->box.setOutlineColor(sf::Color(128,128,128,255));
return 0; return 0;
} }
@ -509,7 +508,7 @@ namespace mcrfpydef {
return NULL; return NULL;
} }
if (self->index > self->start_size) if (self->index > self->start_size - 1)
{ {
PyErr_SetNone(PyExc_StopIteration); PyErr_SetNone(PyExc_StopIteration);
return NULL; return NULL;
@ -521,8 +520,9 @@ namespace mcrfpydef {
PyErr_SetString(PyExc_RuntimeError, "the collection store returned a null pointer"); PyErr_SetString(PyExc_RuntimeError, "the collection store returned a null pointer");
return NULL; return NULL;
} }
auto target = vec[self->index-1]; auto target = (*vec)[self->index-1];
// TODO build PyObject* of the correct UIDrawable subclass to return // TODO build PyObject* of the correct UIDrawable subclass to return
return py_instance(target);
} }
static PyObject* PyUICollectionIter_repr(PyUICollectionIterObject* self) static PyObject* PyUICollectionIter_repr(PyUICollectionIterObject* self)
@ -588,6 +588,79 @@ namespace mcrfpydef {
return NULL; return NULL;
} }
// build a Python version of item at self->data[index] // build a Python version of item at self->data[index]
// Copy pasted::
auto vec = self->data.get();
if (!vec)
{
PyErr_SetString(PyExc_RuntimeError, "the collection store returned a null pointer");
return NULL;
}
while (index < 0) index += self->data->size();
if (index > self->data->size() - 1)
{
PyErr_SetString(PyExc_IndexError, "UICollection index out of range");
return NULL;
}
auto target = (*vec)[index];
// TODO build PyObject* of the correct UIDrawable subclass to return
//return py_instance(target);
/*
PyTypeObject* colorType = &PyColorType;
PyObject* pyColor = colorType->tp_alloc(colorType, 0);
if (pyColor == NULL)
{
std::cout << "failure to allocate mcrfpy.Color / PyColorType" << std::endl;
return NULL;
}
PyColorObject* pyColorObj = reinterpret_cast<PyColorObject*>(pyColor);
pyColorObj->data = std::make_shared<sf::Color>();
pyColorObj->data-> r = 255;
return (PyObject*)pyColorObj;
*/
PyObject* newobj = NULL;
std::cout << "Instantiating object\n";
switch (target->derived_type())
{
case PyObjectsEnum::UIFRAME:
{
std::cout << "UIFRAME case\n" << std::flush;
PyUIFrameObject* o = (PyUIFrameObject*)((&PyUIFrameType)->tp_alloc(&PyUIFrameType, 0));
if (o)
{
std::cout << "Casting data...\n" << std::flush;
auto p = std::static_pointer_cast<UIFrame>(target);
std::cout << "casted. Assigning...\n" << std::flush;
//o->data = std::make_shared<UIFrame>();
o->data = p;
//std::cout << "assigned.\n" << std::flush;
auto utarget = o->data; //(UIFrame*)target.get();
std::cout << "Loaded data into object. " << utarget->box.getPosition().x << " " << utarget->box.getPosition().y << " " <<
utarget->box.getSize().x << " " << utarget->box.getSize().y << std::endl;
}
else
{
std::cout << "Allocation failed.\n" << std::flush;
}
return (PyObject*)o;
}
}
return NULL;
} }
static PySequenceMethods PyUICollection_sqmethods = { static PySequenceMethods PyUICollection_sqmethods = {
@ -605,6 +678,7 @@ namespace mcrfpydef {
{ {
// if not UIDrawable subclass, reject it // if not UIDrawable subclass, reject it
// self->data->push_back( c++ object inside o ); // self->data->push_back( c++ object inside o );
return NULL; // TODO
} }
static PyObject* PyUICollection_remove(PyUICollectionObject* self, PyObject* o) static PyObject* PyUICollection_remove(PyUICollectionObject* self, PyObject* o)
@ -613,6 +687,7 @@ namespace mcrfpydef {
// long index = PyLong_AsLong(o); // long index = PyLong_AsLong(o);
// if (index >= self->data->size()) { //exception text; return -1; } // if (index >= self->data->size()) { //exception text; return -1; }
// release the shared pointer at self->data[index]; // release the shared pointer at self->data[index];
return NULL; // TODO
} }
static PyMethodDef PyUICollection_methods[] = { static PyMethodDef PyUICollection_methods[] = {
@ -694,6 +769,16 @@ namespace mcrfpydef {
*/ */
static 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 } // namespace mcrfpydef