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

Willian Padovani Germano wpgermano at gmail.com
Sun Feb 3 19:45:11 CET 2008


Revision: 13542
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13542
Author:   ianwill
Date:     2008-02-03 19:45:11 +0100 (Sun, 03 Feb 2008)

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

1) Trying to access pynode input/output data in the __init__ call would crash Blender because that function is only to define the sockets and the pynode is not ready yet (no link to Blender node). Added checks to prevent that. Ongoing work, there's more to do in the API side.

2) Another fix for a special case: let's see... take a working pynode, change (break) its script code, update the pynode to make it fail, then fix the script and reparse to make the pynode work again: all ok. But if there were multiple copies of this pynode double free errors would occur.

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-03 18:24:13 UTC (rev 13541)
+++ branches/pynodes/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c	2008-02-03 18:45:11 UTC (rev 13542)
@@ -180,8 +180,12 @@
  * the file is opened. */
 static void node_dynamic_reset(bNode *node, bNodeTree *ntree)
 {
-	bNodeType *tinfo = node->typeinfo;
+	bNodeType *tinfo, *tinfo_default;
+	Material *ma;
 
+	tinfo = node->typeinfo;
+	tinfo_default = node_dynamic_find_typeinfo(&node_all_shaders, NULL);
+
 	node_dynamic_free_typeinfo_sockets(tinfo);
 
 	if (!ntree) { node_dynamic_free_sockets(node); }
@@ -192,9 +196,23 @@
 	/* XXX hardcoded for shaders: */
 	if (node->typeinfo->id) { BLI_remlink(&node_all_shaders, tinfo); }
 
+	node->typeinfo = tinfo_default;
+
+	/* reset all other XXX shader nodes sharing this typeinfo */
+	for (ma= G.main->mat.first; ma; ma= ma->id.next) {
+		if (ma->nodetree) {
+			bNode *nd;
+			for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) {
+				if (nd->typeinfo == tinfo) {
+					node_dynamic_free_storage_cb(nd);
+					node_dynamic_free_sockets(nd);
+					nd->typeinfo = tinfo_default;
+				}
+			}
+		}
+	}
+
 	node_dynamic_free_typeinfo(tinfo);
-	node->typeinfo =
-			node_dynamic_find_typeinfo(&node_all_shaders, NULL);
 }
 
 static void node_dynamic_pyerror_print(bNode *node)
@@ -303,6 +321,7 @@
 {
 	NodeScriptDict *nsd = NULL;
 	bNodeTree *nodetree = NULL;
+	bNodeType *ntype = NULL;
 
 	/* Possible cases:
 	 * NEW
@@ -332,21 +351,36 @@
 
 	/* User asked to update this pynode, prepare it for reparsing */
 	if (BTST(node->custom1, NODE_DYNAMIC_REPARSE)) {
+		int needs_parsing = 1;
+
+		node->custom1 = BSET(node->custom1, NODE_DYNAMIC_NEW);
+
 		if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) {
-			nodeMakeDynamicType(node);
 			node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_REPARSE);
+			ntype = node_dynamic_find_typeinfo(&node_all_shaders, node->id);
+
+			if (ntype) {
+				node->typeinfo = ntype;
+				node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ADDEXIST);
+				node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_ERROR);
+				needs_parsing = 0;
+			}
+			else { nodeMakeDynamicType(node); }
+
 		} else {
 			node_dynamic_free_typeinfo_sockets(node->typeinfo);
 			node_dynamic_update_socket_links(node, NULL);
 			node_dynamic_free_storage_cb(node);
 		}
-		nsd = MEM_callocN(sizeof(NodeScriptDict), "node script dictionary");
-		nsd->dict = init_dynamicdict();
-		node->storage = nsd;
-		node->custom1 = BSET(node->custom1, NODE_DYNAMIC_NEW);
-		/* prepared, now reparse: */
-		node_dynamic_parse(node);
-		return;
+
+		if (needs_parsing) {
+			nsd = MEM_callocN(sizeof(NodeScriptDict), "node script dictionary");
+			nsd->dict = init_dynamicdict();
+			node->storage = nsd;
+			/* prepared, now reparse: */
+			node_dynamic_parse(node);
+			return;
+		}
 	}
 	else if (BTST(node->custom1, NODE_DYNAMIC_LOADED)) {
 		/* when loading from a .blend we don't have G.main yet, so we
@@ -367,13 +401,11 @@
 	if (BNTST(node->custom1, NODE_DYNAMIC_ADDEXIST)) {
 		/* check if there's already a bNodeType linked to this script */
 		/* (XXX hardcoded for shader nodes for now) */
-		bNodeType *ntype;
 		ntype = node_dynamic_find_typeinfo(&node_all_shaders, node->id);
 
 		if (ntype) { /* if so, reuse it */
 			node->typeinfo = ntype;
 			/* so this is actually an ADDEXIST type */
-			//wnode->custom1 = BCLR(node->custom1, NODE_DYNAMIC_NEW);
 			node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ADDEXIST);
 		}
 		else { /* create bNodeType for this pynode */

Modified: branches/pynodes/source/blender/python/api2_2x/Node.c
===================================================================
--- branches/pynodes/source/blender/python/api2_2x/Node.c	2008-02-03 18:24:13 UTC (rev 13541)
+++ branches/pynodes/source/blender/python/api2_2x/Node.c	2008-02-03 18:45:11 UTC (rev 13542)
@@ -337,9 +337,15 @@
 
 static int sockinmap_len ( BPy_SockMap * self) {
 	bNode *node = self->node;
-	bNodeType *tinfo = node->typeinfo;
+	bNodeType *tinfo;
 	int a = 0;
 
+	if (!node) return 0;
+
+	tinfo = node->typeinfo;
+
+	if (BNTST(node->custom1, NODE_DYNAMIC_READY)) return 0;
+
 	if (tinfo && tinfo->inputs) {
 		while(self->node->typeinfo->inputs[a].type!=-1)
 			a++;
@@ -349,10 +355,15 @@
 
 static int sockinmap_has_key( BPy_SockMap *self, PyObject *key) {
 	bNode *node = self->node;
-	bNodeType *tinfo = node->typeinfo;
+	bNodeType *tinfo;
+	char *strkey = NULL;
 	int a = 0;
-	char *strkey = PyString_AsString(key);
 
+	if (!node) return -1;
+
+	tinfo = node->typeinfo;
+	strkey = PyString_AsString(key);
+
 	if(tinfo && tinfo->inputs){
 		while(self->node->typeinfo->inputs[a].type!=-1) {
 			if(BLI_strcaseeq(self->node->typeinfo->inputs[a].name, strkey)) {
@@ -365,11 +376,12 @@
 }
 
 PyObject *sockinmap_subscript(BPy_SockMap *self, PyObject *idx) {
-	int a, _idx;
-	a = sockinmap_len(self);
+	int _idx;
 
+	if (!self->node) Py_RETURN_NONE;
+
 	if (PyString_Check(idx)) {
-		_idx = sockinmap_has_key( self, idx);
+		_idx = sockinmap_has_key(self, idx);
 	}
 	else if(PyInt_Check(idx)) {
 		PyErr_SetString(PyExc_ValueError, "int index not implemented");
@@ -379,7 +391,7 @@
 		PyErr_SetString(PyExc_ValueError, "slices not implemented");
 		Py_RETURN_NONE;
 	} else {
-		PyErr_SetString(PyExc_IndexError, "Index must be string");
+		PyErr_SetString(PyExc_IndexError, "index must be string");
 		Py_RETURN_NONE;
 	}
 
@@ -402,6 +414,7 @@
 		default:
 			break;
 	}
+
 	Py_RETURN_NONE;
 }
 
@@ -496,9 +509,13 @@
 
 static int sockoutmap_len ( BPy_SockMap * self) {
 	bNode *node = self->node;
-	bNodeType *tinfo = node->typeinfo;
+	bNodeType *tinfo;
 	int a = 0;
 
+	if (!node) return 0;
+
+	tinfo = node->typeinfo;
+
 	if (tinfo && tinfo->outputs) {
 		while(self->node->typeinfo->outputs[a].type!=-1)
 			a++;
@@ -508,10 +525,15 @@
 
 static int sockoutmap_has_key( BPy_SockMap *self, PyObject *key) {
 	bNode *node = self->node;
-	bNodeType *tinfo = node->typeinfo;
+	bNodeType *tinfo;
 	int a = 0;
-	char *strkey = PyString_AsString(key);
+	char *strkey = NULL;
 
+	if (!node) return -1;
+
+	tinfo = node->typeinfo;
+	strkey = PyString_AsString(key);
+
 	if(tinfo && tinfo->outputs){
 		while(self->node->typeinfo->outputs[a].type!=-1) {
 			if(BLI_strcaseeq(self->node->typeinfo->outputs[a].name, strkey)) {
@@ -524,13 +546,15 @@
 }
 
 static int sockoutmap_assign_subscript(BPy_SockMap *self, PyObject *idx, PyObject *value) {
-	int a, _idx;
-	a = sockoutmap_len(self);
+	int _idx;
+
+	if (!self->node) return -1;
+
 	if(PyInt_Check(idx)) {
 		_idx = (int)PyInt_AsLong(idx);
 	}
 	else if (PyString_Check(idx)) {
-		_idx = sockoutmap_has_key( self, idx);
+		_idx = sockoutmap_has_key(self, idx);
 	}
 	else if (PySlice_Check(idx)) {
 		PyErr_SetString(PyExc_ValueError, "slices not implemented, yet");





More information about the Bf-blender-cvs mailing list