[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [13606] branches/pynodes/source/blender/ python/api2_2x/Node.c: == Pynodes ==

Willian Padovani Germano wpgermano at gmail.com
Fri Feb 8 16:16:33 CET 2008


Revision: 13606
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13606
Author:   ianwill
Date:     2008-02-08 16:16:27 +0100 (Fri, 08 Feb 2008)

Log Message:
-----------
== Pynodes ==

Improvements to the API side: more robust checking and error handling when getting output socket data from the script (in the __call__ method). Fixes possible crashes.

Modified Paths:
--------------
    branches/pynodes/source/blender/python/api2_2x/Node.c

Modified: branches/pynodes/source/blender/python/api2_2x/Node.c
===================================================================
--- branches/pynodes/source/blender/python/api2_2x/Node.c	2008-02-08 05:31:12 UTC (rev 13605)
+++ branches/pynodes/source/blender/python/api2_2x/Node.c	2008-02-08 15:16:27 UTC (rev 13606)
@@ -527,53 +527,83 @@
 }
 
 static int sockoutmap_assign_subscript(BPy_SockMap *self, PyObject *idx, PyObject *value) {
-	int _idx;
+	int i, _idx, len, wanted_len, ret = -1;
+	PyObject *val;
+	PyObject **items;
 
 	if (!self->node) return -1;
 
-	if(PyInt_Check(idx)) {
+	if (PyInt_Check(idx)) {
 		_idx = (int)PyInt_AsLong(idx);
 	}
 	else if (PyString_Check(idx)) {
 		_idx = sockoutmap_has_key(self, idx);
 	}
 	else if (PySlice_Check(idx)) {
-		PyErr_SetString(PyExc_ValueError, "slices not implemented, yet");
-		return -1;
+		return EXPP_ReturnIntError(PyExc_ValueError, "slices not yet implemented");
 	} else {
-		PyErr_SetString(PyExc_IndexError, "Index must be int or string");
-		return -1;
+		return EXPP_ReturnIntError(PyExc_IndexError, "index must be a positive int or a string");
 	}
-	if(_idx > -1) {
-		switch(self->node->typeinfo->outputs[_idx].type) {
-			case SOCK_VALUE:
-				if(PyTuple_Size(value) == 1)
-					self->stack[_idx]->vec[0] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 0));
-				return 0;
-				break;
-			case SOCK_VECTOR:
-				if(PyTuple_Size(value) == 3) {
-					self->stack[_idx]->vec[0] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 0));
-					self->stack[_idx]->vec[1] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 1));
-					self->stack[_idx]->vec[2] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 2));
-				}
-				return 0;
-				break;
-			case SOCK_RGBA:
-				/* otherwise */
-				if(PyTuple_Size(value) == 4) {
-					self->stack[_idx]->vec[0] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 0));
-					self->stack[_idx]->vec[1] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 1));
-					self->stack[_idx]->vec[2] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 2));
-					self->stack[_idx]->vec[3] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 3));
-				}
-				return 0;
-				break;
-			default:
-				break;
-		}
+
+	if (idx < 0)
+		return EXPP_ReturnIntError(PyExc_IndexError, "index must be a positive int or a string");
+
+	val = PySequence_Fast(value, "expected a numeric tuple or list");
+	if (!val) return -1;
+
+	len = PySequence_Fast_GET_SIZE(val);
+
+	if (len == 0) {
+		Py_DECREF(val);
+		return EXPP_ReturnIntError(PyExc_AttributeError, "expected a non-empty numeric tuple or list");
 	}
-	return 0;
+
+	items = PySequence_Fast_ITEMS(val);
+
+	for (i = 0; i < len; i++) {
+		if (!PyNumber_Check(items[i]))
+			return EXPP_ReturnIntError(PyExc_AttributeError, "expected a *numeric* tuple or list");
+	}
+
+	switch(self->node->typeinfo->outputs[_idx].type) {
+		case SOCK_VALUE:
+			wanted_len = 1;
+			if (len == 1) {
+				self->stack[_idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
+				ret = 0;
+			}
+			break;
+		case SOCK_VECTOR:
+			wanted_len = 3;
+			if (len == 3) {
+				self->stack[_idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
+				self->stack[_idx]->vec[1] = (float)PyFloat_AsDouble(items[1]);
+				self->stack[_idx]->vec[2] = (float)PyFloat_AsDouble(items[2]);
+				ret = 0;
+			}
+			break;
+		case SOCK_RGBA:
+			wanted_len = 4;
+			if (len == 4) {
+				self->stack[_idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
+				self->stack[_idx]->vec[1] = (float)PyFloat_AsDouble(items[1]);
+				self->stack[_idx]->vec[2] = (float)PyFloat_AsDouble(items[2]);
+				self->stack[_idx]->vec[3] = (float)PyFloat_AsDouble(items[3]);
+				ret = 0;
+			}
+			break;
+		default:
+			break;
+	}
+
+	Py_DECREF(val);
+
+	if (ret == -1) {
+		PyErr_SetString(PyExc_AttributeError, "wrong number of items in list or tuple");
+		fprintf(stderr, "\nExpected %d numeric values, got %d.", wanted_len, len);
+	}
+
+	return ret;
 }
 
 /* write only */





More information about the Bf-blender-cvs mailing list