cyphesis/rulesets/Py_Thing.cpp
Al Riddoch 1826587f9d * Fixes to worlds object list so it now contains world.
* 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
2000-12-06 18:21:35 +00:00

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