2.5: Python subclasses can now define RNA properties by making
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 22 Aug 2009 17:30:47 +0000 (17:30 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 22 Aug 2009 17:30:47 +0000 (17:30 +0000)
a __props__ list in the class, same as for operators.

source/blender/python/intern/bpy_rna.c

index 316480373461811de40ae10563e572339b740cfd..70ff8e48084f53197d14e42dd94ae5c9501c7c9b 100644 (file)
@@ -2940,12 +2940,12 @@ static StructRNA *pointer_type_from_py(PyObject *value)
 
        srna= srna_from_self(value);
        if(!srna) {
-               PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup (1)");
+               PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup");
                return NULL;
        }
 
        if(!RNA_struct_is_a(srna, &RNA_IDPropertyGroup)) {
-               PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup (3)");
+               PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup");
                return NULL;
        }
 
@@ -3022,6 +3022,52 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
        return NULL;
 }
 
+static int deferred_register_props(PyObject *py_class, StructRNA *srna)
+{
+       PyObject *props, *dummy_args, *item;
+       int i;
+
+       props= PyObject_GetAttrString(py_class, "__props__");
+       
+       if(!props) {
+               PyErr_Clear();
+               return 1;
+       }
+
+       dummy_args = PyTuple_New(0);
+
+       for(i=0; i<PyList_Size(props); i++) {
+               PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
+               item = PyList_GET_ITEM(props, i);
+               
+               if(PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
+                       PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
+                       pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
+                       py_srna_cobject = PyCObject_FromVoidPtr(srna, NULL);
+                       
+                       py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw);
+                       Py_DECREF(py_srna_cobject);
+
+                       if(py_ret) {
+                               Py_DECREF(py_ret);
+                       }
+                       else {
+                               Py_DECREF(dummy_args);
+                               return 0;
+                       }
+               }
+               else {
+                       PyErr_Clear();
+                       PyErr_SetString(PyExc_AttributeError, "expected list of dicts for __props__.");
+                       Py_DECREF(dummy_args);
+                       return 0;
+               }
+       }
+
+       Py_DECREF(dummy_args);
+       return 1;
+}
+
 /*-------------------- Type Registration ------------------------*/
 
 static int rna_function_arg_count(FunctionRNA *func)
@@ -3382,6 +3428,9 @@ PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class)
                // Py_DECREF(py_class); // shuld be able to do this XXX since the old rna adds a new ref.
        }
 
+       if(!deferred_register_props(py_class, srna_new))
+               return NULL;
+
        Py_RETURN_NONE;
 }
 
@@ -3405,7 +3454,6 @@ PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *py_class)
        
        /* get the context, so register callback can do necessary refreshes */
        C= BPy_GetContext();
-       
 
        /* call unregister */
        unreg(C, srna); /* calls bpy_class_free, this decref's py_class */