Fix Entity property setters and PyVector implementation
Fixed the 'new style getargs format' error in Entity property setters by: - Implementing PyObject_to_sfVector2f/2i using PyVector::from_arg - Adding proper error checking in Entity::set_position - Implementing PyVector get_member/set_member for x/y properties - Fixing PyVector::from_arg to handle non-tuple arguments correctly Now Entity.pos and Entity.sprite_number setters work correctly with proper type validation.
This commit is contained in:
parent
f82b861bcd
commit
6dd1cec600
5 changed files with 247 additions and 21 deletions
|
|
@ -106,13 +106,37 @@ PyObject* PyVector::pynew(PyTypeObject* type, PyObject* args, PyObject* kwds)
|
|||
|
||||
PyObject* PyVector::get_member(PyObject* obj, void* closure)
|
||||
{
|
||||
// TODO
|
||||
return Py_None;
|
||||
PyVectorObject* self = (PyVectorObject*)obj;
|
||||
if (reinterpret_cast<long>(closure) == 0) {
|
||||
// x
|
||||
return PyFloat_FromDouble(self->data.x);
|
||||
} else {
|
||||
// y
|
||||
return PyFloat_FromDouble(self->data.y);
|
||||
}
|
||||
}
|
||||
|
||||
int PyVector::set_member(PyObject* obj, PyObject* value, void* closure)
|
||||
{
|
||||
// TODO
|
||||
PyVectorObject* self = (PyVectorObject*)obj;
|
||||
float val;
|
||||
|
||||
if (PyFloat_Check(value)) {
|
||||
val = PyFloat_AsDouble(value);
|
||||
} else if (PyLong_Check(value)) {
|
||||
val = PyLong_AsDouble(value);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "Vector members must be numeric");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (reinterpret_cast<long>(closure) == 0) {
|
||||
// x
|
||||
self->data.x = val;
|
||||
} else {
|
||||
// y
|
||||
self->data.y = val;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -120,11 +144,31 @@ PyVectorObject* PyVector::from_arg(PyObject* args)
|
|||
{
|
||||
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Vector");
|
||||
if (PyObject_IsInstance(args, (PyObject*)type)) return (PyVectorObject*)args;
|
||||
|
||||
auto obj = (PyVectorObject*)type->tp_alloc(type, 0);
|
||||
int err = init(obj, args, NULL);
|
||||
if (err) {
|
||||
Py_DECREF(obj);
|
||||
return NULL;
|
||||
|
||||
// Handle different input types
|
||||
if (PyTuple_Check(args)) {
|
||||
// It's already a tuple, pass it directly to init
|
||||
int err = init(obj, args, NULL);
|
||||
if (err) {
|
||||
Py_DECREF(obj);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
// Wrap single argument in a tuple for init
|
||||
PyObject* tuple = PyTuple_Pack(1, args);
|
||||
if (!tuple) {
|
||||
Py_DECREF(obj);
|
||||
return NULL;
|
||||
}
|
||||
int err = init(obj, tuple, NULL);
|
||||
Py_DECREF(tuple);
|
||||
if (err) {
|
||||
Py_DECREF(obj);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
#include "UIGrid.h"
|
||||
#include "McRFPy_API.h"
|
||||
#include "PyObjectUtils.h"
|
||||
#include "PyVector.h"
|
||||
|
||||
|
||||
UIEntity::UIEntity() {} // this will not work lol. TODO remove default constructor by finding the shared pointer inits that use it
|
||||
|
||||
|
|
@ -104,28 +106,40 @@ PyObject* UIEntity::get_spritenumber(PyUIEntityObject* self, void* closure) {
|
|||
return PyLong_FromDouble(self->data->sprite.getSpriteIndex());
|
||||
}
|
||||
|
||||
PyObject* sfVector2f_to_PyObject(sf::Vector2f vector) {
|
||||
return Py_BuildValue("(ff)", vector.x, vector.y);
|
||||
PyObject* sfVector2f_to_PyObject(sf::Vector2f vec) {
|
||||
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Vector");
|
||||
auto obj = (PyVectorObject*)type->tp_alloc(type, 0);
|
||||
if (obj) {
|
||||
obj->data = vec;
|
||||
}
|
||||
return (PyObject*)obj;
|
||||
}
|
||||
|
||||
PyObject* sfVector2i_to_PyObject(sf::Vector2i vector) {
|
||||
return Py_BuildValue("(ii)", vector.x, vector.y);
|
||||
PyObject* sfVector2i_to_PyObject(sf::Vector2i vec) {
|
||||
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Vector");
|
||||
auto obj = (PyVectorObject*)type->tp_alloc(type, 0);
|
||||
if (obj) {
|
||||
obj->data = sf::Vector2f(static_cast<float>(vec.x), static_cast<float>(vec.y));
|
||||
}
|
||||
return (PyObject*)obj;
|
||||
}
|
||||
|
||||
sf::Vector2f PyObject_to_sfVector2f(PyObject* obj) {
|
||||
float x, y;
|
||||
if (!PyArg_ParseTuple(obj, "ff", &x, &y)) {
|
||||
return sf::Vector2f(); // TODO / reconsider this default: Return default vector on parse error
|
||||
PyVectorObject* vec = PyVector::from_arg(obj);
|
||||
if (!vec) {
|
||||
// PyVector::from_arg already set the error
|
||||
return sf::Vector2f(0, 0);
|
||||
}
|
||||
return sf::Vector2f(x, y);
|
||||
return vec->data;
|
||||
}
|
||||
|
||||
sf::Vector2i PyObject_to_sfVector2i(PyObject* obj) {
|
||||
int x, y;
|
||||
if (!PyArg_ParseTuple(obj, "ii", &x, &y)) {
|
||||
return sf::Vector2i(); // TODO / reconsider this default: Return default vector on parse error
|
||||
PyVectorObject* vec = PyVector::from_arg(obj);
|
||||
if (!vec) {
|
||||
// PyVector::from_arg already set the error
|
||||
return sf::Vector2i(0, 0);
|
||||
}
|
||||
return sf::Vector2i(x, y);
|
||||
return sf::Vector2i(static_cast<int>(vec->data.x), static_cast<int>(vec->data.y));
|
||||
}
|
||||
|
||||
// TODO - deprecate / remove this helper
|
||||
|
|
@ -161,9 +175,17 @@ PyObject* UIEntity::get_position(PyUIEntityObject* self, void* closure) {
|
|||
|
||||
int UIEntity::set_position(PyUIEntityObject* self, PyObject* value, void* closure) {
|
||||
if (reinterpret_cast<long>(closure) == 0) {
|
||||
self->data->position = PyObject_to_sfVector2f(value);
|
||||
sf::Vector2f vec = PyObject_to_sfVector2f(value);
|
||||
if (PyErr_Occurred()) {
|
||||
return -1; // Error already set by PyObject_to_sfVector2f
|
||||
}
|
||||
self->data->position = vec;
|
||||
} else {
|
||||
self->data->collision_pos = PyObject_to_sfVector2i(value);
|
||||
sf::Vector2i vec = PyObject_to_sfVector2i(value);
|
||||
if (PyErr_Occurred()) {
|
||||
return -1; // Error already set by PyObject_to_sfVector2i
|
||||
}
|
||||
self->data->collision_pos = vec;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue