Not bad for a quick first salvo, but I cannot figure out why init isn't cooperating.

This commit is contained in:
John McCardle 2024-03-30 22:32:28 -04:00
parent f82508b753
commit 1c12e8719c
4 changed files with 169 additions and 1 deletions

View File

@ -56,7 +56,7 @@ PyObject* PyInit_mcrfpy()
using namespace mcrfpydef;
PyTypeObject* pytypes[] = {
/*SFML exposed types*/
&PyColorType, /*&PyLinkedColorType,*/ &PyFontType, &PyTextureType,
&PyColorType, /*&PyLinkedColorType,*/ &PyFontType, &PyTextureType, &PyVectorType,
/*UI widgets*/
&PyUICaptionType, &PyUISpriteType, &PyUIFrameType, &PyUIEntityType, &PyUIGridType,

113
src/PyVector.cpp Normal file
View File

@ -0,0 +1,113 @@
#include "PyVector.h"
PyGetSetDef PyVector::getsetters[] = {
{"x", (getter)PyVector::get_member, (setter)PyVector::set_member, "X/horizontal component", (void*)0},
{"y", (getter)PyVector::get_member, (setter)PyVector::set_member, "Y/vertical component", (void*)1},
{NULL}
};
PyVector::PyVector(sf::Vector2f target)
:data(target) {}
PyObject* PyVector::pyObject()
{
PyObject* obj = PyType_GenericAlloc(&mcrfpydef::PyVectorType, 0);
Py_INCREF(obj);
PyVectorObject* self = (PyVectorObject*)obj;
self->data = data;
return obj;
}
sf::Vector2f PyVector::fromPy(PyObject* obj)
{
PyVectorObject* self = (PyVectorObject*)obj;
return self->data;
}
sf::Vector2f PyVector::fromPy(PyVectorObject* self)
{
return self->data;
}
Py_hash_t PyVector::hash(PyObject* obj)
{
auto self = (PyVectorObject*)obj;
Py_hash_t value = 0;
value += self->data.x;
value << 8; value += self->data.y;
return value;
}
PyObject* PyVector::repr(PyObject* obj)
{
PyVectorObject* self = (PyVectorObject*)obj;
std::ostringstream ss;
sf::Vector2f v = self->data;
ss << "<Vector (" << v.x << ", " << v.y << ")>";
std::string repr_str = ss.str();
return PyUnicode_DecodeUTF8(repr_str.c_str(), repr_str.size(), "replace");
}
int PyVector::init(PyVectorObject* self, PyObject* args, PyObject* kwds)
{
using namespace mcrfpydef;
static const char* keywords[] = { "x", "y", nullptr };
PyObject* leader;
double x=0, y=0;
if (!PyArg_ParseTupleAndKeywords, args, kwds, "|Of", leader, &y)
{
//PyErr_SetString(PyExc_TypeError, "mcrfpy.Vector requires a 2-tuple or two numeric values");
return 0;
}
// if the "r" arg is already a vector, yoink that color value
if (PyObject_IsInstance(leader, (PyObject*)&PyVectorType))
{
self->data = ((PyVectorObject*)leader)->data;
return 0;
}
// else if the "r" arg is a 3-tuple, initialize to (r, g, b, 255)
// (if the "r" arg is a 4-tuple, initialize to (r, g, b, a))
else if (PyTuple_Check(leader))
{
if (PyTuple_Size(leader) != 2)
{
PyErr_SetString(PyExc_TypeError, "Invalid tuple length: mcrfpy.Vector requires a 2-tuple");
return -1;
}
x = PyFloat_AsDouble(PyTuple_GetItem(leader, 0));
y = PyFloat_AsDouble(PyTuple_GetItem(leader, 1));
self->data = sf::Vector2f(x, y);
}
// else -
else if (!PyFloat_Check(leader) && !(PyLong_Check(leader)))
{
PyErr_SetString(PyExc_TypeError, "mcrfpy.Vector requires a 2-tuple or two numeric values");
return -1;
}
if (PyFloat_Check(leader)) x = PyFloat_AsDouble(leader);
else x = PyLong_AsDouble(leader);
self->data = sf::Vector2f(x, y);
return 0;
}
PyObject* PyVector::pynew(PyTypeObject* type, PyObject* args, PyObject* kwds)
{
return (PyObject*)type->tp_alloc(type, 0);
}
PyObject* PyVector::get_member(PyObject* obj, void* closure)
{
// TODO
return Py_None;
}
int PyVector::set_member(PyObject* obj, PyObject* value, void* closure)
{
// TODO
return 0;
}

42
src/PyVector.h Normal file
View File

@ -0,0 +1,42 @@
#pragma once
#include "Common.h"
#include "Python.h"
typedef struct {
PyObject_HEAD
sf::Vector2f data;
} PyVectorObject;
class PyVector
{
public:
sf::Vector2f data;
PyVector(sf::Vector2f);
PyVector();
PyObject* pyObject();
static sf::Vector2f fromPy(PyObject*);
static sf::Vector2f fromPy(PyVectorObject*);
static PyObject* repr(PyObject*);
static Py_hash_t hash(PyObject*);
static int init(PyVectorObject*, PyObject*, PyObject*);
static PyObject* pynew(PyTypeObject* type, PyObject* args=NULL, PyObject* kwds=NULL);
static PyObject* get_member(PyObject*, void*);
static int set_member(PyObject*, PyObject*, void*);
static PyGetSetDef getsetters[];
};
namespace mcrfpydef {
static PyTypeObject PyVectorType = {
.tp_name = "mcrfpy.Vector",
.tp_basicsize = sizeof(PyVectorObject),
.tp_itemsize = 0,
.tp_repr = PyVector::repr,
.tp_hash = PyVector::hash,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = PyDoc_STR("SFML Vector Object"),
.tp_getset = PyVector::getsetters,
.tp_init = (initproc)PyVector::init,
.tp_new = PyVector::pynew,
};
}

View File

@ -12,6 +12,7 @@
#include "PyTexture.h"
#include "PyColor.h"
//#include "PyLinkedColor.h"
#include "PyVector.h"
enum PyObjectsEnum : int
{
@ -587,6 +588,17 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c
return 0;
}
static PyObject* PyUICaption_get_vec_member(PyUICaptionObject* self, void* closure)
{
return PyVector(self->data->text.getPosition()).pyObject();
}
static int PyUICaption_set_vec_member(PyUICaptionObject* self, PyObject* value, void* closure)
{
self->data->text.setPosition(PyVector::fromPy(value));
return 0;
}
static PyObject* PyUICaption_get_color_member(PyUICaptionObject* self, void* closure)
{
// validate closure (should be impossible to be wrong, but it's thorough)
@ -730,6 +742,7 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c
static PyGetSetDef PyUICaption_getsetters[] = {
{"x", (getter)PyUICaption_get_float_member, (setter)PyUICaption_set_float_member, "X coordinate of top-left corner", (void*)0},
{"y", (getter)PyUICaption_get_float_member, (setter)PyUICaption_set_float_member, "Y coordinate of top-left corner", (void*)1},
{"pos", (getter)PyUICaption_get_vec_member, (setter)PyUICaption_set_vec_member, "(x, y) vector", (void*)0},
//{"w", (getter)PyUIFrame_get_float_member, (setter)PyUIFrame_set_float_member, "width of the rectangle", (void*)2},
//{"h", (getter)PyUIFrame_get_float_member, (setter)PyUIFrame_set_float_member, "height of the rectangle", (void*)3},
{"outline", (getter)PyUICaption_get_float_member, (setter)PyUICaption_set_float_member, "Thickness of the border", (void*)4},