diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-04-03 06:16:56 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-04-03 06:16:56 +0400 |
commit | b22705f1694f83756f7ca785b6f20caf353f5998 (patch) | |
tree | d7a8561e3fba5232fbe7347d4e39dc95c9d601b5 /source | |
parent | 2178fcea6e2412db4d919f00b00cd5965bcbe27e (diff) |
BGE Python
- Bugfix for running dir() on all BGE python objects. was not getting the immediate methods and attributes for each class.
- Use attributes for KX_Scene (so they are included with dir())
- Override __dict__ attributes for KX_Scene and KX_GameObject so custom properties are included with a dir()
Diffstat (limited to 'source')
-rw-r--r-- | source/gameengine/Expressions/PyObjectPlus.h | 5 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_GameObject.cpp | 34 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_GameObject.h | 3 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Scene.cpp | 65 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Scene.h | 9 |
5 files changed, 85 insertions, 31 deletions
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 6ba80255aa3..345eb8c9c3f 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -100,9 +100,8 @@ static inline void Py_Fatal(const char *M) { PyErr_Clear(); \ rvalue = Parent::_getattr(attr); \ } \ - if ((rvalue == NULL) && !strcmp(attr, "__dict__")) {\ - PyErr_Clear(); \ - rvalue = _getattr_dict(Parent::_getattr(attr), Methods, Attributes); \ + if (strcmp(attr, "__dict__")==0) {\ + rvalue = _getattr_dict(rvalue, Methods, Attributes); \ } \ return rvalue; \ diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 281de1965d4..5c9615c408b 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -942,14 +942,14 @@ const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const } - +static MT_Point3 dummy_point= MT_Point3(0.0, 0.0, 0.0); const MT_Point3& KX_GameObject::NodeGetWorldPosition() const { // check on valid node in case a python controller holds a reference to a deleted object if (GetSGNode()) return GetSGNode()->GetWorldPosition(); else - return MT_Point3(0.0, 0.0, 0.0); + return dummy_point; } /* Suspend/ resume: for the dynamic behaviour, there is a simple @@ -1043,6 +1043,7 @@ PyAttributeDef KX_GameObject::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("scaling", KX_GameObject, pyattr_get_scaling, pyattr_set_scaling), KX_PYATTRIBUTE_RW_FUNCTION("timeOffset",KX_GameObject, pyattr_get_timeOffset,pyattr_set_timeOffset), KX_PYATTRIBUTE_RW_FUNCTION("state", KX_GameObject, pyattr_get_state, pyattr_set_state), + KX_PYATTRIBUTE_RO_FUNCTION("__dict__", KX_GameObject, pyattr_get_dir_dict), {NULL} //Sentinel }; @@ -1412,16 +1413,37 @@ int KX_GameObject::pyattr_set_state(void *self_v, const KX_PYATTRIBUTE_DEF *attr return 0; } +/* __dict__ only for the purpose of giving useful dir() results */ +PyObject* KX_GameObject::pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self= static_cast<KX_GameObject*>(self_v); + PyObject *dict= _getattr_dict(self->SCA_IObject::_getattr("__dict__"), KX_GameObject::Methods, KX_GameObject::Attributes); + + if(dict==NULL) + return NULL; + + /* Not super fast getting as a list then making into dict keys but its only for dir() */ + PyObject *list= self->ConvertKeysToPython(); + if(list) + { + int i; + for(i=0; i<PyList_Size(list); i++) + PyDict_SetItem(dict, PyList_GET_ITEM(list, i), Py_None); + } + else + PyErr_Clear(); + + Py_DECREF(list); + + return dict; +} + PyObject* KX_GameObject::_getattr(const char *attr) { PyObject* object = _getattr_self(Attributes, this, attr); if (object != NULL) return object; - if (!strcmp(attr, "__dict__")) { /* python 3.0 uses .__dir__()*/ - return _getattr_dict(SCA_IObject::_getattr(attr), Methods, Attributes); - } - _getattr_up(SCA_IObject); } diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 774977f2ecf..bada19c4895 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -822,6 +822,9 @@ public: static PyObject* pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + /* for dir(), python3 uses __dir__() */ + static PyObject* pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + /* getitem/setitem */ static int Map_Len(PyObject* self); static PyMappingMethods Mapping; diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 0fded15f1a1..b24b5cd9693 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -32,7 +32,6 @@ #pragma warning (disable : 4786) #endif //WIN32 - #include "KX_Scene.h" #include "MT_assert.h" @@ -1551,35 +1550,57 @@ PyMethodDef KX_Scene::Methods[] = { {NULL,NULL} //Sentinel }; +PyObject* KX_Scene::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_Scene* self= static_cast<KX_Scene*>(self_v); + return PyString_FromString(self->GetName().ReadPtr()); +} + +PyObject* KX_Scene::pyattr_get_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_Scene* self= static_cast<KX_Scene*>(self_v); + return self->GetObjectList()->AddRef(); +} + +PyObject* KX_Scene::pyattr_get_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_Scene* self= static_cast<KX_Scene*>(self_v); + return self->GetActiveCamera()->AddRef(); +} + +/* __dict__ only for the purpose of giving useful dir() results */ +PyObject* KX_Scene::pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_Scene* self= static_cast<KX_Scene*>(self_v); + /* Useually done by _getattr_up but in this case we want to include m_attrlist dict */ + PyObject *dict= _getattr_dict(self->PyObjectPlus::_getattr("__dict__"), KX_Scene::Methods, KX_Scene::Attributes); + + PyDict_Update(dict, self->m_attrlist); + return dict; +} + PyAttributeDef KX_Scene::Attributes[] = { + KX_PYATTRIBUTE_RO_FUNCTION("name", KX_Scene, pyattr_get_name), + KX_PYATTRIBUTE_RO_FUNCTION("objects", KX_Scene, pyattr_get_objects), + KX_PYATTRIBUTE_RO_FUNCTION("active_camera", KX_Scene, pyattr_get_active_camera), + KX_PYATTRIBUTE_BOOL_RO("suspended", KX_Scene, m_suspend), + KX_PYATTRIBUTE_BOOL_RO("activity_culling", KX_Scene, m_activity_culling), + KX_PYATTRIBUTE_FLOAT_RW("activity_culling_radius", 0.5f, FLT_MAX, KX_Scene, m_activity_box_radius), + KX_PYATTRIBUTE_RO_FUNCTION("__dict__", KX_Scene, pyattr_get_dir_dict), { NULL } //Sentinel }; PyObject* KX_Scene::_getattr(const char *attr) { - if (!strcmp(attr, "name")) - return PyString_FromString(GetName()); - - if (!strcmp(attr, "objects")) - return (PyObject*) m_objectlist->AddRef(); - - if (!strcmp(attr, "active_camera")) - return (PyObject*) GetActiveCamera()->AddRef(); - - if (!strcmp(attr, "suspended")) - return PyInt_FromLong(m_suspend); - - if (!strcmp(attr, "activity_culling")) - return PyInt_FromLong(m_activity_culling); - - if (!strcmp(attr, "activity_culling_radius")) - return PyFloat_FromDouble(m_activity_box_radius); + PyObject* object = _getattr_self(Attributes, this, attr); + if (object != NULL) + return object; - PyObject* value = PyDict_GetItemString(m_attrlist, attr); - if (value) + object = PyDict_GetItemString(m_attrlist, attr); + if (object) { - Py_INCREF(value); - return value; + Py_INCREF(object); + return object; } _getattr_up(PyObjectPlus); diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 962db1a9b96..d1da44c600e 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -565,6 +565,15 @@ public: KX_PYMETHOD_DOC(KX_Scene, setSceneViewport); */ + /* attributes */ + static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_objects(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_active_camera(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + + /* for dir(), python3 uses __dir__() */ + static PyObject* pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + + virtual PyObject* _getattr(const char *attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */ virtual int _setattr(const char *attr, PyObject *pyvalue); virtual int _delattr(const char *attr); |