CListWrapper - UPBGE/upbge GitHub Wiki
CListValue
and CListWrapper
are objects which contain python functions to behave like a list and a dictionnary for item name research. The difference between the both is that CListValue
is more used when the list will be frequently accessed in python and that the data are not temporary and not abundant. CListWrapper
respond to these issue by getting the python object of an item only at its access. By this way the data are unlimited but temporary.
The constructor of CListWrapper
looks:
CListWrapper(void *client,
PyObject *base,
bool (*checkValid)(void *),
int (*getSize)(void *),
PyObject *(*getItem)(void *, int),
const char *(*getItemName)(void *, int),
bool (*setItem)(void *, int, PyObject *),
int flag = FLAG_NONE);
CListWrapper
use five callbacks:
bool (*checkValid)(void *)
Return true when the object which own the list is still valid, it can be used to make a list invalid sooner. (optional)
int (*getSize)(void *)
Return the size of the list.
PyObject *(*getItem)(void *, int)
Return the python proxy (or value) of an item at the given index.
const char *(*getItemName)(void *, int)
Return the name of the item at the given index, if this callback is NULL then name research is disallowed. (optional)
bool (*setItem)(void *, int, PyObject *)
Set the item value at the given index and the given python object, this callback can be NULL and then disallow the list to be writable.
In the same time the CListWrapper
need in its constructor the client object (the owner of the list), its python proxy to make sure we can check if the python proxy of the client is still valid and a flag
argument which can be the two values: FLAG_NONE
and FLAG_FIND_VALUE
. The last one allow to search if an item exist in a list by doing in python:
if item in list:
pass
An example of use of CListWrapper
is in KX_GameObject
for the sensors list:
static int kx_game_object_get_sensors_size_cb(void *self_v)
{
return ((KX_GameObject *)self_v)->GetSensors().size();
}
static PyObject *kx_game_object_get_sensors_item_cb(void *self_v, int index)
{
return ((KX_GameObject *)self_v)->GetSensors()[index]->GetProxy();
}
static const char *kx_game_object_get_sensors_item_name_cb(void *self_v, int index)
{
return ((KX_GameObject *)self_v)->GetSensors()[index]->GetName().ReadPtr();
}
PyObject *KX_GameObject::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
return (new CListWrapper(self_v,
((KX_GameObject *)self_v)->GetProxy(),
NULL,
kx_game_object_get_sensors_size_cb,
kx_game_object_get_sensors_item_cb,
kx_game_object_get_sensors_item_name_cb,
NULL))->NewProxy(true);
}
Here the conditions are here to use CListValue
instead of CListWrapper
but as the sensors are stored in a list in a level which doesn't know/use the CListValue
, then we use CListWrapper
.