From 34e7eb16769c31ba99fe5b74f06fd5c219b1133b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Nov 2009 20:58:46 +0000 Subject: [PATCH] use a metaclass to have operator attributes register and display in the order defined. --- release/scripts/modules/bpy_types.py | 15 +++ release/scripts/modules/rna_prop_ui.py | 9 +- .../blender/python/intern/bpy_operator_wrap.c | 1 - source/blender/python/intern/bpy_rna.c | 95 ++++++++++++------- 4 files changed, 82 insertions(+), 38 deletions(-) diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index 206dbacb3ba..6a65cb7ae71 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -92,3 +92,18 @@ class MeshFace(StructRNA): return ord_ind(verts[0], verts[1]), ord_ind(verts[1], verts[2]), ord_ind(verts[2], verts[3]), ord_ind(verts[3], verts[0]) edge_keys = property(_get_edge_keys) + + +import collections +class OrderedMeta(type): + def __init__(cls, name, bases, attributes): + super(OrderedMeta, cls).__init__(name, bases, attributes) + cls.order = list(attributes.keys()) + def __prepare__(name, bases, **kwargs): + return collections.OrderedDict() + +class Operator(StructRNA, metaclass=OrderedMeta): + ''' + Only defined so operators members can be used by accessing self.order + ''' + pass diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py index ec0a47981d3..24359aca64c 100644 --- a/release/scripts/modules/rna_prop_ui.py +++ b/release/scripts/modules/rna_prop_ui.py @@ -138,14 +138,13 @@ class WM_OT_properties_edit(bpy.types.Operator): '''Internal use (edit a property path)''' bl_idname = "wm.properties_edit" bl_label = "Edit Property!" - - description = StringProperty(name="Tip", default="") - path = rna_path - value = rna_value - property = rna_property + path = rna_path + property = rna_property + value = rna_value min = rna_min max = rna_max + description = StringProperty(name="Tip", default="") # the class instance is not persistant, need to store in the class # not ideal but changes as the op runs. diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 1aa56befe0e..3789c5b1258 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -294,7 +294,6 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata) * later */ RNA_def_struct_identifier(ot->srna, ot->idname); - if(pyrna_deferred_register_props(ot->srna, item)!=0) { /* failed to register operator props */ PyErr_Print(); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index aca07e2916c..205dbb2970f 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -3550,55 +3550,86 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; } -int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict) + +static int deferred_register_prop(StructRNA *srna, PyObject *item, PyObject *key, PyObject *dummy_args) { - PyObject *dummy_args, *item, *key; - Py_ssize_t pos = 0; + /* We only care about results from C which + * are for sure types, save some time with error */ + if(PyTuple_CheckExact(item) && PyTuple_GET_SIZE(item)==2) { - dummy_args = PyTuple_New(0); - - while (PyDict_Next(class_dict, &pos, &key, &item)) { PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret; - /* We only care about results from C which - * are for sure types, save some time with error */ - if(PyTuple_CheckExact(item)) { - 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); + if(PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) { - /* not 100% nice :/, modifies the dict passed, should be ok */ - PyDict_SetItemString(py_kw, "attr", key); + PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *); - py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw); - Py_DECREF(py_srna_cobject); + pyfunc = PyCObject_AsVoidPtr(py_func_ptr); + py_srna_cobject = PyCObject_FromVoidPtr(srna, NULL); - if(py_ret) { - Py_DECREF(py_ret); - } - else { - PyErr_Print(); - PyErr_Clear(); + /* not 100% nice :/, modifies the dict passed, should be ok */ + PyDict_SetItemString(py_kw, "attr", key); - PyErr_Format(PyExc_ValueError, "StructRNA \"%.200s\" registration error: %.200s could not register\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key)); - Py_DECREF(dummy_args); - return -1; - } + py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw); + Py_DECREF(py_srna_cobject); + + if(py_ret) { + Py_DECREF(py_ret); } else { - /* Since this is a class dict, ignore args that can't be passed */ - - /* for testing only */ - /* PyObSpit("Why doesn't this work??", item); - PyErr_Print(); */ + PyErr_Print(); PyErr_Clear(); + PyErr_Format(PyExc_ValueError, "StructRNA \"%.200s\" registration error: %.200s could not register\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key)); + Py_DECREF(dummy_args); + return -1; } } + else { + /* Since this is a class dict, ignore args that can't be passed */ + + /* for testing only */ + /* PyObSpit("Why doesn't this work??", item); + PyErr_Print(); */ + PyErr_Clear(); + } + } + + return 0; +} + +int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict) +{ + PyObject *item, *key; + PyObject *order; + PyObject *dummy_args; + Py_ssize_t pos = 0; + int ret; + + dummy_args = PyTuple_New(0); + + order= PyDict_GetItemString(class_dict, "order"); + + if(order && PyList_Check(order)) { + printf("using order\n"); + for(pos= 0; pos