mirror of
https://github.com/worldforge/cyphesis
synced 2026-08-13 12:26:04 -04:00
* More python code tweaks to work with modifications to interface. * Modified code which gets Thing attributes from Message::Object so it can use any object dictionary to look up parent object. * Fixed handling of Thing's static type attribute. * Modified creation of operations from python to eliminate some strange segfaults. * Re-wrote and fixed Entity creation from python. * Implemented dictlist.remove_value for removing things from inventory. * Implemented Vector3D arithmetic and methods from python. * Implemented as_entity() and get_xyz() methods for Thing from python. * Commented out deletion of operations from python OperationObject dealloc() function as it was causing segfaults. There is a problem somewhere with ownership not being cleared, but I can't find it. * Implemented conversion of Python Operation and Oplist objects to Message::Object. * Fixed MemMap so that attributes of Things are accuratly updated. * Fixed it so that look ops from mind are broadcast rather than sent to world. This may have to be reverted. * Tweaked autoconf to make it cleaner and work better. Still needs alot of work. A simple test of some goals now works! The lych goals worked to some extent and no-longer gives python errors. Only a few more things are required before Acorn can run, at which point I will release 0.1 for testing. Al
183 lines
5.2 KiB
C++
183 lines
5.2 KiB
C++
#include <stdio.h>
|
|
#include <unistd.h>
|
|
|
|
#include <Python.h>
|
|
|
|
#include "Python_API.h"
|
|
#include "Thing.h"
|
|
|
|
static PyObject * Thing_as_entity(ThingObject * self, PyObject * args)
|
|
{
|
|
printf("Thing_as_entity\n");
|
|
if (self->m_thing == NULL) {
|
|
PyErr_SetString(PyExc_TypeError, "invalid thing");
|
|
return NULL;
|
|
}
|
|
if (!PyArg_ParseTuple(args, "")) {
|
|
return NULL;
|
|
}
|
|
AtlasObject * ret = newAtlasObject(NULL);
|
|
if (ret == NULL) {
|
|
return NULL;
|
|
}
|
|
ret->m_obj = new Object(self->m_thing->asObject());
|
|
return (PyObject *)ret;
|
|
}
|
|
|
|
static PyObject * Thing_get_xyz(ThingObject * self, PyObject * args)
|
|
{
|
|
if (self->m_thing == NULL) {
|
|
PyErr_SetString(PyExc_TypeError, "invalid thing");
|
|
return NULL;
|
|
}
|
|
if (!PyArg_ParseTuple(args, "")) {
|
|
return NULL;
|
|
}
|
|
Vector3DObject * ret = newVector3DObject(NULL);
|
|
if (ret == NULL) {
|
|
return NULL;
|
|
}
|
|
ret->coords = self->m_thing->get_xyz();
|
|
return (PyObject *)ret;
|
|
}
|
|
|
|
PyMethodDef Thing_methods[] = {
|
|
{"get_xyz", (PyCFunction)Thing_get_xyz, 1},
|
|
{"as_entity", (PyCFunction)Thing_as_entity, 1},
|
|
{NULL, NULL} /* sentinel */
|
|
};
|
|
|
|
static void Thing_dealloc(ThingObject *self)
|
|
{
|
|
//if (self->m_thing != NULL) {
|
|
//delete self->m_thing;
|
|
//}
|
|
Py_XDECREF(self->Thing_attr);
|
|
PyMem_DEL(self);
|
|
}
|
|
|
|
PyObject * Thing_getattr(ThingObject *self, char *name)
|
|
{
|
|
cout << "Thing_getattr" << endl << flush;
|
|
if (self->m_thing == NULL) {
|
|
PyErr_SetString(PyExc_TypeError, "invalid thing");
|
|
return NULL;
|
|
}
|
|
if (strcmp(name, "id") == 0) {
|
|
cout << "Thing_getattr(id)" << endl << flush;
|
|
return PyString_FromString(self->m_thing->fullid.c_str());
|
|
}
|
|
if (strcmp(name, "name") == 0) {
|
|
cout << "Thing_getattr(name)" << endl << flush;
|
|
return PyString_FromString(self->m_thing->name.c_str());
|
|
}
|
|
if (strcmp(name, "status") == 0) {
|
|
cout << "Thing_getattr(status)" << endl << flush;
|
|
return PyFloat_FromDouble(self->m_thing->status);
|
|
}
|
|
if (strcmp(name, "map") == 0) {
|
|
cout << "Thing_getattr(map)" << endl << flush;
|
|
MapObject * map = newMapObject(NULL);
|
|
map->m_map = &self->m_thing->map;
|
|
return (PyObject *)map;
|
|
}
|
|
if (strcmp(name, "location") == 0) {
|
|
cout << "Thing_getattr(location)" << endl << flush;
|
|
LocationObject * loc = newLocationObject(NULL);
|
|
loc->location = &self->m_thing->location;
|
|
return (PyObject *)loc;
|
|
}
|
|
if (strcmp(name, "world") == 0) {
|
|
cout << "Thing_getattr(world)" << endl << flush;
|
|
WorldObject * world = newWorldObject(NULL);
|
|
world->world = self->m_thing->world;
|
|
return (PyObject *)world;
|
|
}
|
|
if (self->Thing_attr != NULL) {
|
|
PyObject *v = PyDict_GetItemString(self->Thing_attr, name);
|
|
if (v != NULL) {
|
|
Py_INCREF(v);
|
|
return v;
|
|
}
|
|
}
|
|
Thing * thing = self->m_thing;
|
|
string attr(name);
|
|
if (thing->attributes.find(attr) != thing->attributes.end()) {
|
|
cout << name << " is in the attributes list" << endl << flush;
|
|
return Object_asPyObject(thing->attributes[attr]);
|
|
}
|
|
cout << "Just doing the method lookup" << endl << flush;
|
|
return Py_FindMethod(Thing_methods, (PyObject *)self, name);
|
|
}
|
|
|
|
int Thing_setattr(ThingObject *self, char *name, PyObject *v)
|
|
{
|
|
cout << "Thing_setattr" << endl << flush;
|
|
if (self->m_thing == NULL) {
|
|
return -1;
|
|
}
|
|
if (self->Thing_attr == NULL) {
|
|
self->Thing_attr = PyDict_New();
|
|
if (self->Thing_attr == NULL) {
|
|
return -1;
|
|
}
|
|
}
|
|
if (strcmp(name, "status") == 0) {
|
|
if (PyInt_Check(v)) {
|
|
self->m_thing->status = (double)PyInt_AsLong(v);
|
|
} else if (PyFloat_Check(v)) {
|
|
self->m_thing->status = PyFloat_AsDouble(v);
|
|
} else {
|
|
PyErr_SetString(PyExc_TypeError, "status must be numeric type");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
if (strcmp(name, "map") == 0) {
|
|
return -1;
|
|
}
|
|
Thing * thing = self->m_thing;
|
|
string attr(name);
|
|
if (v == NULL) {
|
|
thing->attributes.erase(attr);
|
|
return(0);
|
|
}
|
|
Object obj = PyObject_asObject(v);
|
|
if (!obj.IsNone() && !obj.IsMap() && !obj.IsList()) {
|
|
thing->attributes[name] = obj;
|
|
return(0);
|
|
}
|
|
// If we get here, then the attribute is not Atlas compatable, so we
|
|
// need to store it in a python dictionary
|
|
return PyDict_SetItemString(self->Thing_attr, name, v);
|
|
}
|
|
|
|
PyTypeObject Thing_Type = {
|
|
PyObject_HEAD_INIT(&PyType_Type)
|
|
0, /*ob_size*/
|
|
"cppThing", /*tp_name*/
|
|
sizeof(ThingObject), /*tp_basicsize*/
|
|
0, /*tp_itemsize*/
|
|
/* methods */
|
|
(destructor)Thing_dealloc, /*tp_dealloc*/
|
|
0, /*tp_print*/
|
|
(getattrfunc)Thing_getattr, /*tp_getattr*/
|
|
(setattrfunc)Thing_setattr, /*tp_setattr*/
|
|
0, /*tp_compare*/
|
|
0, /*tp_repr*/
|
|
0, /*tp_as_number*/
|
|
0, /*tp_as_sequence*/
|
|
0, /*tp_as_mapping*/
|
|
0, /*tp_hash*/
|
|
};
|
|
|
|
ThingObject * newThingObject(PyObject *arg)
|
|
{
|
|
ThingObject * self;
|
|
self = PyObject_NEW(ThingObject, &Thing_Type);
|
|
if (self == NULL) {
|
|
return NULL;
|
|
}
|
|
self->Thing_attr = NULL;
|
|
return self;
|
|
}
|