Compare commits

..

2 Commits

13 changed files with 241 additions and 64 deletions

View File

@ -28,36 +28,12 @@ sf::Sprite PyTexture::sprite(int index, sf::Vector2f pos, sf::Vector2f s)
PyObject* PyTexture::pyObject()
{
// method 1: works but with type weirdness
//PyObject* obj = PyType_GenericAlloc(&mcrfpydef::PyTextureType, 0);
//Py_SET_TYPE(obj, &mcrfpydef::PyTextureType);
// method 2: does not work (segfault on use of the mcrfpy.Texture object)
//PyObject* obj = PyTexture::pynew(&mcrfpydef::PyTextureType, Py_None, Py_None);
// method 3: does not work (segfault on use of the mcrfpy.Texture object)
std::cout << "Find type" << std::endl;
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Texture");
//auto type = obj->ob_type;
//auto type = &mcrfpydef::PyTextureType;
//std::cout << "assigned value 0x" << std::hex << reinterpret_cast<long>(type) << std::endl;
//std::cout << "Found PyTextureType: " << PyUnicode_AsUTF8(PyObject_Repr((PyObject*)type)) << std::endl;
//std::cout << "PyTextureType metatype: " << PyUnicode_AsUTF8(PyObject_Repr((PyObject_Type((PyObject*)type)))) << std::endl;
//std::cout << "tp_alloc: 0x" << std::hex << reinterpret_cast <long>(type->tp_alloc) << std::endl <<
// "tp_new: 0x" << std::hex << reinterpret_cast<long>(type->tp_new) << std::endl;
//PyObject* obj = ((PyTypeObject*)type)->tp_new((PyTypeObject*)type, Py_None, Py_None);
PyObject* obj = PyTexture::pynew(type, Py_None, Py_None);
//Py_SET_TYPE(obj, type);
// method 4: call the type object?
std::cout << "Instantiated" << std::endl;
//Py_SET_TYPE(obj, &mcrfpydef::PyTextureType);
//PyObject_CallFunction(&mcrfpydef::PyTextureType,
try {
((PyTextureObject*)obj)->data = shared_from_this();
std::cout << "Sideloaded texture: " << PyUnicode_AsUTF8(PyObject_Repr(obj)) << std::endl;
}
catch (std::bad_weak_ptr& e)
{

32
src/UIBase.h Normal file
View File

@ -0,0 +1,32 @@
#pragma once
class UIEntity;
typedef struct {
PyObject_HEAD
std::shared_ptr<UIEntity> data;
} PyUIEntityObject;
class UIFrame;
typedef struct {
PyObject_HEAD
std::shared_ptr<UIFrame> data;
} PyUIFrameObject;
class UICaption;
typedef struct {
PyObject_HEAD
std::shared_ptr<UICaption> data;
PyObject* font;
} PyUICaptionObject;
class UIGrid;
typedef struct {
PyObject_HEAD
std::shared_ptr<UIGrid> data;
} PyUIGridObject;
class UISprite;
typedef struct {
PyObject_HEAD
std::shared_ptr<UISprite> data;
} PyUISpriteObject;

View File

@ -1,4 +1,5 @@
#include "UICaption.h"
#include "GameEngine.h"
UIDrawable* UICaption::click_at(sf::Vector2f point)
{

View File

@ -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<UICaption> data;
PyObject* font;
} PyUICaptionObject;
//class UICaption;
//typedef struct {
// PyObject_HEAD
// std::shared_ptr<UICaption> 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}
};

View File

@ -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<PyObjectsEnum>(reinterpret_cast<long>(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<PyObjectsEnum>(reinterpret_cast<long>(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;
}

View File

@ -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<PyObjectsEnum>(reinterpret_cast<long>(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<PyObjectsEnum>(reinterpret_cast<long>(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;
}
*/
}

View File

@ -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<UIEntity>(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<char**>(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<UIEntity>();
else
self->data = std::make_shared<UIEntity>(*((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;
}

View File

@ -14,9 +14,15 @@
#include "UIGridPoint.h"
#include "UIDrawable.h"
#include "UIBase.h"
class UIGrid;
//class UIEntity;
//typedef struct {
// PyObject_HEAD
// std::shared_ptr<UIEntity> 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<UIEntity> 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,
};
}

View File

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

View File

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

View File

@ -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<std::list<std::shared_ptr<UIEntity>>> entities;
};
typedef struct {
PyObject_HEAD
std::shared_ptr<UIGrid> data;
//PyObject* texture;
} PyUIGridObject;
//typedef struct {
// PyObject_HEAD
// std::shared_ptr<UIGrid> 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 */

View File

@ -29,6 +29,8 @@ public:
bool visible, discovered;
};
class UIGrid;
typedef struct {
PyObject_HEAD
UIGridPoint* data;

View File

@ -42,10 +42,10 @@ public:
PyObjectsEnum derived_type() override final;
};
typedef struct {
PyObject_HEAD
std::shared_ptr<UISprite> data;
} PyUISpriteObject;
//typedef struct {
// PyObject_HEAD
// std::shared_ptr<UISprite> 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}
};