Revision: 6907
http://playerstage.svn.sourceforge.net/playerstage/?rev=6907&view=rev
Author: thjc
Date: 2008-07-23 05:30:31 +0000 (Wed, 23 Jul 2008)
Log Message:
-----------
Fix for python blackboard proxy, the second time you subscribed to a key
with the same group that has not been set it would throw an exception.
Modified Paths:
--------------
code/player/branches/release-2-1-patches/client_libs/libplayerc/bindings/python/playerc.i
Modified:
code/player/branches/release-2-1-patches/client_libs/libplayerc/bindings/python/playerc.i
===================================================================
---
code/player/branches/release-2-1-patches/client_libs/libplayerc/bindings/python/playerc.i
2008-07-23 05:01:11 UTC (rev 6906)
+++
code/player/branches/release-2-1-patches/client_libs/libplayerc/bindings/python/playerc.i
2008-07-23 05:30:31 UTC (rev 6907)
@@ -422,15 +422,17 @@
#define LIST_EVENTS_INDEX 2
#define BOOL_QUEUE_EVENTS_INDEX 3
-// Helper function to convert a c blackboard_entry_t into a python dictionary
object
+// Helper function to convert a c blackboard_entry_t into a python dictionary
object.
+// Returns a new reference to a dictionary object.
PyObject *__convert_blackboard_entry__(player_blackboard_entry_t *entry)
{
PyObject *entry_dict, *data;
char* str;
int i;
double d;
+ int ok;
- entry_dict = PyDict_New();
+ entry_dict = PyDict_New(); // New reference
assert (entry_dict);
assert(entry);
@@ -439,22 +441,68 @@
assert(entry->group);
assert(entry->group_count > 0);
- PyDict_SetItemString(entry_dict, "key", PyString_FromString(entry->key));
- PyDict_SetItemString(entry_dict, "group",
PyString_FromString(entry->group));
- PyDict_SetItemString(entry_dict, "type", PyLong_FromLong(entry->type));
- PyDict_SetItemString(entry_dict, "subtype", PyLong_FromLong(entry->subtype));
- PyDict_SetItemString(entry_dict, "timestamp_sec",
PyLong_FromLong(entry->timestamp_sec));
- PyDict_SetItemString(entry_dict, "timestamp_usec",
PyLong_FromLong(entry->timestamp_usec));
+ ok = PyDict_SetItemString(entry_dict, "key",
PyString_FromString(entry->key)); // Steals reference
+ if (ok != 0)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Could not set dictionary value for
'key'");
+ Py_XDECREF(entry_dict);
+ return NULL;
+ }
+ ok = PyDict_SetItemString(entry_dict, "group",
PyString_FromString(entry->group)); // Steals reference
+ if (ok != 0)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Could not set dictionary value for
'group'");
+ Py_XDECREF(entry_dict);
+ return NULL;
+ }
+
+ ok = PyDict_SetItemString(entry_dict, "type", PyLong_FromLong(entry->type));
// Steals reference
+ if (ok != 0)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Could not set dictionary value for
'type'");
+ Py_XDECREF(entry_dict);
+ return NULL;
+ }
+
+ ok = PyDict_SetItemString(entry_dict, "subtype",
PyLong_FromLong(entry->subtype)); // Steals reference
+ if (ok != 0)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Could not set dictionary value for
'subtype'");
+ Py_XDECREF(entry_dict);
+ return NULL;
+ }
+
+ ok = PyDict_SetItemString(entry_dict, "timestamp_sec",
PyLong_FromLong(entry->timestamp_sec)); // Steals reference
+ if (ok != 0)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Could not set dictionary value for
'timestamp_sec'");
+ Py_XDECREF(entry_dict);
+ return NULL;
+ }
+
+ ok = PyDict_SetItemString(entry_dict, "timestamp_usec",
PyLong_FromLong(entry->timestamp_usec)); // Steals reference
+ if (ok != 0)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Could not set dictionary value for
'timestamp_usec'");
+ Py_XDECREF(entry_dict);
+ return NULL;
+ }
+
switch(entry->subtype)
{
case PLAYERC_BLACKBOARD_DATA_SUBTYPE_NONE:
data = Py_None;
+ Py_INCREF(data);
break;
case PLAYERC_BLACKBOARD_DATA_SUBTYPE_STRING:
assert(entry->type == PLAYERC_BLACKBOARD_DATA_TYPE_COMPLEX);
str = malloc(entry->data_count);
- assert(str);
+ if (!str)
+ {
+ Py_XDECREF(entry_dict);
+ return PyErr_NoMemory();
+ }
memcpy(str, entry->data, entry->data_count);
data = PyString_FromString(str);
break;
@@ -472,17 +520,27 @@
break;
default:
data = Py_None;
+ Py_INCREF(data);
break;
}
- PyDict_SetItemString(entry_dict, "data", data);
+ ok = PyDict_SetItemString(entry_dict, "data", data); // Steals reference
+ if (ok != 0)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Could not set dictionary value for
'data'");
+ Py_XDECREF(entry_dict);
+ return NULL;
+ }
+
return entry_dict;
}
// Helper function which sets a value in a nested dictionary. Equivalent of
dict['group']['key'] = value.
+// Steals the entry reference.
PyObject *__set_nested_dictionary_entry__(PyObject *dict, const char* key,
const char* group, PyObject *entry)
{
PyObject *group_dict;
+ int ok;
int create_dict = 0;
// Check we got valid arguments.
@@ -511,19 +569,34 @@
}
// Get the dictionary for the entry's group. If it doesn't exist, create it.
- group_dict = (PyObject*)PyDict_GetItemString(dict, group);
+ group_dict = (PyObject*)PyDict_GetItemString(dict, group); // Borrowed
reference
if (!group_dict)
{
create_dict = 1;
- group_dict = PyDict_New();
+ group_dict = PyDict_New(); // New reference
}
- PyDict_SetItemString(group_dict, key, entry);
+ ok = PyDict_SetItemString(group_dict, key, entry); // Steals reference
+ if (ok != 0)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Failed to set dictionary entry");
+ if (create_dict)
+ {
+ Py_XDECREF(group_dict);
+ }
+ return NULL;
+ }
// If we created the dictionary, we need to put it in the parent dictionary.
if (create_dict == 1)
{
- PyDict_SetItemString(dict, group, group_dict);
+ ok = PyDict_SetItemString(dict, group, group_dict); // Steals reference
+ if (ok != 0)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Failed to set dictionary entry");
+ Py_XDECREF(group_dict);
+ return NULL;
+ }
}
Py_RETURN_NONE;
@@ -535,21 +608,31 @@
PyObject *group_dict, *entry;
int old_value, new_value;
- // Get the dictionary for the entry's group. If it doesn't exist, create it
and increment it.
- group_dict = (PyObject*)PyDict_GetItemString(dict, group);
+ // Get the dictionary for the entry's group. If it doesn't exist.
+ group_dict = (PyObject*)PyDict_GetItemString(dict, group); // Borrowed
reference
if (!group_dict)
{
- playerc_blackboard___set_nested_dictionary_entry__(self, dict, key, group,
(PyObject*)PyInt_FromLong(inc));
+ playerc_blackboard___set_nested_dictionary_entry__(self, dict, key, group,
(PyObject*)PyInt_FromLong(inc)); // Steals reference to entry
return inc;
}
- entry = PyDict_GetItemString(group_dict, key);
- old_value = PyLong_AsLong(entry);
+ entry = PyDict_GetItemString(group_dict, key); // Borrowed reference
+ if (entry)
+ {
+ old_value = PyLong_AsLong(entry);
+ }
+ else
+ {
+ old_value = 0;
+ }
+
new_value = old_value + inc;
if (new_value < 0)
+ {
new_value = 0;
+ }
- playerc_blackboard___set_nested_dictionary_entry__(self, dict, key, group,
PyInt_FromLong(new_value));
+ playerc_blackboard___set_nested_dictionary_entry__(self, dict, key, group,
PyInt_FromLong(new_value)); // Steals reference to entry
return new_value;
}
@@ -561,24 +644,25 @@
// Get the main groups dictionary
assert(device->py_private);
- groups_dict = (PyObject*)PyTuple_GetItem(device->py_private,
DICT_GROUPS_INDEX);
+ groups_dict = (PyObject*)PyTuple_GetItem(device->py_private,
DICT_GROUPS_INDEX); // Borrowed reference
assert(groups_dict);
// Get a dictionary of the entry
- entry_dict = playerc_blackboard___convert_blackboard_entry__(device, &entry);
+ entry_dict = playerc_blackboard___convert_blackboard_entry__(device,
&entry); // New reference
assert(entry_dict);
- // Set the entry in the groups dictionary
- playerc_blackboard___set_nested_dictionary_entry__(device, groups_dict,
entry.key, entry.group, entry_dict);
-
+
// If we are queueing events, add them to the list
- queue_events = PyTuple_GetItem(device->py_private, BOOL_QUEUE_EVENTS_INDEX);
+ queue_events = PyTuple_GetItem(device->py_private, BOOL_QUEUE_EVENTS_INDEX);
// Borrowed reference
assert(queue_events);
if (PyLong_AsLong(queue_events) != 0)
{
- list = (PyObject*)PyTuple_GetItem(device->py_private, LIST_EVENTS_INDEX);
+ list = (PyObject*)PyTuple_GetItem(device->py_private, LIST_EVENTS_INDEX);
// Borrowed reference
assert(list);
- PyList_Append(list, PyDict_Copy(entry_dict));
+ PyList_Append(list, entry_dict); // Increments refcount for us
}
+
+ // Set the entry in the groups dictionary
+ playerc_blackboard___set_nested_dictionary_entry__(device, groups_dict,
entry.key, entry.group, entry_dict); // Steals reference to entry_dict
}
// Returns a list of dictionary objects containing the entries.
@@ -588,20 +672,32 @@
%feature("autodoc", "1");
PyObject *GetEvents()
{
- PyObject *list, *copy;
- int i, j;
+ PyObject *list, *copy, *item;
+ int i, j, ok;
assert(self->py_private);
- list = (PyObject*)PyTuple_GetItem(self->py_private, LIST_EVENTS_INDEX);
+ list = (PyObject*)PyTuple_GetItem(self->py_private, LIST_EVENTS_INDEX); //
Borrowed reference
assert(list);
- copy = PyList_New(0);
j = PyList_Size(list);
+ copy = PyList_New(j); // New reference
+
for (i = 0; i < j; i++)
{
- PyList_Append(copy, PyList_GetItem(list, 0));
+ item = PyList_GetItem(list, 0); // Borrowed reference
+ Py_INCREF(item);
+ assert(item);
+ ok = PyList_SetItem(copy, i, item); // Steals reference
+ if (ok != 0)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Failed to set list entry");
+ Py_XDECREF(copy);
+ Py_XDECREF(item);
+ return NULL;
+ }
PySequence_DelItem(list,0);
}
+
return copy;
}
@@ -610,28 +706,21 @@
// Will always return a dictionary object.
PyObject *GetDict()
{
- PyObject *dict, *copy, *list, *pair;
- int i, j;
+ PyObject *dict, *copy;
assert(self->py_private);
- dict = (PyObject*)PyTuple_GetItem(self->py_private, DICT_GROUPS_INDEX);
+ dict = (PyObject*)PyTuple_GetItem(self->py_private, DICT_GROUPS_INDEX); //
Borrowed reference
assert(dict);
- copy = PyDict_New();
- list = PyDict_Items(dict);
- j = PyList_Size(list);
- for (i = 0; i < j; i++)
- {
- pair = PyList_GetItem(list, i);
- PyDict_SetItem(copy, PyTuple_GetItem(pair, 0), PyTuple_GetItem(pair, 1));
- }
-
+ copy = PyDict_Copy(dict); // New reference
return copy;
}
// Set whether events should be put into the list, to be retrieved by
get_events_list().
PyObject *SetQueueEvents(PyObject *boolean)
{
+ int ok;
+
if(!PyBool_Check(boolean))
{
PyErr_SetString(PyExc_TypeError, "Expected type 'bool'");
@@ -639,11 +728,21 @@
}
if (boolean == Py_False)
{
- PyTuple_SetItem(self->py_private, BOOL_QUEUE_EVENTS_INDEX,
PyLong_FromLong(0));
+ ok = PyTuple_SetItem((PyObject*)self->py_private, BOOL_QUEUE_EVENTS_INDEX,
PyLong_FromLong(0)); // Steals reference
+ if (ok != 0)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Failed to set tuple entry");
+ return NULL;
+ }
}
else
{
- PyTuple_SetItem(self->py_private, BOOL_QUEUE_EVENTS_INDEX,
PyLong_FromLong(1));
+ ok = PyTuple_SetItem((PyObject*)self->py_private, BOOL_QUEUE_EVENTS_INDEX,
PyLong_FromLong(1)); // Steals reference
+ if (ok != 0)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Failed to set tuple entry");
+ return NULL;
+ }
}
Py_RETURN_NONE;
@@ -688,14 +787,15 @@
{
PyObject *groups_dict, *group_dict, *subscription_data;
int result, ref_count;
- subscription_data = PyTuple_GetItem(self->py_private,
DICT_SUBSCRIPTION_DATA_INDEX);
+
+ subscription_data = PyTuple_GetItem((PyObject*)self->py_private,
DICT_SUBSCRIPTION_DATA_INDEX); // Borrowed reference
assert(subscription_data);
ref_count = playerc_blackboard___increment_reference_count__(self,
subscription_data, key, group, -1);
if (ref_count <= 0)
{
- groups_dict = PyTuple_GetItem(self->py_private, DICT_GROUPS_INDEX);
+ groups_dict = PyTuple_GetItem((PyObject*)self->py_private,
DICT_GROUPS_INDEX); // Borrowed reference
assert(groups_dict);
- group_dict = PyDict_GetItemString(groups_dict, group);
+ group_dict = PyDict_GetItemString(groups_dict, group); // Borrowed
reference
assert(group_dict);
PyDict_DelItemString(group_dict, key);
}
@@ -717,14 +817,15 @@
return NULL;
}
- entry_dict = playerc_blackboard___convert_blackboard_entry__(self, entry);
- groups_dict = (PyObject*)PyTuple_GetItem(self->py_private,
DICT_GROUPS_INDEX);
+ entry_dict = playerc_blackboard___convert_blackboard_entry__(self, entry);
// New reference
+ assert(entry_dict);
+ groups_dict = (PyObject*)PyTuple_GetItem((PyObject*)self->py_private,
DICT_GROUPS_INDEX); // Borrowed reference
assert(groups_dict);
- assert(entry_dict);
- playerc_blackboard___set_nested_dictionary_entry__(self, groups_dict, key,
group, entry_dict);
+ Py_INCREF(entry_dict);
+ playerc_blackboard___set_nested_dictionary_entry__(self, groups_dict, key,
group, entry_dict); // Steals reference to entry_dict
- subscription_data = PyTuple_GetItem(self->py_private,
DICT_SUBSCRIPTION_DATA_INDEX);
+ subscription_data = PyTuple_GetItem((PyObject*)self->py_private,
DICT_SUBSCRIPTION_DATA_INDEX); // Borrowed reference
assert(subscription_data);
playerc_blackboard___increment_reference_count__(self, subscription_data,
key, group, 1);
@@ -740,40 +841,48 @@
int UnsubscribeFromGroup(const char *group)
{
int i, j, ref_count;
- PyObject *groups_dict, *group_dict, *list, *tuple, *subscription_data,
*items;
+ PyObject *groups_dict, *group_dict, *list, *tuple, *subscription_data,
*items, *item;
const char* key;
int result;
+
result = playerc_blackboard_unsubscribe_from_group(self, group);
assert(self->py_private);
- groups_dict = PyTuple_GetItem(self->py_private, DICT_GROUPS_INDEX);
+ groups_dict = PyTuple_GetItem((PyObject*)self->py_private,
DICT_GROUPS_INDEX); // Borrowed reference
assert(groups_dict);
- group_dict = PyDict_GetItemString(groups_dict, group);
+ group_dict = PyDict_GetItemString(groups_dict, group); // Borrowed reference
if (group_dict)
{
- list = PyList_New(0);
- subscription_data = PyTuple_GetItem(self->py_private,
DICT_SUBSCRIPTION_DATA_INDEX);
+ list = PyList_New(0); // New reference
+ subscription_data = PyTuple_GetItem((PyObject*)self->py_private,
DICT_SUBSCRIPTION_DATA_INDEX); // Borrowed reference
assert(subscription_data);
items = PyDict_Items(group_dict);
j = PyList_Size(items);
for (i = 0; i < j; i++)
{
- tuple = PyList_GetItem(items, 0);
- key = PyString_AsString(PyTuple_GetItem(tuple, 0));
+ tuple = PyList_GetItem(items, 0); // Borrowed reference
+ assert(tuple);
+ item = PyTuple_GetItem(tuple, 0); // Borrowed reference
+ assert(item);
+ key = PyString_AsString(item);
ref_count = playerc_blackboard___increment_reference_count__(self,
subscription_data, key, group, 0);
if (ref_count <= 0)
- {
- PyList_Append(list, PyTuple_GetItem(tuple, 0));
+ {
+ PyList_Append(list, item); // Increments refcount for us
}
}
j = PyList_Size(list);
for (i =0; i < j; i++)
{
- PyDict_DelItem(group_dict, PyList_GetItem(list, i));
+ item = PyList_GetItem(list, i); // Borrowed reference
+ assert(item);
+ PyDict_DelItem(group_dict, item);
}
+
+ Py_DECREF(list);
}
return result;
@@ -798,12 +907,13 @@
PyErr_SetString(PyExc_RuntimeError, "Failed to get entry");
return NULL;
}
- entry_dict = playerc_blackboard___convert_blackboard_entry__(self, entry);
+ entry_dict = playerc_blackboard___convert_blackboard_entry__(self, entry);
// New reference
- groups_dict = PyTuple_GetItem(self->py_private, DICT_GROUPS_INDEX);
+ groups_dict = PyTuple_GetItem((PyObject*)self->py_private,
DICT_GROUPS_INDEX); // Borrowed reference
assert(groups_dict);
assert(entry_dict);
- playerc_blackboard___set_nested_dictionary_entry__(self, groups_dict, key,
group, entry_dict);
+ Py_INCREF(entry_dict);
+ playerc_blackboard___set_nested_dictionary_entry__(self, groups_dict, key,
group, entry_dict); // Steals reference to entry_dict
free(entry->key);
free(entry->group);
@@ -818,12 +928,12 @@
int result;
PyObject *entry_dict, *groups_dict;
- entry_dict = playerc_blackboard___convert_blackboard_entry__(self, entry);
- groups_dict = PyTuple_GetItem(self->py_private, DICT_GROUPS_INDEX);
+ entry_dict = playerc_blackboard___convert_blackboard_entry__(self, entry);
// New reference
+ assert(entry_dict);
+ groups_dict = PyTuple_GetItem((PyObject*)self->py_private,
DICT_GROUPS_INDEX); // Borrowed reference
assert(groups_dict);
- assert(entry_dict);
- playerc_blackboard___set_nested_dictionary_entry__(self, groups_dict,
entry->key, entry->group, entry_dict);
+ playerc_blackboard___set_nested_dictionary_entry__(self, groups_dict,
entry->key, entry->group, entry_dict); // Steals reference to entry_dict
result = playerc_blackboard_set_entry(self, entry);
return PyInt_FromLong(result);
}
@@ -844,13 +954,13 @@
player_blackboard_entry_t entry;
memset(&entry, 0, sizeof(entry));
- key = PyDict_GetItem(dict, PyString_FromString("key"));
- group = PyDict_GetItem(dict, PyString_FromString("group"));
- type = PyDict_GetItem(dict, PyString_FromString("type"));
- subtype = PyDict_GetItem(dict, PyString_FromString("subtype"));
- timestamp_sec = PyDict_GetItem(dict, PyString_FromString("timestamp_sec"));
- timestamp_usec = PyDict_GetItem(dict, PyString_FromString("timestamp_usec"));
- data = PyDict_GetItem(dict, PyString_FromString("data"));
+ key = PyDict_GetItem(dict, PyString_FromString("key")); // Borrowed reference
+ group = PyDict_GetItem(dict, PyString_FromString("group")); // Borrowed
reference
+ type = PyDict_GetItem(dict, PyString_FromString("type")); // Borrowed
reference
+ subtype = PyDict_GetItem(dict, PyString_FromString("subtype")); // Borrowed
reference
+ timestamp_sec = PyDict_GetItem(dict, PyString_FromString("timestamp_sec"));
// Borrowed reference
+ timestamp_usec = PyDict_GetItem(dict,
PyString_FromString("timestamp_usec")); // Borrowed reference
+ data = PyDict_GetItem(dict, PyString_FromString("data")); // Borrowed
reference
if (key == NULL || group == NULL || type == NULL || subtype == NULL ||
timestamp_sec == NULL || timestamp_usec == NULL || data == NULL)
{
@@ -958,10 +1068,10 @@
}
result = playerc_blackboard_set_entry(self, &entry);
- groups_dict = PyTuple_GetItem(self->py_private, DICT_GROUPS_INDEX);
+ groups_dict = PyTuple_GetItem((PyObject*)self->py_private,
DICT_GROUPS_INDEX); // Borrowed reference
assert(groups_dict);
- assert(entry_dict);
- playerc_blackboard___set_nested_dictionary_entry__(self, groups_dict,
entry.key, entry.group, dict);
+ Py_INCREF(dict);
+ playerc_blackboard___set_nested_dictionary_entry__(self, groups_dict,
entry.key, entry.group, dict); // Steals reference to entry
free(entry.data);
return PyInt_FromLong(result);
@@ -985,7 +1095,7 @@
// Tuple item 1: Dictionary of keys that have been subscribed to.
// Tuple item 2: List of all events that have occurred. Need to call
set_queue_events(True). Updated on client.read() callback.
// Tuple item 3: Whether to queue all events or not. Default not. (0 for
false, non-zero for true)
- device->py_private = Py_BuildValue("({},{},[],i)",0); // tuple of a dict and
a list to store our keys and events in
+ device->py_private = (void*)Py_BuildValue("({},{},[],i)",0); // tuple of a
dict and a list to store our keys and events in
device->on_blackboard_event =
playerc_blackboard___python_on_blackboard_event__;
return device;
@@ -1000,7 +1110,7 @@
playerc_device_term(&device->info);
if (device->py_private != NULL)
{
- Py_DECREF((PyObject*)device->py_private);
+ Py_XDECREF((PyObject*)device->py_private);
}
free(device);
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit