[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [13600] branches/pynodes/source/blender: = = Pynodes ==

Willian Padovani Germano wpgermano at gmail.com
Thu Feb 7 04:31:46 CET 2008


Revision: 13600
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13600
Author:   ianwill
Date:     2008-02-07 04:31:45 +0100 (Thu, 07 Feb 2008)

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

Found and fixed a crash when multiple pynodes shared a script that failed in the __call__ method. Ongoing work: minor improvements in Node.c for the Python side, specially error reporting.

Modified Paths:
--------------
    branches/pynodes/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c
    branches/pynodes/source/blender/python/api2_2x/Node.c

Modified: branches/pynodes/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c
===================================================================
--- branches/pynodes/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c	2008-02-06 23:27:03 UTC (rev 13599)
+++ branches/pynodes/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c	2008-02-07 03:31:45 UTC (rev 13600)
@@ -167,6 +167,25 @@
 	node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ERROR);
 }
 
+/* Disable all pynodes using the given text (script) id */
+static void node_dynamic_disable_all_by_id(ID *id)
+{
+	Material *ma; /* XXX hardcoded for shaders */
+
+	for (ma= G.main->mat.first; ma; ma= ma->id.next) {
+		if (ma->nodetree) {
+			bNode *nd;
+			bNodeTree *ntree = ma->nodetree;
+			for (nd= ntree->nodes.first; nd; nd= nd->next) {
+				if (nd->id == id) {
+					nd->custom1 = 0;
+					nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_ERROR);
+				}
+			}
+		}
+	}
+}
+
 static void node_rem_socklist_links(bNodeTree *ntree, ListBase *lb)
 {
 	bNodeLink *link, *next;
@@ -263,6 +282,8 @@
 			for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) {
 				if ((nd->type == NODE_DYNAMIC) && (nd->id == txtid)) {
 					nd->id = NULL;
+					nd->custom1 = 0;
+					nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_NEW);
 					BLI_strncpy(nd->name, "Dynamic", 8);
 					nd2 = nd; /* so we have a ptr to one of them */
 					unlinked++;
@@ -280,7 +301,8 @@
 static void node_dynamic_pyerror_print(bNode *node)
 {
 	fprintf(stderr, "\nError in dynamic node script \"%s\":\n", node->name);
-	if (PyErr_Occurred()) PyErr_Print();
+	if (PyErr_Occurred()) { PyErr_Print(); }
+	else { fprintf(stderr, "Not a valid dynamic node Python script.\n"); }
 }
 
 static int node_dynamic_parse(struct bNode *node)
@@ -288,7 +310,7 @@
 	PyObject *dict= NULL;
 	PyObject *key= NULL;
 	PyObject *value= NULL;
-	PyObject *testinst= NULL;
+	PyObject *pynode= NULL;
 	PyObject *args= NULL;
 	NodeScriptDict *nsd = NULL;
 	PyObject *pyresult = NULL;
@@ -325,23 +347,23 @@
 			BPy_NodeSockets *sockets = Node_CreateSockets(node);
 
 			args = Py_BuildValue("(O)", sockets);
+
 			/* init it to get the input and output sockets */
-			testinst = PyObject_Call(value, args, NULL);
+			pynode = PyObject_Call(value, args, NULL);
 
 			Py_DECREF(sockets);
 			Py_DECREF(args);
 
-			if (testinst && PyObject_TypeCheck(testinst, &Node_Type)==1) {
-				InitNode((BPy_Node *)(testinst), node);
-				//wPy_INCREF(testinst); /* XXX uneeded, right? */
-				nsd->node = testinst;
+			if (!PyErr_Occurred() && pynode && PyObject_TypeCheck(pynode, &Node_Type)==1) {
+				InitNode((BPy_Node *)(pynode), node);
+				nsd->node = pynode;
 				node->typeinfo->execfunc = node_dynamic_exec_cb;
 				is_valid_script = 1;
 
 				/* for NEW, LOADED, REPARSE */
 				if (BNTST(node->custom1, NODE_DYNAMIC_ADDEXIST)) {
 					node->typeinfo->pydict = dict;
-					node->typeinfo->pynode = testinst;
+					node->typeinfo->pynode = pynode;
 					node->typeinfo->id = node->id;
 					nodeAddSockets(node, node->typeinfo);
 					if (BNTST(node->custom1, NODE_DYNAMIC_REPARSE)) {
@@ -573,8 +595,9 @@
 			args=Py_BuildValue("()");
 			pyresult= PyObject_Call((PyObject *)mynode, args, NULL);
 			Py_DECREF(args);
+
 			if (!pyresult) {
-				node_dynamic_disable(node);
+				node_dynamic_disable_all_by_id(node->id);
 				node_dynamic_pyerror_print(node);
 				node_dynamic_setup(node);
 				return;

Modified: branches/pynodes/source/blender/python/api2_2x/Node.c
===================================================================
--- branches/pynodes/source/blender/python/api2_2x/Node.c	2008-02-06 23:27:03 UTC (rev 13599)
+++ branches/pynodes/source/blender/python/api2_2x/Node.c	2008-02-07 03:31:45 UTC (rev 13600)
@@ -56,7 +56,7 @@
  * socks is a socketstack from a bNodeTypeInfo
  */
 static int list_socks_to_typeinfo(PyObject *tuple, bNodeSocketType **socks, int stage, int limit) {
-	int len = 0, a = 0, pos = 0, failed = 0;
+	int len = 0, a = 0, pos = 0, retval = 0;
 	//wPyObject *key = NULL, *value = NULL;
 	PyObject *item, *arg;
 	bNodeSocketType *newsocks = NULL;
@@ -79,10 +79,10 @@
 		s_max = 0.0f;
 
 		item = PyTuple_GetItem(tuple, pos);
-		//wPy_INCREF(element);
 
 		if (!PySequence_Check(item)) {
-			failed = 1;
+			PyErr_SetString(PyExc_AttributeError, "a socket must be a List of Lists or Tuples");
+			retval = -1;
 			break;
 		}
 
@@ -91,13 +91,13 @@
 		if (!PyArg_ParseTuple(arg, "s|iffffff", &s_name, &s_type,
 					&s_val[0], &s_val[1], &s_val[2], &s_val[3],
 					&s_min, &s_max)) {
-			/* XXX print error msg */
-			failed = 1;
+			PyErr_SetString(PyExc_AttributeError, "socket definitions require a string and optionally an int and 6 floats");
+			retval = -1;
 			Py_DECREF(arg);
 			break;
 		}
 
-		newsocks[a].name = BLI_strdup(s_name); /* XXX better strncpy? */
+		newsocks[a].name = BLI_strdupn(s_name, NODE_MAXSTR);
 		newsocks[a].type = s_type;
 		newsocks[a].val1 = s_val[0];
 		newsocks[a].val2 = s_val[1];
@@ -111,18 +111,10 @@
 	}
 
 	newsocks[a].type = -1;
-	/*if(*socks) {
-		int b = 0;
-		while((*socks)[b].type!=-1) {
-			MEM_freeN((*socks)[b].name);
-			(*socks)[b].name = NULL;
-			b++;
-		}
-		MEM_freeN(*socks);
-	}*/
+
 	*socks = newsocks;
 
-	return 0;
+	return retval;
 }
 
 /* Get number of complying entries in a list.
@@ -179,12 +171,7 @@
 {
 	bNode *node = NULL;
 	PyObject *tuple = NULL;
-	//wBPy_NodeSockets *defs = NULL;
 
-	//wPy_INCREF(args);
-	//wPy_INCREF(self);
-
-	//wdefs = (BPy_NodeSockets *)self;
 	node = self->node;
 
 	if(!node) {
@@ -204,8 +191,6 @@
 					Py_DECREF(self->input);
 					self->input = tuple;
 				} else {
-					//wPy_DECREF(self);
-					//wPy_DECREF(args);
 					return(EXPP_ReturnIntError( PyExc_AttributeError, "INPUT must be a List of Lists or Tuples"));
 				}
 			}
@@ -218,18 +203,14 @@
 					Py_DECREF(self->output);
 					self->output = tuple;
 				} else {
-					//wPy_DECREF(self);
-					//wPy_DECREF(args);
 					return(EXPP_ReturnIntError( PyExc_AttributeError, "OUTPUT must be a List of Lists or Tuples"));
 				}
 			}
 			break;
 		default:
-			fprintf(stderr, "Hrm, why we got no list? Todo: figure out proper complaint to scripter\n");
+			fprintf(stderr,"DEBUG pynodes: got no list in Map_socketdef\n");
 			break;
 	}
-	//wPy_DECREF(self);
-	//wPy_DECREF(args);
 	return 0;
 }
 
@@ -303,7 +284,7 @@
   /*** Attribute descriptor and subclassing stuff ***/
 	0, //BPy_MVertSeq_methods,       /* struct PyMethodDef *tp_methods; */
 	NULL,                       /* struct PyMemberDef *tp_members; */
-	NodeSockets_getseters,                       /* struct PyGetSetDef *tp_getset; */
+	NodeSockets_getseters,      /* struct PyGetSetDef *tp_getset; */
 	NULL,                       /* struct _typeobject *tp_base; */
 	NULL,                       /* PyObject *tp_dict; */
 	NULL,                       /* descrgetfunc tp_descr_get; */





More information about the Bf-blender-cvs mailing list