diff --git a/source/gameengine/Expressions/CMakeLists.txt b/source/gameengine/Expressions/CMakeLists.txt index e41fa0c93d06..6a6ad684810c 100644 --- a/source/gameengine/Expressions/CMakeLists.txt +++ b/source/gameengine/Expressions/CMakeLists.txt @@ -39,6 +39,7 @@ set(INC_SYS set(SRC intern/BaseListValue.cpp + intern/BaseListWrapper.cpp intern/BoolValue.cpp intern/ConstExpr.cpp intern/EmptyValue.cpp @@ -54,9 +55,9 @@ set(SRC intern/PyObjectPlus.cpp intern/StringValue.cpp intern/Value.cpp - intern/ListWrapper.cpp EXP_BaseListValue.h + EXP_BaseListWrapper.h EXP_BoolValue.h EXP_ConstExpr.h EXP_EmptyValue.h diff --git a/source/gameengine/Expressions/EXP_BaseListWrapper.h b/source/gameengine/Expressions/EXP_BaseListWrapper.h new file mode 100644 index 000000000000..a65673ed7f3a --- /dev/null +++ b/source/gameengine/Expressions/EXP_BaseListWrapper.h @@ -0,0 +1,106 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Porteries Tristan. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file EXP_BaseListWrapper.h + * \ingroup expressions + */ + +#ifdef WITH_PYTHON + +#ifndef __EXP_BASELISTWRAPPER_H__ +#define __EXP_BASELISTWRAPPER_H__ + +#include "EXP_Value.h" + +class EXP_BaseListWrapper : public EXP_Value +{ + Py_Header +public: + + using GetItemFunction = PyObject *(*)(EXP_PyObjectPlus *, unsigned int); + using GetItemNameFunction = std::string (*)(EXP_PyObjectPlus *, unsigned int); + using GetSizeFunction = unsigned int (*)(EXP_PyObjectPlus *); + using SetItemFunction = bool (*)(EXP_PyObjectPlus *, unsigned int, PyObject *); +private: + /// The client instance passed as first argument of each callback. + EXP_PyObjectPlus *m_client; + /// Weak reference to the client proxy. + PyObject *m_weakRef; + /// Returns the list size. + GetSizeFunction m_getSize; + /// Returns the list item for the giving index. + GetItemFunction m_getItem; + /// Returns name item for the giving index, used for python operator list["name"]. + GetItemNameFunction m_getItemName; + /// Sets the new item to the index place, return false when failed item conversion. + SetItemFunction m_setItem; + + /// Flags used to define special behaviours of the list. + int m_flag; + +public: + enum Flag { + FLAG_NONE = 0, + /// Allow iterating on all items and compare the value of it with a research key. + FLAG_FIND_VALUE = (1 << 0), + /// Allow no validation using weak ref. + FLAG_NO_WEAK_REF = (1 << 1) + }; + + EXP_BaseListWrapper(EXP_PyObjectPlus *client, + GetSizeFunction getSize, GetItemFunction getItem, + GetItemNameFunction getItemName, SetItemFunction setItem, Flag flag = FLAG_NONE); + virtual ~EXP_BaseListWrapper(); + + /// \section Python Interface + static bool CheckValid(EXP_BaseListWrapper *list); + unsigned int GetSize() const; + PyObject *GetItem(int index) const; + std::string GetItemName(int index) const; + bool SetItem(int index, PyObject *item); + bool AllowSetItem() const; + bool AllowGetItemByName() const; + bool AllowFindValue() const; + + /// \section EXP_Value Inherited Functions. + virtual std::string GetName(); + virtual std::string GetText(); + virtual int GetValueType(); + + // Python list operators. + static PySequenceMethods py_as_sequence; + // Python dictionnary operators. + static PyMappingMethods py_as_mapping; + + static Py_ssize_t py_len(PyObject *self); + static PyObject *py_get_item(PyObject *self, Py_ssize_t index); + static int py_set_item(PyObject *self, Py_ssize_t index, PyObject *value); + static PyObject *py_mapping_subscript(PyObject *self, PyObject *key); + static int py_mapping_ass_subscript(PyObject *self, PyObject *key, PyObject *value); + static int py_contains(PyObject *self, PyObject *key); + + EXP_PYMETHOD_VARARGS(EXP_BaseListWrapper, Get); +}; + +#endif // __EXP_BASELISTWRAPPER_H__ + +#endif // WITH_PYTHON diff --git a/source/gameengine/Expressions/EXP_ListWrapper.h b/source/gameengine/Expressions/EXP_ListWrapper.h index dd592526949f..2f5ea34132dd 100644 --- a/source/gameengine/Expressions/EXP_ListWrapper.h +++ b/source/gameengine/Expressions/EXP_ListWrapper.h @@ -29,84 +29,46 @@ #ifndef __EXP_LISTWRAPPER_H__ #define __EXP_LISTWRAPPER_H__ -#include "EXP_Value.h" - -class EXP_ListWrapper : public EXP_Value +#include "EXP_BaseListWrapper.h" + +template +class EXP_ListWrapper : public EXP_BaseListWrapper { - Py_Header private: - /** The client instance passed as first argument of each callback. - * We use a void * instead of a template to avoid to declare this class - * for each use in KX_PythonInitTypes. - */ - void *m_client; - - // The python object which owned this list. - PyObject *m_base; - - /// Returns true if the list is still valid, else each call will raise an error. - bool (*m_checkValid)(void *); - - /// Returns the list size. - int (*m_getSize)(void *); - - /// Returns the list item for the giving index. - PyObject *(*m_getItem)(void *, int); - - /// Returns name item for the giving index, used for python operator list["name"]. - const std::string (*m_getItemName)(void *, int); - - /// Sets the nex item to the index place, return false when failed item conversion. - bool (*m_setItem)(void *, int, PyObject *); - - /// Flags used to define special behaviours of the list. - int m_flag; + static PyObject *GetItem(EXP_PyObjectPlus *self, unsigned int index) + { + return (static_cast(self)->*GetItemFunc)(index); + } + + static std::string GetItemName(EXP_PyObjectPlus *self, unsigned int index) + { + return (static_cast(self)->*GetItemNameFunc)(index); + } + + static unsigned int GetSize(EXP_PyObjectPlus *self) + { + return (static_cast(self)->*GetSizeFunc)(); + } + + static bool SetItem(EXP_PyObjectPlus *self, unsigned int index, PyObject *item) + { + return (static_cast(self)->*SetItemFunc)(index, item); + } public: - enum { - FLAG_NONE = 0, - /// Allow iterating on all items and compare the value of it with a research key. - FLAG_FIND_VALUE = (1 << 0) - }; - - EXP_ListWrapper(void *client, - PyObject *base, - bool(*checkValid)(void *), - int(*getSize)(void *), - PyObject *(*getItem)(void *, int), - const std::string(*getItemName)(void *, int), - bool(*setItem)(void *, int, PyObject *), - int flag = FLAG_NONE); - ~EXP_ListWrapper(); - - /// \section Python Interface - bool CheckValid(); - int GetSize(); - PyObject *GetItem(int index); - const std::string GetItemName(int index); - bool SetItem(int index, PyObject *item); - bool AllowSetItem(); - bool AllowGetItemByName(); - bool AllowFindValue(); - - /// \section EXP_Value Inherited Functions. - virtual std::string GetName(); - virtual std::string GetText(); - virtual int GetValueType(); - - // Python list operators. - static PySequenceMethods py_as_sequence; - // Python dictionnary operators. - static PyMappingMethods py_as_mapping; - - static Py_ssize_t py_len(PyObject *self); - static PyObject *py_get_item(PyObject *self, Py_ssize_t index); - static int py_set_item(PyObject *self, Py_ssize_t index, PyObject *value); - static PyObject *py_mapping_subscript(PyObject *self, PyObject *key); - static int py_mapping_ass_subscript(PyObject *self, PyObject *key, PyObject *value); - static int py_contains(PyObject *self, PyObject *key); - - EXP_PYMETHOD_VARARGS(EXP_ListWrapper, Get); + EXP_ListWrapper(EXP_PyObjectPlus *client, Flag flag = FLAG_NONE) + :EXP_BaseListWrapper(client, GetSize, GetItem, + GetItemNameFunc ? GetItemName : nullptr, + SetItemFunc ? SetItem : nullptr, flag) + { + } + virtual ~EXP_ListWrapper() + { + } }; #endif // __EXP_LISTWRAPPER_H__ diff --git a/source/gameengine/Expressions/intern/ListWrapper.cpp b/source/gameengine/Expressions/intern/BaseListWrapper.cpp similarity index 55% rename from source/gameengine/Expressions/intern/ListWrapper.cpp rename to source/gameengine/Expressions/intern/BaseListWrapper.cpp index 6630a2bc650e..c50464223d4f 100644 --- a/source/gameengine/Expressions/intern/ListWrapper.cpp +++ b/source/gameengine/Expressions/intern/BaseListWrapper.cpp @@ -26,93 +26,95 @@ #ifdef WITH_PYTHON -#include "EXP_ListWrapper.h" - -EXP_ListWrapper::EXP_ListWrapper(void *client, - PyObject *base, - bool (*checkValid)(void *), - int (*getSize)(void *), - PyObject *(*getItem)(void *, int), - const std::string (*getItemName)(void *, int), - bool (*setItem)(void *, int, PyObject *), - int flag) +#include "EXP_BaseListWrapper.h" + +EXP_BaseListWrapper::EXP_BaseListWrapper(EXP_PyObjectPlus *client, + GetSizeFunction getSize, GetItemFunction getItem, + GetItemNameFunction getItemName, SetItemFunction setItem, Flag flag) :m_client(client), - m_base(base), - m_checkValid(checkValid), + m_weakRef(nullptr), m_getSize(getSize), m_getItem(getItem), m_getItemName(getItemName), m_setItem(setItem), m_flag(flag) { - /* Incref to always have a existing pointer. - * If there's no base python proxy it mean that we must manage the - * invalidation of this list manualy when the instance which create - * it is freed. - */ - if (m_base) { - Py_INCREF(m_base); + if (m_flag & FLAG_NO_WEAK_REF) { + m_weakRef = PyWeakref_NewRef(client->GetProxy(), nullptr); } } -EXP_ListWrapper::~EXP_ListWrapper() +EXP_BaseListWrapper::~EXP_BaseListWrapper() { - if (m_base) { - Py_DECREF(m_base); - } + Py_XDECREF(m_weakRef); } -bool EXP_ListWrapper::CheckValid() +bool EXP_BaseListWrapper::CheckValid(EXP_BaseListWrapper *list) { - if (m_base && !EXP_PROXY_REF(m_base)) { + if (!list) { + return false; + } + + if (list->m_flag & FLAG_NO_WEAK_REF) { + return true; + } + + PyObject *proxy = PyWeakref_GET_OBJECT(list->m_weakRef); + if (proxy == Py_None) { return false; } - return m_checkValid ? (*m_checkValid)(m_client) : true; + + EXP_PyObjectPlus *ref = EXP_PROXY_REF(proxy); + if (!ref) { + return false; + } + + BLI_assert(ref == list->m_client); + + return true; } -int EXP_ListWrapper::GetSize() +unsigned int EXP_BaseListWrapper::GetSize() const { return (*m_getSize)(m_client); } -PyObject *EXP_ListWrapper::GetItem(int index) +PyObject *EXP_BaseListWrapper::GetItem(int index) const { return (*m_getItem)(m_client, index); } -const std::string EXP_ListWrapper::GetItemName(int index) +std::string EXP_BaseListWrapper::GetItemName(int index) const { return (*m_getItemName)(m_client, index); } -bool EXP_ListWrapper::SetItem(int index, PyObject *item) +bool EXP_BaseListWrapper::SetItem(int index, PyObject *item) { return (*m_setItem)(m_client, index, item); } -bool EXP_ListWrapper::AllowSetItem() +bool EXP_BaseListWrapper::AllowSetItem() const { return m_setItem != nullptr; } -bool EXP_ListWrapper::AllowGetItemByName() +bool EXP_BaseListWrapper::AllowGetItemByName() const { return m_getItemName != nullptr; } -bool EXP_ListWrapper::AllowFindValue() +bool EXP_BaseListWrapper::AllowFindValue() const { return (m_flag & FLAG_FIND_VALUE); } -// ================================================================ - -std::string EXP_ListWrapper::GetName() +std::string EXP_BaseListWrapper::GetName() { return "ListWrapper"; } -std::string EXP_ListWrapper::GetText() +std::string EXP_BaseListWrapper::GetText() { std::string strListRep = "["; std::string commastr = ""; @@ -127,29 +129,29 @@ std::string EXP_ListWrapper::GetText() return strListRep; } -int EXP_ListWrapper::GetValueType() +int EXP_BaseListWrapper::GetValueType() { return -1; } -Py_ssize_t EXP_ListWrapper::py_len(PyObject *self) +Py_ssize_t EXP_BaseListWrapper::py_len(PyObject *self) { - EXP_ListWrapper *list = (EXP_ListWrapper *)EXP_PROXY_REF(self); + EXP_BaseListWrapper *list = (EXP_BaseListWrapper *)EXP_PROXY_REF(self); // Invalid list. - if (!list->CheckValid()) { - PyErr_SetString(PyExc_SystemError, "len(EXP_ListWrapper), " EXP_PROXY_ERROR_MSG); + if (!CheckValid(list)) { + PyErr_SetString(PyExc_SystemError, "len(EXP_BaseListWrapper), " EXP_PROXY_ERROR_MSG); return 0; } return (Py_ssize_t)list->GetSize(); } -PyObject *EXP_ListWrapper::py_get_item(PyObject *self, Py_ssize_t index) +PyObject *EXP_BaseListWrapper::py_get_item(PyObject *self, Py_ssize_t index) { - EXP_ListWrapper *list = (EXP_ListWrapper *)EXP_PROXY_REF(self); + EXP_BaseListWrapper *list = (EXP_BaseListWrapper *)EXP_PROXY_REF(self); // Invalid list. - if (!list->CheckValid()) { - PyErr_SetString(PyExc_SystemError, "val = EXP_ListWrapper[i], " EXP_PROXY_ERROR_MSG); + if (!CheckValid(list)) { + PyErr_SetString(PyExc_SystemError, "val = EXP_BaseListWrapper[i], " EXP_PROXY_ERROR_MSG); return nullptr; } @@ -159,7 +161,7 @@ PyObject *EXP_ListWrapper::py_get_item(PyObject *self, Py_ssize_t index) index = size + index; } if (index < 0 || index >= size) { - PyErr_SetString(PyExc_IndexError, "EXP_ListWrapper[i]: List index out of range in EXP_ListWrapper"); + PyErr_SetString(PyExc_IndexError, "EXP_BaseListWrapper[i]: List index out of range in EXP_BaseListWrapper"); return nullptr; } @@ -168,22 +170,22 @@ PyObject *EXP_ListWrapper::py_get_item(PyObject *self, Py_ssize_t index) return pyobj; } -int EXP_ListWrapper::py_set_item(PyObject *self, Py_ssize_t index, PyObject *value) +int EXP_BaseListWrapper::py_set_item(PyObject *self, Py_ssize_t index, PyObject *value) { - EXP_ListWrapper *list = (EXP_ListWrapper *)EXP_PROXY_REF(self); + EXP_BaseListWrapper *list = (EXP_BaseListWrapper *)EXP_PROXY_REF(self); // Invalid list. - if (!list->CheckValid()) { - PyErr_SetString(PyExc_SystemError, "EXP_ListWrapper[i] = val, " EXP_PROXY_ERROR_MSG); + if (!CheckValid(list)) { + PyErr_SetString(PyExc_SystemError, "EXP_BaseListWrapper[i] = val, " EXP_PROXY_ERROR_MSG); return -1; } if (!list->AllowSetItem()) { - PyErr_SetString(PyExc_TypeError, "EXP_ListWrapper's item type doesn't support assignment"); + PyErr_SetString(PyExc_TypeError, "EXP_BaseListWrapper's item type doesn't support assignment"); return -1; } if (!value) { - PyErr_SetString(PyExc_TypeError, "EXP_ListWrapper doesn't support item deletion"); + PyErr_SetString(PyExc_TypeError, "EXP_BaseListWrapper doesn't support item deletion"); return -1; } @@ -193,7 +195,7 @@ int EXP_ListWrapper::py_set_item(PyObject *self, Py_ssize_t index, PyObject *val index = size + index; } if (index < 0 || index >= size) { - PyErr_SetString(PyExc_IndexError, "EXP_ListWrapper[i]: List index out of range in EXP_ListWrapper"); + PyErr_SetString(PyExc_IndexError, "EXP_BaseListWrapper[i]: List index out of range in EXP_BaseListWrapper"); return -1; } @@ -203,12 +205,12 @@ int EXP_ListWrapper::py_set_item(PyObject *self, Py_ssize_t index, PyObject *val return 0; } -PyObject *EXP_ListWrapper::py_mapping_subscript(PyObject *self, PyObject *key) +PyObject *EXP_BaseListWrapper::py_mapping_subscript(PyObject *self, PyObject *key) { - EXP_ListWrapper *list = (EXP_ListWrapper *)EXP_PROXY_REF(self); + EXP_BaseListWrapper *list = (EXP_BaseListWrapper *)EXP_PROXY_REF(self); // Invalid list. - if (!list->CheckValid()) { - PyErr_SetString(PyExc_SystemError, "val = EXP_ListWrapper[key], " EXP_PROXY_ERROR_MSG); + if (!CheckValid(list)) { + PyErr_SetString(PyExc_SystemError, "val = EXP_BaseListWrapper[key], " EXP_PROXY_ERROR_MSG); return nullptr; } @@ -218,7 +220,7 @@ PyObject *EXP_ListWrapper::py_mapping_subscript(PyObject *self, PyObject *key) } else if (PyUnicode_Check(key)) { if (!list->AllowGetItemByName()) { - PyErr_SetString(PyExc_SystemError, "EXP_ListWrapper's item type doesn't support access by key"); + PyErr_SetString(PyExc_SystemError, "EXP_BaseListWrapper's item type doesn't support access by key"); return nullptr; } @@ -235,21 +237,21 @@ PyObject *EXP_ListWrapper::py_mapping_subscript(PyObject *self, PyObject *key) return nullptr; } - PyErr_Format(PyExc_KeyError, "EXP_ListWrapper[key]: '%R' key not in list", key); + PyErr_Format(PyExc_KeyError, "EXP_BaseListWrapper[key]: '%R' key not in list", key); return nullptr; } -int EXP_ListWrapper::py_mapping_ass_subscript(PyObject *self, PyObject *key, PyObject *value) +int EXP_BaseListWrapper::py_mapping_ass_subscript(PyObject *self, PyObject *key, PyObject *value) { - EXP_ListWrapper *list = (EXP_ListWrapper *)EXP_PROXY_REF(self); + EXP_BaseListWrapper *list = (EXP_BaseListWrapper *)EXP_PROXY_REF(self); // Invalid list. - if (!list->CheckValid()) { - PyErr_SetString(PyExc_SystemError, "val = EXP_ListWrapper[key], " EXP_PROXY_ERROR_MSG); + if (!CheckValid(list)) { + PyErr_SetString(PyExc_SystemError, "val = EXP_BaseListWrapper[key], " EXP_PROXY_ERROR_MSG); return -1; } if (!list->AllowSetItem()) { - PyErr_SetString(PyExc_TypeError, "EXP_ListWrapper's item type doesn't support assignment"); + PyErr_SetString(PyExc_TypeError, "EXP_BaseListWrapper's item type doesn't support assignment"); return -1; } @@ -259,7 +261,7 @@ int EXP_ListWrapper::py_mapping_ass_subscript(PyObject *self, PyObject *key, PyO } else if (PyUnicode_Check(key)) { if (!list->AllowGetItemByName()) { - PyErr_SetString(PyExc_SystemError, "EXP_ListWrapper's item type doesn't support access by key"); + PyErr_SetString(PyExc_SystemError, "EXP_BaseListWrapper's item type doesn't support access by key"); return -1; } @@ -279,22 +281,22 @@ int EXP_ListWrapper::py_mapping_ass_subscript(PyObject *self, PyObject *key, PyO return -1; } - PyErr_Format(PyExc_KeyError, "EXP_ListWrapper[key]: '%R' key not in list", key); + PyErr_Format(PyExc_KeyError, "EXP_BaseListWrapper[key]: '%R' key not in list", key); return -1; } -int EXP_ListWrapper::py_contains(PyObject *self, PyObject *key) +int EXP_BaseListWrapper::py_contains(PyObject *self, PyObject *key) { - EXP_ListWrapper *list = (EXP_ListWrapper *)EXP_PROXY_REF(self); + EXP_BaseListWrapper *list = (EXP_BaseListWrapper *)EXP_PROXY_REF(self); // Invalid list. - if (!list->CheckValid()) { - PyErr_SetString(PyExc_SystemError, "val = EXP_ListWrapper[i], " EXP_PROXY_ERROR_MSG); + if (!CheckValid(list)) { + PyErr_SetString(PyExc_SystemError, "val = EXP_BaseListWrapper[i], " EXP_PROXY_ERROR_MSG); return -1; } if (PyUnicode_Check(key)) { if (!list->AllowGetItemByName()) { - PyErr_SetString(PyExc_SystemError, "EXP_ListWrapper's item type doesn't support access by key"); + PyErr_SetString(PyExc_SystemError, "EXP_BaseListWrapper's item type doesn't support access by key"); return -1; } @@ -318,7 +320,7 @@ int EXP_ListWrapper::py_contains(PyObject *self, PyObject *key) return 0; } -PySequenceMethods EXP_ListWrapper::py_as_sequence = { +PySequenceMethods EXP_BaseListWrapper::py_as_sequence = { py_len, // sq_length nullptr, // sq_concat nullptr, // sq_repeat @@ -331,13 +333,13 @@ PySequenceMethods EXP_ListWrapper::py_as_sequence = { (ssizeargfunc)nullptr, // sq_inplace_repeat }; -PyMappingMethods EXP_ListWrapper::py_as_mapping = { +PyMappingMethods EXP_BaseListWrapper::py_as_mapping = { py_len, // mp_length py_mapping_subscript, // mp_subscript py_mapping_ass_subscript // mp_ass_subscript }; -PyTypeObject EXP_ListWrapper::Type = { +PyTypeObject EXP_BaseListWrapper::Type = { PyVarObject_HEAD_INIT(nullptr, 0) "EXP_ListWrapper", // tp_name sizeof(EXP_PyObjectPlus_Proxy), // tp_basicsize @@ -367,29 +369,29 @@ PyTypeObject EXP_ListWrapper::Type = { py_base_new }; -PyMethodDef EXP_ListWrapper::Methods[] = { - {"get", (PyCFunction)EXP_ListWrapper::sPyGet, METH_VARARGS}, +PyMethodDef EXP_BaseListWrapper::Methods[] = { + {"get", (PyCFunction)EXP_BaseListWrapper::sPyGet, METH_VARARGS}, {nullptr, nullptr} // Sentinel }; -PyAttributeDef EXP_ListWrapper::Attributes[] = { +PyAttributeDef EXP_BaseListWrapper::Attributes[] = { EXP_PYATTRIBUTE_NULL // Sentinel }; // Matches python dict.get(key, [default]). -PyObject *EXP_ListWrapper::PyGet(PyObject *args) +PyObject *EXP_BaseListWrapper::PyGet(PyObject *args) { char *name; PyObject *def = Py_None; // Invalid list. - if (!CheckValid()) { - PyErr_SetString(PyExc_SystemError, "val = EXP_ListWrapper[i], " EXP_PROXY_ERROR_MSG); + if (!CheckValid(this)) { + PyErr_SetString(PyExc_SystemError, "val = EXP_BaseListWrapper[i], " EXP_PROXY_ERROR_MSG); return nullptr; } if (!AllowGetItemByName()) { - PyErr_SetString(PyExc_SystemError, "EXP_ListWrapper's item type doesn't support access by key"); + PyErr_SetString(PyExc_SystemError, "EXP_BaseListWrapper's item type doesn't support access by key"); return nullptr; } diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp index 8a682df2c008..963834eb3d7f 100644 --- a/source/gameengine/GameLogic/SCA_IController.cpp +++ b/source/gameengine/GameLogic/SCA_IController.cpp @@ -239,55 +239,45 @@ PyObject *SCA_IController::pyattr_get_state(EXP_PyObjectPlus *self_v, const EXP_ return PyLong_FromLong(self->m_statemask); } -static int sca_icontroller_get_sensors_size_cb(void *self_v) +unsigned int SCA_IController::py_get_sensors_size() { - return ((SCA_IController *)self_v)->GetLinkedSensors().size(); + return m_linkedsensors.size(); } -static PyObject *sca_icontroller_get_sensors_item_cb(void *self_v, int index) +PyObject *SCA_IController::py_get_sensors_item(unsigned int index) { - return ((SCA_IController *)self_v)->GetLinkedSensors()[index]->GetProxy(); + return m_linkedsensors[index]->GetProxy(); } -static const std::string sca_icontroller_get_sensors_item_name_cb(void *self_v, int index) +std::string SCA_IController::py_get_sensors_item_name(unsigned int index) { - return ((SCA_IController *)self_v)->GetLinkedSensors()[index]->GetName(); + return m_linkedsensors[index]->GetName(); } PyObject *SCA_IController::pyattr_get_sensors(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((SCA_IController *)self_v)->GetProxy(), - nullptr, - sca_icontroller_get_sensors_size_cb, - sca_icontroller_get_sensors_item_cb, - sca_icontroller_get_sensors_item_name_cb, - nullptr))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } -static int sca_icontroller_get_actuators_size_cb(void *self_v) +unsigned int SCA_IController::py_get_actuators_size() { - return ((SCA_IController *)self_v)->GetLinkedActuators().size(); + return m_linkedactuators.size(); } -static PyObject *sca_icontroller_get_actuators_item_cb(void *self_v, int index) +PyObject *SCA_IController::py_get_actuators_item(unsigned int index) { - return ((SCA_IController *)self_v)->GetLinkedActuators()[index]->GetProxy(); + return m_linkedactuators[index]->GetProxy(); } -static const std::string sca_icontroller_get_actuators_item_name_cb(void *self_v, int index) +std::string SCA_IController::py_get_actuators_item_name(unsigned int index) { - return ((SCA_IController *)self_v)->GetLinkedActuators()[index]->GetName(); + return m_linkedactuators[index]->GetName(); } PyObject *SCA_IController::pyattr_get_actuators(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((SCA_IController *)self_v)->GetProxy(), - nullptr, - sca_icontroller_get_actuators_size_cb, - sca_icontroller_get_actuators_item_cb, - sca_icontroller_get_actuators_item_name_cb, - nullptr))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } #endif // WITH_PYTHON diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h index 6236e1be4274..d9c3f7f0f46a 100644 --- a/source/gameengine/GameLogic/SCA_IController.h +++ b/source/gameengine/GameLogic/SCA_IController.h @@ -76,6 +76,14 @@ class SCA_IController : public SCA_ILogicBrick static PyObject *pyattr_get_state(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); static PyObject *pyattr_get_sensors(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); static PyObject *pyattr_get_actuators(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); + + unsigned int py_get_sensors_size(); + PyObject *py_get_sensors_item(unsigned int index); + std::string py_get_sensors_item_name(unsigned int index); + + unsigned int py_get_actuators_size(); + PyObject *py_get_actuators_item(unsigned int index); + std::string py_get_actuators_item_name(unsigned int index); #endif // WITH_PYTHON }; diff --git a/source/gameengine/GameLogic/SCA_InputEvent.cpp b/source/gameengine/GameLogic/SCA_InputEvent.cpp index 43c38b21fe95..76c53f884f5a 100644 --- a/source/gameengine/GameLogic/SCA_InputEvent.cpp +++ b/source/gameengine/GameLogic/SCA_InputEvent.cpp @@ -129,70 +129,49 @@ PyAttributeDef SCA_InputEvent::Attributes[] = { EXP_PYATTRIBUTE_NULL //Sentinel }; -int SCA_InputEvent::get_status_size_cb(void *self_v) +unsigned int SCA_InputEvent::get_status_size() { - return ((SCA_InputEvent *)self_v)->m_status.size(); + return m_status.size(); } -PyObject *SCA_InputEvent::get_status_item_cb(void *self_v, int index) +PyObject *SCA_InputEvent::get_status_item(unsigned int index) { - return PyLong_FromLong(((SCA_InputEvent *)self_v)->m_status[index]); + return PyLong_FromLong(m_status[index]); } PyObject *SCA_InputEvent::pyattr_get_status(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((SCA_InputEvent *)self_v)->GetProxy(), - nullptr, - SCA_InputEvent::get_status_size_cb, - SCA_InputEvent::get_status_item_cb, - nullptr, - nullptr, - EXP_ListWrapper::FLAG_FIND_VALUE))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } -int SCA_InputEvent::get_queue_size_cb(void *self_v) +unsigned int SCA_InputEvent::get_queue_size() { - return ((SCA_InputEvent *)self_v)->m_queue.size(); + return m_queue.size(); } -PyObject *SCA_InputEvent::get_queue_item_cb(void *self_v, int index) +PyObject *SCA_InputEvent::get_queue_item(unsigned int index) { - return PyLong_FromLong(((SCA_InputEvent *)self_v)->m_queue[index]); + return PyLong_FromLong(m_queue[index]); } PyObject *SCA_InputEvent::pyattr_get_queue(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((SCA_InputEvent *)self_v)->GetProxy(), - nullptr, - SCA_InputEvent::get_queue_size_cb, - SCA_InputEvent::get_queue_item_cb, - nullptr, - nullptr, - EXP_ListWrapper::FLAG_FIND_VALUE))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } -int SCA_InputEvent::get_values_size_cb(void *self_v) +unsigned int SCA_InputEvent::get_values_size() { - return ((SCA_InputEvent *)self_v)->m_values.size(); + return m_values.size(); } -PyObject *SCA_InputEvent::get_values_item_cb(void *self_v, int index) +PyObject *SCA_InputEvent::get_values_item(unsigned int index) { - return PyLong_FromLong(((SCA_InputEvent *)self_v)->m_values[index]); + return PyLong_FromLong(m_values[index]); } PyObject *SCA_InputEvent::pyattr_get_values(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((SCA_InputEvent *)self_v)->GetProxy(), - nullptr, - SCA_InputEvent::get_values_size_cb, - SCA_InputEvent::get_values_item_cb, - nullptr, - nullptr, - EXP_ListWrapper::FLAG_FIND_VALUE))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } PyObject *SCA_InputEvent::pyattr_get_inactive(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/GameLogic/SCA_InputEvent.h b/source/gameengine/GameLogic/SCA_InputEvent.h index c32ef596f6a6..f857215745b7 100644 --- a/source/gameengine/GameLogic/SCA_InputEvent.h +++ b/source/gameengine/GameLogic/SCA_InputEvent.h @@ -68,12 +68,12 @@ Py_Header int m_type; #ifdef WITH_PYTHON - static int get_status_size_cb(void *self_v); - static PyObject *get_status_item_cb(void *self_v, int index); - static int get_queue_size_cb(void *self_v); - static PyObject *get_queue_item_cb(void *self_v, int index); - static int get_values_size_cb(void *self_v); - static PyObject *get_values_item_cb(void *self_v, int index); + unsigned int get_status_size(); + PyObject *get_status_item(unsigned int index); + unsigned int get_queue_size(); + PyObject *get_queue_item(unsigned int index); + unsigned int get_values_size(); + PyObject *get_values_item(unsigned int index); static PyObject *pyattr_get_status(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); static PyObject *pyattr_get_queue(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_2DFilterOffScreen.cpp b/source/gameengine/Ketsji/KX_2DFilterOffScreen.cpp index 318a8c5e92dd..b78e163dba23 100644 --- a/source/gameengine/Ketsji/KX_2DFilterOffScreen.cpp +++ b/source/gameengine/Ketsji/KX_2DFilterOffScreen.cpp @@ -91,28 +91,20 @@ PyObject *KX_2DFilterOffScreen::pyattr_get_height(EXP_PyObjectPlus *self_v, cons return PyLong_FromLong(self->GetHeight()); } -static int kx_2dfilter_offscreen_get_textures_size_cb(void *self_v) +unsigned int KX_2DFilterOffScreen::py_get_textures_size() { return RAS_2DFilterOffScreen::NUM_COLOR_SLOTS; } -static PyObject *kx_2dfilter_offscreen_get_textures_item_cb(void *self_v, int index) +PyObject *KX_2DFilterOffScreen::py_get_textures_item(unsigned int index) { - int bindCode = static_cast(self_v)->GetColorBindCode(index); + const int bindCode = GetColorBindCode(index); return PyLong_FromLong(bindCode); } PyObject *KX_2DFilterOffScreen::pyattr_get_colorBindCodes(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - KX_2DFilterOffScreen *self = static_cast(self_v); - - return (new EXP_ListWrapper(self_v, - self->GetProxy(), - nullptr, - kx_2dfilter_offscreen_get_textures_size_cb, - kx_2dfilter_offscreen_get_textures_item_cb, - nullptr, - nullptr))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } PyObject *KX_2DFilterOffScreen::pyattr_get_depthBindCode(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/Ketsji/KX_2DFilterOffScreen.h b/source/gameengine/Ketsji/KX_2DFilterOffScreen.h index a0ffaadd8b0e..4afcd0cf3512 100644 --- a/source/gameengine/Ketsji/KX_2DFilterOffScreen.h +++ b/source/gameengine/Ketsji/KX_2DFilterOffScreen.h @@ -46,6 +46,9 @@ class KX_2DFilterOffScreen : public EXP_Value, public RAS_2DFilterOffScreen static PyObject *pyattr_get_colorBindCodes(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); static PyObject *pyattr_get_depthBindCode(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); + unsigned int py_get_textures_size(); + PyObject *py_get_textures_item(unsigned int index); + #endif }; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index d1347d3e13b4..340bfb4b2203 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -597,40 +597,34 @@ PyObject *KX_BlenderMaterial::pyattr_get_shader(EXP_PyObjectPlus *self_v, const return self->PygetShader(nullptr, nullptr); } -static int kx_blender_material_get_textures_size_cb(void *self_v) +unsigned int KX_BlenderMaterial::py_get_textures_size() { return RAS_Texture::MaxUnits; } -static PyObject *kx_blender_material_get_textures_item_cb(void *self_v, int index) +PyObject *KX_BlenderMaterial::py_get_textures_item(unsigned int index) { - BL_Texture *tex = (BL_Texture *)((KX_BlenderMaterial *)self_v)->GetTexture(index); + BL_Texture *tex = static_cast(m_textures[index]); PyObject *item = nullptr; if (tex) { item = tex->GetProxy(); } else { - item = Py_None; - Py_INCREF(Py_None); + Py_RETURN_NONE; } return item; } -static const std::string kx_blender_material_get_textures_item_name_cb(void *self_v, int index) +std::string KX_BlenderMaterial::py_get_textures_item_name(unsigned int index) { - BL_Texture *tex = (BL_Texture *)((KX_BlenderMaterial *)self_v)->GetTexture(index); + BL_Texture *tex = static_cast(m_textures[index]); return (tex ? tex->GetName() : ""); } PyObject *KX_BlenderMaterial::pyattr_get_textures(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((KX_BlenderMaterial *)self_v)->GetProxy(), - nullptr, - kx_blender_material_get_textures_size_cb, - kx_blender_material_get_textures_item_cb, - kx_blender_material_get_textures_item_name_cb, - nullptr))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } PyObject *KX_BlenderMaterial::pyattr_get_blending(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 2836e4dbf2fe..4ac76be10c9d 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -92,6 +92,10 @@ class KX_BlenderMaterial : public EXP_Value, public RAS_IPolyMaterial static PyObject *pyattr_get_specular_alpha(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_specular_alpha(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef, PyObject *value); + unsigned int py_get_textures_size(); + PyObject *py_get_textures_item(unsigned int index); + std::string py_get_textures_item_name(unsigned int index); + EXP_PYMETHOD_DOC(KX_BlenderMaterial, getShader); EXP_PYMETHOD_DOC(KX_BlenderMaterial, getTextureBindcode); diff --git a/source/gameengine/Ketsji/KX_CollisionContactPoints.cpp b/source/gameengine/Ketsji/KX_CollisionContactPoints.cpp index 41ed35facb48..cb4d12df8471 100644 --- a/source/gameengine/Ketsji/KX_CollisionContactPoints.cpp +++ b/source/gameengine/Ketsji/KX_CollisionContactPoints.cpp @@ -132,12 +132,12 @@ PyObject *KX_CollisionContactPoint::pyattr_get_applied_impulse(EXP_PyObjectPlus return PyFloat_FromDouble(self->m_collData->GetAppliedImpulse(self->m_index, self->m_firstObject)); } -static int kx_collision_contact_point_list_get_sensors_size_cb(void *self_v) +static unsigned int kx_collision_contact_point_list_get_size_cb(EXP_PyObjectPlus *self_v) { return ((KX_CollisionContactPointList *)self_v)->GetNumCollisionContactPoint(); } -static PyObject *kx_collision_contact_point_list_get_sensors_item_cb(void *self_v, int index) +static PyObject *kx_collision_contact_point_list_get_item_cb(EXP_PyObjectPlus *self_v, unsigned int index) { return ((KX_CollisionContactPointList *)self_v)->GetCollisionContactPoint(index)->NewProxy(true); } @@ -147,8 +147,8 @@ static PyObject *kx_collision_contact_point_list_get_sensors_item_cb(void *self_ KX_CollisionContactPointList::KX_CollisionContactPointList(const PHY_ICollData *collData, bool firstObject) : #ifdef WITH_PYTHON - EXP_ListWrapper(this, nullptr, nullptr, kx_collision_contact_point_list_get_sensors_size_cb, - kx_collision_contact_point_list_get_sensors_item_cb, nullptr, nullptr), + EXP_BaseListWrapper(this, kx_collision_contact_point_list_get_size_cb, + kx_collision_contact_point_list_get_item_cb, nullptr, nullptr, EXP_BaseListWrapper::FLAG_NO_WEAK_REF), #endif // WITH_PYTHON m_collData(collData), m_firstObject(firstObject) diff --git a/source/gameengine/Ketsji/KX_CollisionContactPoints.h b/source/gameengine/Ketsji/KX_CollisionContactPoints.h index 0af3df745a6a..2ae7295101c2 100644 --- a/source/gameengine/Ketsji/KX_CollisionContactPoints.h +++ b/source/gameengine/Ketsji/KX_CollisionContactPoints.h @@ -64,7 +64,7 @@ class KX_CollisionContactPoint : public EXP_Value class KX_CollisionContactPointList #ifdef WITH_PYTHON - : public EXP_ListWrapper + : public EXP_BaseListWrapper #endif // WITH_PYTHON { private: diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index a72dbae21a32..32bb671be75b 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -3255,85 +3255,68 @@ PyObject *KX_GameObject::pyattr_get_components(EXP_PyObjectPlus *self_v, const E return components ? components->GetProxy() : (new EXP_ListValue())->NewProxy(true); } -static int kx_game_object_get_sensors_size_cb(void *self_v) +unsigned int KX_GameObject::py_get_sensors_size() { - return ((KX_GameObject *)self_v)->GetSensors().size(); + return m_sensors.size(); } -static PyObject *kx_game_object_get_sensors_item_cb(void *self_v, int index) +PyObject *KX_GameObject::py_get_sensors_item(unsigned int index) { - return ((KX_GameObject *)self_v)->GetSensors()[index]->GetProxy(); + return m_sensors[index]->GetProxy(); } -static const std::string kx_game_object_get_sensors_item_name_cb(void *self_v, int index) +std::string KX_GameObject::py_get_sensors_item_name(unsigned int index) { - return ((KX_GameObject *)self_v)->GetSensors()[index]->GetName(); + return m_sensors[index]->GetName(); } -/* These are experimental! */ PyObject *KX_GameObject::pyattr_get_sensors(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((KX_GameObject *)self_v)->GetProxy(), - nullptr, - kx_game_object_get_sensors_size_cb, - kx_game_object_get_sensors_item_cb, - kx_game_object_get_sensors_item_name_cb, - nullptr))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } -static int kx_game_object_get_controllers_size_cb(void *self_v) +unsigned int KX_GameObject::py_get_controllers_size() { - return ((KX_GameObject *)self_v)->GetControllers().size(); + return m_controllers.size(); } -static PyObject *kx_game_object_get_controllers_item_cb(void *self_v, int index) +PyObject *KX_GameObject::py_get_controllers_item(unsigned int index) { - return ((KX_GameObject *)self_v)->GetControllers()[index]->GetProxy(); + return m_controllers[index]->GetProxy(); } -static const std::string kx_game_object_get_controllers_item_name_cb(void *self_v, int index) +std::string KX_GameObject::py_get_controllers_item_name(unsigned int index) { - return ((KX_GameObject *)self_v)->GetControllers()[index]->GetName(); + return m_controllers[index]->GetName(); } PyObject *KX_GameObject::pyattr_get_controllers(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((KX_GameObject *)self_v)->GetProxy(), - nullptr, - kx_game_object_get_controllers_size_cb, - kx_game_object_get_controllers_item_cb, - kx_game_object_get_controllers_item_name_cb, - nullptr))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } -static int kx_game_object_get_actuators_size_cb(void *self_v) +unsigned int KX_GameObject::py_get_actuators_size() { - return ((KX_GameObject *)self_v)->GetActuators().size(); + return m_actuators.size(); } -static PyObject *kx_game_object_get_actuators_item_cb(void *self_v, int index) +PyObject *KX_GameObject::py_get_actuators_item(unsigned int index) { - return ((KX_GameObject *)self_v)->GetActuators()[index]->GetProxy(); + return m_actuators[index]->GetProxy(); } -static const std::string kx_game_object_get_actuators_item_name_cb(void *self_v, int index) +std::string KX_GameObject::py_get_actuators_item_name(unsigned int index) { - return ((KX_GameObject *)self_v)->GetActuators()[index]->GetName(); + return m_actuators[index]->GetName(); } PyObject *KX_GameObject::pyattr_get_actuators(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((KX_GameObject *)self_v)->GetProxy(), - nullptr, - kx_game_object_get_actuators_size_cb, - kx_game_object_get_actuators_item_cb, - kx_game_object_get_actuators_item_name_cb, - nullptr))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } -/* End experimental */ PyObject *KX_GameObject::pyattr_get_children(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index c99311712b09..570aec49664a 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -1021,11 +1021,22 @@ class KX_GameObject : public SCA_IObject, public mt::SimdClassAllocator static PyObject* pyattr_get_lodManager(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_lodManager(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef, PyObject *value); - /* Experimental! */ static PyObject* pyattr_get_sensors(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_controllers(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_actuators(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); - + + unsigned int py_get_sensors_size(); + PyObject *py_get_sensors_item(unsigned int index); + std::string py_get_sensors_item_name(unsigned int index); + + unsigned int py_get_controllers_size(); + PyObject *py_get_controllers_item(unsigned int index); + std::string py_get_controllers_item_name(unsigned int index); + + unsigned int py_get_actuators_size(); + PyObject *py_get_actuators_item(unsigned int index); + std::string py_get_actuators_item_name(unsigned int index); + /* getitem/setitem */ static PyMappingMethods Mapping; static PySequenceMethods Sequence; diff --git a/source/gameengine/Ketsji/KX_LodManager.cpp b/source/gameengine/Ketsji/KX_LodManager.cpp index 8a83750cf191..b77c0c47a58f 100644 --- a/source/gameengine/Ketsji/KX_LodManager.cpp +++ b/source/gameengine/Ketsji/KX_LodManager.cpp @@ -206,25 +206,19 @@ PyAttributeDef KX_LodManager::Attributes[] = { EXP_PYATTRIBUTE_NULL }; -static int kx_lod_manager_get_levels_size_cb(void *self_v) +unsigned int KX_LodManager::py_get_levels_size() { - return static_cast(self_v)->GetLevelCount(); + return m_levels.size(); } -static PyObject *kx_lod_manager_get_levels_item_cb(void *self_v, int index) +PyObject *KX_LodManager::py_get_levels_item(unsigned int index) { - return static_cast(self_v)->GetLevel(index).GetProxy(); + return m_levels[index].GetProxy(); } PyObject *KX_LodManager::pyattr_get_levels(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((KX_LodManager *)self_v)->GetProxy(), - nullptr, - kx_lod_manager_get_levels_size_cb, - kx_lod_manager_get_levels_item_cb, - nullptr, - nullptr))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } bool ConvertPythonToLodManager(PyObject *value, KX_LodManager **object, bool py_none_ok, const char *error_prefix) diff --git a/source/gameengine/Ketsji/KX_LodManager.h b/source/gameengine/Ketsji/KX_LodManager.h index 63c22389af4e..d87a85fd2776 100644 --- a/source/gameengine/Ketsji/KX_LodManager.h +++ b/source/gameengine/Ketsji/KX_LodManager.h @@ -104,6 +104,9 @@ class KX_LodManager : public EXP_Value static PyObject *pyattr_get_levels(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); + unsigned int py_get_levels_size(); + PyObject *py_get_levels_item(unsigned int index); + #endif //WITH_PYTHON }; diff --git a/source/gameengine/Ketsji/KX_Mesh.cpp b/source/gameengine/Ketsji/KX_Mesh.cpp index f1d6618dacad..d9cbd7253862 100644 --- a/source/gameengine/Ketsji/KX_Mesh.cpp +++ b/source/gameengine/Ketsji/KX_Mesh.cpp @@ -419,29 +419,22 @@ PyObject *KX_Mesh::pyattr_get_numPolygons(EXP_PyObjectPlus *self_v, const EXP_PY return PyLong_FromLong(self->m_numPolygons); } -static int kx_mesh_proxy_get_polygons_size_cb(void *self_v) +unsigned int KX_Mesh::py_get_polygons_size() { - return ((KX_Mesh *)self_v)->GetNumPolygons(); + return m_numPolygons; } -static PyObject *kx_mesh_proxy_get_polygons_item_cb(void *self_v, int index) +PyObject *KX_Mesh::py_get_polygons_item(unsigned int index) { - KX_Mesh *self = static_cast(self_v); - const RAS_Mesh::PolygonInfo polygon = self->GetPolygon(index); + const RAS_Mesh::PolygonInfo polygon = GetPolygon(index); - KX_PolyProxy *polyProxy = new KX_PolyProxy(self, polygon); + KX_PolyProxy *polyProxy = new KX_PolyProxy(this, polygon); return polyProxy->NewProxy(true); } PyObject *KX_Mesh::pyattr_get_polygons(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((KX_Mesh *)self_v)->GetProxy(), - nullptr, - kx_mesh_proxy_get_polygons_size_cb, - kx_mesh_proxy_get_polygons_item_cb, - nullptr, - nullptr))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } /* a close copy of ConvertPythonToGameObject but for meshes */ diff --git a/source/gameengine/Ketsji/KX_Mesh.h b/source/gameengine/Ketsji/KX_Mesh.h index 2d909632b29b..96dfd24037bf 100644 --- a/source/gameengine/Ketsji/KX_Mesh.h +++ b/source/gameengine/Ketsji/KX_Mesh.h @@ -82,6 +82,9 @@ class KX_Mesh : public EXP_Value, public RAS_Mesh static PyObject *pyattr_get_numPolygons(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); static PyObject *pyattr_get_polygons(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); + unsigned int py_get_polygons_size(); + PyObject *py_get_polygons_item(unsigned int index); + #endif // WITH_PYTHON }; diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp index 4b99bd2816dc..b90c57496cbb 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.cpp +++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp @@ -179,30 +179,22 @@ PyObject *KX_PolyProxy::pyattr_get_collide(EXP_PyObjectPlus *self_v, const EXP_P return self->PyisCollider(); } -static int kx_poly_proxy_get_vertices_size_cb(void *self_v) +unsigned int KX_PolyProxy::py_get_vertices_size() { return 3; } -static PyObject *kx_poly_proxy_get_vertices_item_cb(void *self_v, int index) +PyObject *KX_PolyProxy::py_get_vertices_item(unsigned int index) { - KX_PolyProxy *self = static_cast(self_v); - const RAS_Mesh::PolygonInfo& polygon = self->GetPolygon(); - RAS_IDisplayArray *array = polygon.array; - KX_VertexProxy *vert = new KX_VertexProxy(array, array->GetVertex(polygon.indices[index])); + RAS_IDisplayArray *array = m_polygon.array; + KX_VertexProxy *vert = new KX_VertexProxy(array, array->GetVertex(m_polygon.indices[index])); - return vert->GetProxy(); + return vert->NewProxy(true); } PyObject *KX_PolyProxy::pyattr_get_vertices(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((KX_PolyProxy *)self_v)->GetProxy(), - nullptr, - kx_poly_proxy_get_vertices_size_cb, - kx_poly_proxy_get_vertices_item_cb, - nullptr, - nullptr))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } EXP_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterialIndex, diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h index 69dbda47d104..685a7dff5702 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.h +++ b/source/gameengine/Ketsji/KX_PolyProxy.h @@ -68,6 +68,9 @@ class KX_PolyProxy : public EXP_Value static PyObject *pyattr_get_collide(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); static PyObject *pyattr_get_vertices(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef); + unsigned int py_get_vertices_size(); + PyObject *py_get_vertices_item(unsigned int index); + EXP_PYMETHOD_DOC_NOARGS(KX_PolyProxy, getMaterialIndex) EXP_PYMETHOD_DOC_NOARGS(KX_PolyProxy, getNumVertex) EXP_PYMETHOD_DOC_NOARGS(KX_PolyProxy, isVisible) diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp index 0c0f0f701c50..0ee5f5da2975 100644 --- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp +++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp @@ -222,7 +222,7 @@ PyMODINIT_FUNC initGameTypesPythonBinding(void) PyType_Ready_Attr(dict, BL_Texture, init_getset); // PyType_Ready_Attr(dict, EXP_PropValue, init_getset); // doesn't use Py_Header PyType_Ready_Attr(dict, EXP_BaseListValue, init_getset); - PyType_Ready_Attr(dict, EXP_ListWrapper, init_getset); + PyType_Ready_Attr(dict, EXP_BaseListWrapper, init_getset); PyType_Ready_Attr(dict, EXP_Value, init_getset); PyType_Ready_Attr(dict, KX_2DFilter, init_getset); PyType_Ready_Attr(dict, KX_2DFilterManager, init_getset); diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.cpp b/source/gameengine/Ketsji/KX_SteeringActuator.cpp index b71cb0f794ca..3c0b99176d52 100644 --- a/source/gameengine/Ketsji/KX_SteeringActuator.cpp +++ b/source/gameengine/Ketsji/KX_SteeringActuator.cpp @@ -619,26 +619,19 @@ PyObject *KX_SteeringActuator::pyattr_get_steeringVec(EXP_PyObjectPlus *self, co return PyObjectFrom(steeringVec); } -static int kx_steering_actuator_get_path_size_cb(void *self) +unsigned int KX_SteeringActuator::py_get_path_size() { - return ((KX_SteeringActuator *)self)->m_path.size(); + return m_path.size(); } -static PyObject *kx_steering_actuator_get_path_item_cb(void *self, int index) +PyObject *KX_SteeringActuator::py_get_path_item(unsigned int index) { - const mt::vec3& vec = ((KX_SteeringActuator *)self)->m_path[index]; - return PyObjectFrom(vec); + return PyObjectFrom(m_path[index]); } PyObject *KX_SteeringActuator::pyattr_get_path(EXP_PyObjectPlus *self, const struct EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self, - ((KX_SteeringActuator *)self)->GetProxy(), - nullptr, - kx_steering_actuator_get_path_size_cb, - kx_steering_actuator_get_path_item_cb, - nullptr, - nullptr))->NewProxy(true); + return (new EXP_ListWrapper(self))->NewProxy(true); } #endif // WITH_PYTHON diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.h b/source/gameengine/Ketsji/KX_SteeringActuator.h index 28588852381a..0cf1538ab7ef 100644 --- a/source/gameengine/Ketsji/KX_SteeringActuator.h +++ b/source/gameengine/Ketsji/KX_SteeringActuator.h @@ -102,6 +102,9 @@ class KX_SteeringActuator : public SCA_IActuator, public mt::SimdClassAllocator static PyObject *pyattr_get_steeringVec(EXP_PyObjectPlus *self, const struct EXP_PYATTRIBUTE_DEF *attrdef); static PyObject *pyattr_get_path(EXP_PyObjectPlus *self, const struct EXP_PYATTRIBUTE_DEF *attrdef); + unsigned int py_get_path_size(); + PyObject *py_get_path_item(unsigned int index); + #endif // WITH_PYTHON }; diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index 91b16801f681..1a607efeed77 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -185,78 +185,66 @@ PyObject *KX_VertexProxy::pyattr_get_UV(EXP_PyObjectPlus *self_v, const EXP_PYAT return PyObjectFrom(self->m_vertex.GetUv(0)); } -static int kx_vertex_proxy_get_uvs_size_cb(void *self_v) +unsigned int KX_VertexProxy::py_get_uvs_size() { - return ((KX_VertexProxy *)self_v)->GetVertex().GetFormat().uvSize; + return m_vertex.GetFormat().uvSize; } -static PyObject *kx_vertex_proxy_get_uvs_item_cb(void *self_v, int index) +PyObject *KX_VertexProxy::py_get_uvs_item(unsigned int index) { - mt::vec2 uv = mt::vec2(((KX_VertexProxy *)self_v)->GetVertex().GetUv(index)); + const mt::vec2 uv = mt::vec2(m_vertex.GetUv(index)); return PyObjectFrom(uv); } -static bool kx_vertex_proxy_set_uvs_item_cb(void *self_v, int index, PyObject *item) +bool KX_VertexProxy::py_set_uvs_item(unsigned int index, PyObject *item) { mt::vec2 uv; if (!PyVecTo(item, uv)) { return false; } - KX_VertexProxy *self = ((KX_VertexProxy *)self_v); - self->GetVertex().SetUV(index, uv); - self->GetDisplayArray()->NotifyUpdate(RAS_IDisplayArray::UVS_MODIFIED); + m_vertex.SetUV(index, uv); + m_array->NotifyUpdate(RAS_IDisplayArray::UVS_MODIFIED); return true; } PyObject *KX_VertexProxy::pyattr_get_uvs(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((KX_VertexProxy *)self_v)->GetProxy(), - nullptr, - kx_vertex_proxy_get_uvs_size_cb, - kx_vertex_proxy_get_uvs_item_cb, - nullptr, - kx_vertex_proxy_set_uvs_item_cb))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } -static int kx_vertex_proxy_get_colors_size_cb(void *self_v) +unsigned int KX_VertexProxy::py_get_colors_size() { - return ((KX_VertexProxy *)self_v)->GetVertex().GetFormat().colorSize; + return m_vertex.GetFormat().colorSize; } -static PyObject *kx_vertex_proxy_get_colors_item_cb(void *self_v, int index) +PyObject *KX_VertexProxy::py_get_colors_item(unsigned int index) { - const unsigned char *rgba = ((KX_VertexProxy *)self_v)->GetVertex().GetColor(index); + const unsigned char *rgba = m_vertex.GetColor(index); mt::vec4 color(rgba[0], rgba[1], rgba[2], rgba[3]); color /= 255.0f; return PyObjectFrom(color); } -static bool kx_vertex_proxy_set_colors_item_cb(void *self_v, int index, PyObject *item) +bool KX_VertexProxy::py_set_colors_item(unsigned int index, PyObject *item) { mt::vec4 color; if (!PyVecTo(item, color)) { return false; } - KX_VertexProxy *self = ((KX_VertexProxy *)self_v); - self->GetVertex().SetColor(index, color); - self->GetDisplayArray()->NotifyUpdate(RAS_IDisplayArray::COLORS_MODIFIED); + m_vertex.SetColor(index, color); + m_array->NotifyUpdate(RAS_IDisplayArray::COLORS_MODIFIED); return true; } PyObject *KX_VertexProxy::pyattr_get_colors(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) { - return (new EXP_ListWrapper(self_v, - ((KX_VertexProxy *)self_v)->GetProxy(), - nullptr, - kx_vertex_proxy_get_colors_size_cb, - kx_vertex_proxy_get_colors_item_cb, - nullptr, - kx_vertex_proxy_set_colors_item_cb))->NewProxy(true); + return (new EXP_ListWrapper(self_v))->NewProxy(true); } PyObject *KX_VertexProxy::pyattr_get_color(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index 98ccde6fd1bb..7b5c90c54e2a 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -93,6 +93,13 @@ class KX_VertexProxy : public EXP_Value static int pyattr_set_normal(EXP_PyObjectPlus *self, const EXP_PYATTRIBUTE_DEF *attrdef, PyObject *value); static int pyattr_set_uvs(EXP_PyObjectPlus *self, const EXP_PYATTRIBUTE_DEF *attrdef, PyObject *value); + unsigned int py_get_uvs_size(); + PyObject *py_get_uvs_item(unsigned int index); + bool py_set_uvs_item(unsigned int index, PyObject *item); + unsigned int py_get_colors_size(); + PyObject *py_get_colors_item(unsigned int index); + bool py_set_colors_item(unsigned int index, PyObject *item); + EXP_PYMETHOD_NOARGS(KX_VertexProxy, GetXYZ); EXP_PYMETHOD_O(KX_VertexProxy, SetXYZ); EXP_PYMETHOD_NOARGS(KX_VertexProxy, GetUV1);