awesome!<div><br><br><div class="gmail_quote">On Sat, Dec 27, 2008 at 7:52 AM, Campbell Barton <span dir="ltr">&lt;<a href="mailto:ideasman42@gmail.com">ideasman42@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Revision: 18097<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&amp;root=bf-blender&amp;revision=18097" target="_blank">http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&amp;root=bf-blender&amp;revision=18097</a><br>

Author: &nbsp; campbellbarton<br>
Date: &nbsp; &nbsp; 2008-12-27 15:52:49 +0100 (Sat, 27 Dec 2008)<br>
<br>
Log Message:<br>
-----------<br>
python operators (in bpy_opwrapper.*)<br>
This means you can define an operator in python that is called from C or Python - like any other operator.<br>
<br>
Python functions for invoke and exec can be registered with an operator name.<br>
<br>
keywords are read from the python exec() function, then used to create operator properties. The default python values are used to set the property type and defaults.<br>
<br>
def exec(size=2.0, text=&quot;blah&quot;): ...<br>
<br>
is equivalent to...<br>
prop = RNA_def_property(ot-&gt;srna, &quot;size&quot;, PROP_FLOAT, PROP_NONE);<br>
RNA_def_property_float_default(prop, 2.0f);<br>
<br>
prop = RNA_def_property(ot-&gt;srna, &quot;size&quot;, PROP_STRING, PROP_NONE);<br>
RNA_def_property_string_default(prop, &quot;blah&quot;);<br>
<br>
<br>
TODO -<br>
* make use of events<br>
* return OPERATOR_CANCELLED/OPERATOR_FINISHED.. etc<br>
* add support for array args<br>
* more testing<br>
<br>
Modified Paths:<br>
--------------<br>
 &nbsp; &nbsp;branches/blender2.5/blender/source/blender/makesdna/DNA_windowmanager_types.h<br>
 &nbsp; &nbsp;branches/blender2.5/blender/source/blender/makesrna/RNA_define.h<br>
 &nbsp; &nbsp;branches/blender2.5/blender/source/blender/makesrna/intern/rna_define.c<br>
 &nbsp; &nbsp;branches/blender2.5/blender/source/blender/python/intern/bpy_operator.c<br>
 &nbsp; &nbsp;branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c<br>
 &nbsp; &nbsp;branches/blender2.5/blender/source/blender/python/intern/bpy_rna.h<br>
 &nbsp; &nbsp;branches/blender2.5/blender/source/blender/windowmanager/WM_api.h<br>
 &nbsp; &nbsp;branches/blender2.5/blender/source/blender/windowmanager/intern/wm_operators.c<br>
<br>
Added Paths:<br>
-----------<br>
 &nbsp; &nbsp;branches/blender2.5/blender/source/blender/python/intern/bpy_opwrapper.c<br>
 &nbsp; &nbsp;branches/blender2.5/blender/source/blender/python/intern/bpy_opwrapper.h<br>
<br>
Modified: branches/blender2.5/blender/source/blender/makesdna/DNA_windowmanager_types.h<br>
===================================================================<br>
--- branches/blender2.5/blender/source/blender/makesdna/DNA_windowmanager_types.h &nbsp; &nbsp; &nbsp; 2008-12-27 11:44:00 UTC (rev 18096)<br>
+++ branches/blender2.5/blender/source/blender/makesdna/DNA_windowmanager_types.h &nbsp; &nbsp; &nbsp; 2008-12-27 14:52:49 UTC (rev 18097)<br>
@@ -137,6 +137,10 @@<br>
<br>
 &nbsp; &nbsp; &nbsp; &nbsp;short flag;<br>
<br>
+ &nbsp; &nbsp; &nbsp; /* only used for operators defined with python<br>
+ &nbsp; &nbsp; &nbsp; &nbsp;* use to store pointers to python functions */<br>
+ &nbsp; &nbsp; &nbsp; void *pyop_data;<br>
+<br>
&nbsp;} wmOperatorType;<br>
<br>
&nbsp;#define OP_MAX_TYPENAME &nbsp; &nbsp; &nbsp; &nbsp;64<br>
<br>
Modified: branches/blender2.5/blender/source/blender/makesrna/RNA_define.h<br>
===================================================================<br>
--- branches/blender2.5/blender/source/blender/makesrna/RNA_define.h &nbsp; &nbsp;2008-12-27 11:44:00 UTC (rev 18096)<br>
+++ branches/blender2.5/blender/source/blender/makesrna/RNA_define.h &nbsp; &nbsp;2008-12-27 14:52:49 UTC (rev 18097)<br>
@@ -47,7 +47,7 @@<br>
&nbsp;void RNA_def_struct_funcs(StructRNA *srna, const char *notify, const char *refine);<br>
&nbsp;void RNA_def_struct_identifier(StructRNA *srna, const char *identifier);<br>
&nbsp;void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description);<br>
-<br>
+void RNA_struct_free(BlenderRNA *brna, StructRNA *srna);<br>
&nbsp;/* Property */<br>
<br>
&nbsp;PropertyRNA *RNA_def_property(StructRNA *srna, const char *identifier, int type, int subtype);<br>
<br>
Modified: branches/blender2.5/blender/source/blender/makesrna/intern/rna_define.c<br>
===================================================================<br>
--- branches/blender2.5/blender/source/blender/makesrna/intern/rna_define.c &nbsp; &nbsp; 2008-12-27 11:44:00 UTC (rev 18096)<br>
+++ branches/blender2.5/blender/source/blender/makesrna/intern/rna_define.c &nbsp; &nbsp; 2008-12-27 14:52:49 UTC (rev 18097)<br>
@@ -549,6 +549,12 @@<br>
 &nbsp; &nbsp; &nbsp; &nbsp;srna-&gt;description= description;<br>
&nbsp;}<br>
<br>
+void RNA_struct_free(BlenderRNA *brna, StructRNA *srna)<br>
+{<br>
+ &nbsp; &nbsp; &nbsp; rna_freelistN(&amp;srna-&gt;properties);<br>
+ &nbsp; &nbsp; &nbsp; rna_freelinkN(&amp;brna-&gt;structs, srna);<br>
+}<br>
+<br>
&nbsp;/* Property Definition */<br>
<br>
&nbsp;PropertyRNA *RNA_def_property(StructRNA *srna, const char *identifier, int type, int subtype)<br>
<br>
Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_operator.c<br>
===================================================================<br>
--- branches/blender2.5/blender/source/blender/python/intern/bpy_operator.c &nbsp; &nbsp; 2008-12-27 11:44:00 UTC (rev 18096)<br>
+++ branches/blender2.5/blender/source/blender/python/intern/bpy_operator.c &nbsp; &nbsp; 2008-12-27 14:52:49 UTC (rev 18097)<br>
@@ -24,11 +24,13 @@<br>
 &nbsp;*/<br>
<br>
&nbsp;#include &quot;bpy_operator.h&quot;<br>
+#include &quot;bpy_opwrapper.h&quot;<br>
&nbsp;#include &quot;bpy_rna.h&quot; /* for setting arg props only - pyrna_py_to_prop() */<br>
&nbsp;#include &quot;bpy_compat.h&quot;<br>
<br>
&nbsp;//#include &quot;blendef.h&quot;<br>
&nbsp;#include &quot;BLI_dynstr.h&quot;<br>
+<br>
&nbsp;#include &quot;WM_api.h&quot;<br>
&nbsp;#include &quot;WM_types.h&quot;<br>
<br>
@@ -40,6 +42,20 @@<br>
&nbsp;/* floats bigger then this are displayed as inf in the docstrings */<br>
&nbsp;#define MAXFLOAT_DOC 10000000<br>
<br>
+#if 0<br>
+void PyObSpit(char *name, PyObject *var) {<br>
+ &nbsp; &nbsp; &nbsp; fprintf(stderr, &quot;&lt;%s&gt; : &quot;, name);<br>
+ &nbsp; &nbsp; &nbsp; if (var==NULL) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fprintf(stderr, &quot;&lt;NIL&gt;&quot;);<br>
+ &nbsp; &nbsp; &nbsp; }<br>
+ &nbsp; &nbsp; &nbsp; else {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PyObject_Print(var, stderr, 0);<br>
+ &nbsp; &nbsp; &nbsp; }<br>
+ &nbsp; &nbsp; &nbsp; fprintf(stderr, &quot;\n&quot;);<br>
+}<br>
+#endif<br>
+<br>
+<br>
&nbsp;static int pyop_func_compare( BPy_OperatorFunc * a, BPy_OperatorFunc * b )<br>
&nbsp;{<br>
 &nbsp; &nbsp; &nbsp; &nbsp;return (strcmp(a-&gt;name, b-&gt;name)==0) ? 0 : -1;<br>
@@ -56,6 +72,7 @@<br>
 &nbsp; &nbsp; &nbsp; &nbsp;return PyUnicode_FromFormat( &quot;[BPy_OperatorFunc \&quot;%s\&quot;]&quot;, self-&gt;name);<br>
&nbsp;}<br>
<br>
+<br>
&nbsp;//---------------getattr--------------------------------------------<br>
&nbsp;static PyObject *pyop_base_getattro( BPy_OperatorBase * self, PyObject *pyname )<br>
&nbsp;{<br>
@@ -73,7 +90,17 @@<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PyList_Append(ret, item);<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Py_DECREF(item);<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>
- &nbsp; &nbsp; &nbsp; } else {<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item = PyUnicode_FromString(&quot;add&quot;); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PyList_Append(ret, item); Py_DECREF(item);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item = PyUnicode_FromString(&quot;remove&quot;); &nbsp;PyList_Append(ret, item); Py_DECREF(item);<br>
+ &nbsp; &nbsp; &nbsp; }<br>
+ &nbsp; &nbsp; &nbsp; else if ( strcmp( name, &quot;add&quot; ) == 0 ) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ret= PYOP_wrap_add_func();<br>
+ &nbsp; &nbsp; &nbsp; }<br>
+ &nbsp; &nbsp; &nbsp; else if ( strcmp( name, &quot;remove&quot; ) == 0 ) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ret= PYOP_wrap_remove_func();<br>
+ &nbsp; &nbsp; &nbsp; }<br>
+ &nbsp; &nbsp; &nbsp; else {<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ot = WM_operatortype_find(name);<br>
<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (ot) {<br>
<br>
Added: branches/blender2.5/blender/source/blender/python/intern/bpy_opwrapper.c<br>
===================================================================<br>
--- branches/blender2.5/blender/source/blender/python/intern/bpy_opwrapper.c &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(rev 0)<br>
+++ branches/blender2.5/blender/source/blender/python/intern/bpy_opwrapper.c &nbsp; &nbsp;2008-12-27 14:52:49 UTC (rev 18097)<br>
@@ -0,0 +1,252 @@<br>
+<br>
+/**<br>
+ * $Id$<br>
+ *<br>
+ * ***** BEGIN GPL LICENSE BLOCK *****<br>
+ *<br>
+ * This program is free software; you can redistribute it and/or<br>
+ * modify it under the terms of the GNU General Public License<br>
+ * as published by the Free Software Foundation; either version 2<br>
+ * of the License, or (at your option) any later version.<br>
+ *<br>
+ * This program is distributed in the hope that it will be useful,<br>
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. &nbsp;See the<br>
+ * GNU General Public License for more details.<br>
+ *<br>
+ * You should have received a copy of the GNU General Public License<br>
+ * along with this program; if not, write to the Free Software Foundation,<br>
+ * Inc., 59 Temple Place - Suite 330, Boston, MA &nbsp;02111-1307, USA.<br>
+ *<br>
+ * Contributor(s): Campbell Barton<br>
+ *<br>
+ * ***** END GPL LICENSE BLOCK *****<br>
+ */<br>
+<br>
+<br>
+#include &quot;bpy_opwrapper.h&quot;<br>
+#include &quot;BLI_listbase.h&quot;<br>
+#include &quot;BKE_context.h&quot;<br>
+#include &quot;DNA_windowmanager_types.h&quot;<br>
+#include &quot;MEM_guardedalloc.h&quot;<br>
+#include &quot;WM_api.h&quot;<br>
+#include &quot;WM_types.h&quot;<br>
+#include &quot;ED_screen.h&quot;<br>
+<br>
+#include &quot;RNA_define.h&quot;<br>
+<br>
+#include &quot;bpy_rna.h&quot;<br>
+#include &quot;bpy_compat.h&quot;<br>
+<br>
+typedef struct PyOperatorType {<br>
+ &nbsp; &nbsp; &nbsp; void *next, *prev;<br>
+ &nbsp; &nbsp; &nbsp; char idname[OP_MAX_TYPENAME];<br>
+ &nbsp; &nbsp; &nbsp; char name[OP_MAX_TYPENAME];<br>
+ &nbsp; &nbsp; &nbsp; PyObject *py_invoke;<br>
+ &nbsp; &nbsp; &nbsp; PyObject *py_exec;<br>
+} PyOperatorType;<br>
+<br>
+static void pyop_kwargs_from_operator(PyObject *dict, wmOperator *op)<br>
+{<br>
+ &nbsp; &nbsp; &nbsp; PyObject *item;<br>
+ &nbsp; &nbsp; &nbsp; PropertyRNA *prop, *iterprop;<br>
+ &nbsp; &nbsp; &nbsp; CollectionPropertyIterator iter;<br>
+ &nbsp; &nbsp; &nbsp; const char *arg_name;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; iterprop= RNA_struct_iterator_property(op-&gt;ptr);<br>
+ &nbsp; &nbsp; &nbsp; RNA_property_collection_begin(op-&gt;ptr, iterprop, &amp;iter);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; for(; iter.valid; RNA_property_collection_next(&amp;iter)) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prop= iter.ptr.data;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; arg_name= RNA_property_identifier(&amp;iter.ptr, prop);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (strcmp(arg_name, &quot;rna_type&quot;)==0) continue;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item = pyrna_prop_to_py(&amp;iter.ptr, prop);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PyDict_SetItemString(dict, arg_name, item);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Py_DECREF(item);<br>
+ &nbsp; &nbsp; &nbsp; }<br>
+<br>
+ &nbsp; &nbsp; &nbsp; RNA_property_collection_end(&amp;iter);<br>
+<br>
+}<br>
+<br>
+static int PYTHON_OT_exec(bContext *C, wmOperator *op)<br>
+{<br>
+ &nbsp; &nbsp; &nbsp; PyOperatorType *pyot = op-&gt;type-&gt;pyop_data;<br>
+ &nbsp; &nbsp; &nbsp; PyObject *ret, *args= PyTuple_New(0), *kw= PyDict_New();<br>
+<br>
+ &nbsp; &nbsp; &nbsp; pyop_kwargs_from_operator(kw, op);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; ret = PyObject_Call(pyot-&gt;py_exec, args, kw);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; Py_DECREF(args);<br>
+ &nbsp; &nbsp; &nbsp; Py_DECREF(kw);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; return OPERATOR_FINISHED;<br>
+}<br>
+<br>
+static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)<br>
+{<br>
+ &nbsp; &nbsp; &nbsp; PyOperatorType *pyot = op-&gt;type-&gt;pyop_data;<br>
+ &nbsp; &nbsp; &nbsp; PyObject *ret, *args= PyTuple_New(0), *kw= PyDict_New();<br>
+<br>
+ &nbsp; &nbsp; &nbsp; pyop_kwargs_from_operator(kw, op);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; ret = PyObject_Call(pyot-&gt;py_invoke, args, kw);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; Py_DECREF(args);<br>
+ &nbsp; &nbsp; &nbsp; Py_DECREF(kw);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; return OPERATOR_FINISHED;<br>
+}<br>
+<br>
+void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)<br>
+{<br>
+ &nbsp; &nbsp; &nbsp; PyOperatorType *pyot = (PyOperatorType *)userdata;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; /* identifiers */<br>
+ &nbsp; &nbsp; &nbsp; ot-&gt;name= pyot-&gt;name;<br>
+ &nbsp; &nbsp; &nbsp; ot-&gt;idname= pyot-&gt;idname;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; /* api callbacks */<br>
+ &nbsp; &nbsp; &nbsp; if (pyot-&gt;py_invoke != Py_None)<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ot-&gt;invoke= PYTHON_OT_invoke;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; ot-&gt;exec= PYTHON_OT_exec;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; ot-&gt;poll= ED_operator_screenactive; /* how should this work?? */<br>
+<br>
+ &nbsp; &nbsp; &nbsp; ot-&gt;pyop_data= userdata;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; /* inspect function keyword args to get properties */<br>
+ &nbsp; &nbsp; &nbsp; {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PropertyRNA *prop;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PyObject *var_names= PyObject_GetAttrString(PyFunction_GET_CODE(pyot-&gt;py_exec), &quot;co_varnames&quot;);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PyObject *var_vals = PyFunction_GET_DEFAULTS(pyot-&gt;py_exec);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PyObject *py_val, *py_name;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int i;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char *name;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (PyTuple_Size(var_names) != PyTuple_Size(var_vals)) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(&quot;All args must be keywords&quot;);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for(i=0; i&lt;PyTuple_Size(var_names); i++) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; py_name = PyTuple_GetItem(var_names, i);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name = _PyUnicode_AsString(py_name);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; py_val = PyTuple_GetItem(var_vals, i);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (PyBool_Check(py_val)) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prop = RNA_def_property(ot-&gt;srna, name, PROP_BOOLEAN, PROP_NONE);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RNA_def_property_boolean_default(prop, PyObject_IsTrue(py_val));<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if (PyLong_Check(py_val)) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prop = RNA_def_property(ot-&gt;srna, name, PROP_INT, PROP_NONE);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RNA_def_property_int_default(prop, (int)PyLong_AsSsize_t(py_val));<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if (PyFloat_Check(py_val)) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prop = RNA_def_property(ot-&gt;srna, name, PROP_FLOAT, PROP_NONE);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RNA_def_property_float_default(prop, (float)PyFloat_AsDouble(py_val));<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if (PyUnicode_Check(py_val)) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* WARNING - holding a reference to the string from py_val is<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* not ideal since we rely on python keeping it,<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* however we&#39;re also keeping a reference to this function<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* so it should be OK!. just be careful with changes */<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prop = RNA_def_property(ot-&gt;srna, name, PROP_STRING, PROP_NONE);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RNA_def_property_string_default(prop, _PyUnicode_AsString(py_val));<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(&quot;error, python function arg \&quot;%s\&quot; was not a bool, int, float or string type\n&quot;, name);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>
+ &nbsp; &nbsp; &nbsp; }<br>
+<br>
+}<br>
+<br>
+/* pyOperators - Operators defined IN Python */<br>
+static PyObject *pyop_add(PyObject *self, PyObject *args)<br>
+{<br>
+ &nbsp; &nbsp; &nbsp; PyOperatorType *pyot;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; char *idname= NULL;<br>
+ &nbsp; &nbsp; &nbsp; char *name= NULL;<br>
+ &nbsp; &nbsp; &nbsp; PyObject *invoke= NULL;<br>
+ &nbsp; &nbsp; &nbsp; PyObject *exec= NULL;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; if (!PyArg_ParseTuple(args, &quot;ssOO&quot;, &amp;idname, &amp;name, &amp;invoke, &amp;exec))<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PyErr_SetString( PyExc_AttributeError, &quot;expected 2 strings and 2 function objects&quot;);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return NULL;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; if (WM_operatortype_find(idname)) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PyErr_Format( PyExc_AttributeError, &quot;First argument \&quot;%s\&quot; operator alredy exists with this name&quot;, idname);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return NULL;<br>
+ &nbsp; &nbsp; &nbsp; }<br>
+<br>
+ &nbsp; &nbsp; &nbsp; if (((PyFunction_Check(invoke) || invoke==Py_None) &amp;&amp; PyFunction_Check(exec)) == 0) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PyErr_SetString( PyExc_AttributeError, &quot;the 2nd arg must be a function or None, the secons must be a function&quot;);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return NULL;<br>
+ &nbsp; &nbsp; &nbsp; }<br>
+<br>
+ &nbsp; &nbsp; &nbsp; pyot= MEM_callocN(sizeof(PyOperatorType), &quot;PyOperatorType&quot;);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; strcpy(pyot-&gt;idname, idname);<br>
+ &nbsp; &nbsp; &nbsp; strcpy(pyot-&gt;name, name);<br>
+ &nbsp; &nbsp; &nbsp; pyot-&gt;py_invoke= invoke;<br>
+ &nbsp; &nbsp; &nbsp; pyot-&gt;py_exec= exec;<br>
+ &nbsp; &nbsp; &nbsp; Py_INCREF(invoke);<br>
+ &nbsp; &nbsp; &nbsp; Py_INCREF(exec);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; WM_operatortype_append_ptr(PYTHON_OT_wrapper, pyot);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; Py_RETURN_NONE;<br>
+}<br>
+<br>
+static PyObject *pyop_remove(PyObject *self, PyObject *args)<br>
+{<br>
+ &nbsp; &nbsp; &nbsp; char *idname= NULL;<br>
+ &nbsp; &nbsp; &nbsp; wmOperatorType *ot;<br>
+ &nbsp; &nbsp; &nbsp; PyOperatorType *pyot;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; if (!PyArg_ParseTuple(args, &quot;s&quot;, &amp;idname))<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return NULL;<br>
+<br>
+ &nbsp; &nbsp; &nbsp; if (!(ot= WM_operatortype_find(idname))) {<br>
<br>
@@ Diff output truncated at 10240 characters. @@<br>
<br>
_______________________________________________<br>
Bf-blender-cvs mailing list<br>
<a href="mailto:Bf-blender-cvs@blender.org">Bf-blender-cvs@blender.org</a><br>
<a href="http://lists.blender.org/mailman/listinfo/bf-blender-cvs" target="_blank">http://lists.blender.org/mailman/listinfo/bf-blender-cvs</a><br>
</blockquote></div><br></div>