Skip to content
panzergame edited this page Dec 6, 2016 · 2 revisions

CListValueand 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 CListWrapperlooks:

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 flagargument 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 CListValueinstead of CListWrapperbut as the sensors are stored in a list in a level which doesn't know/use the CListValue, then we use CListWrapper.

Clone this wiki locally