[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11258] trunk/blender/source/blender/ python/api2_2x/Draw.c: Revision: 11257 from 2.44 stable
Campbell Barton
cbarton at metavr.com
Thu Jul 12 22:49:36 CEST 2007
Revision: 11258
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11258
Author: campbellbarton
Date: 2007-07-12 22:49:36 +0200 (Thu, 12 Jul 2007)
Log Message:
-----------
Revision: 11257 from 2.44 stable
Modified Paths:
--------------
trunk/blender/source/blender/python/api2_2x/Draw.c
Modified: trunk/blender/source/blender/python/api2_2x/Draw.c
===================================================================
--- trunk/blender/source/blender/python/api2_2x/Draw.c 2007-07-12 20:14:16 UTC (rev 11257)
+++ trunk/blender/source/blender/python/api2_2x/Draw.c 2007-07-12 20:49:36 UTC (rev 11258)
@@ -103,10 +103,10 @@
static void spacescript_do_pywin_buttons( SpaceScript * sc,
unsigned short event );
-static PyObject *Method_Exit( PyObject * self, PyObject * args );
+static PyObject *Method_Exit( PyObject * self );
static PyObject *Method_Register( PyObject * self, PyObject * args );
static PyObject *Method_Redraw( PyObject * self, PyObject * args );
-static PyObject *Method_Draw( PyObject * self, PyObject * args );
+static PyObject *Method_Draw( PyObject * self );
static PyObject *Method_Create( PyObject * self, PyObject * args );
static PyObject *Method_UIBlock( PyObject * self, PyObject * args );
@@ -134,12 +134,19 @@
/* CLEVER NUMBUT */
static PyObject *Method_PupBlock( PyObject * self, PyObject * args );
+PyObject * pycallback_weakref_dealloc(PyObject *self, PyObject *weakref);
+/* python callable */
+PyObject * pycallback_weakref_dealloc__pyfunc;
+
static uiBlock *Get_uiBlock( void );
static void py_slider_update( void *butv, void *data2_unused );
/* hack to get 1 block for the UIBlock, only ever 1 at a time */
static uiBlock *uiblock=NULL;
+/* store weakref's to callbacks here */
+static PyObject *callback_list;
+
static char Draw_doc[] = "The Blender.Draw submodule";
static char Method_UIBlock_doc[] = "(drawfunc, x,y) - Popup dialog where buttons can be drawn (expemental)";
@@ -389,11 +396,11 @@
MethodDef( PupStrInput ),
MethodDef( PupBlock ),
MethodDef( Image ),
- MethodDef( Exit ),
+ {"Exit", (PyCFunction)Method_Exit, METH_NOARGS, Method_Exit_doc},
MethodDef( Redraw ),
- MethodDef( Draw ),
+ {"Draw", (PyCFunction)Method_Draw, METH_NOARGS, Method_Draw_doc},
MethodDef( Register ),
- {"PushButton", Method_Button, METH_VARARGS, Method_Button_doc},
+ {"PushButton", (PyCFunction)Method_Button, METH_VARARGS, Method_Button_doc},
MethodDef( BeginAlign ),
MethodDef( EndAlign),
{NULL, NULL, 0, NULL}
@@ -591,11 +598,7 @@
static Button *newbutton( void )
{
- Button *but = NULL;
-
- but = ( Button * ) PyObject_NEW( Button, &Button_Type );
-
- return but;
+ return ( Button * ) PyObject_NEW( Button, &Button_Type );
}
/* GUI interface routines */
@@ -710,7 +713,10 @@
if (event == UI_BUT_EVENT) {
/* check that event is in free range for script button events;
- * read the comment before check_button_event() below to understand */
+ * read the comment before check_button_event() below to understand
+ *
+ * This will never run from UIBlock so no need to check if uiblock==NULL
+ * And only sub EXPP_BUTTON_EVENTS_OFFSET in that case */
if (val >= EXPP_BUTTON_EVENTS_OFFSET && val < 0x4000)
spacescript_do_pywin_buttons(sc, val - EXPP_BUTTON_EVENTS_OFFSET);
return;
@@ -748,6 +754,14 @@
if (callback==NULL || callback == Py_None)
return;
+ if (callback) {
+ if (!PySequence_Contains(callback_list, callback)) {
+ printf("Error, the callback is out of scope.\n\tmake the callback global to resolve this.\n");
+ return;
+ }
+ callback = PyWeakref_GetObject(callback);
+ }
+
/* Button types support
case MENU:
case TEX:
@@ -814,13 +828,34 @@
Py_XDECREF( result );
}
+PyObject * pycallback_weakref_dealloc(PyObject *self, PyObject *weakref)
+{
+ int i = PySequence_Index(callback_list, weakref);
+ if (i==-1) {
+ printf("callback weakref internal error, weakref not in list\n\tthis should never happen.\n");
+ return NULL;
+ }
+ PySequence_DelItem(callback_list, i);
+ Py_RETURN_NONE;
+}
static void set_pycallback(uiBut *ubut, PyObject *callback)
{
+ PyObject *weakref;
if (!callback || !PyCallable_Check(callback)) return;
- uiButSetFunc(ubut, exec_but_callback, callback, ubut);
+
+ /* This works in most cases except where there are local functions
+ * that are deallocated so we must use weakrefs, will complain rather then crashing */
+ /*uiButSetFunc(ubut, exec_but_callback, callback, ubut);*/
+
+ weakref = PyWeakref_NewRef(callback, pycallback_weakref_dealloc__pyfunc);
+ PyList_Append(callback_list, weakref);
+ Py_DECREF(weakref);
+
+ /*printf("adding weakref, totlength %i\n", PyList_Size(callback_list));*/
+ uiButSetFunc(ubut, exec_but_callback, weakref, ubut);
}
-static PyObject *Method_Exit( PyObject * self, PyObject * args )
+static PyObject *Method_Exit( PyObject * self )
{
SpaceScript *sc;
Script *script;
@@ -832,10 +867,6 @@
else
Py_RETURN_NONE;
- if( PyTuple_Size(args) )
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected empty argument list" );
-
exit_pydraw( sc, 0 );
script = sc->script;
@@ -950,7 +981,7 @@
Py_RETURN_NONE;
}
-static PyObject *Method_Draw( PyObject * self, PyObject * args )
+static PyObject *Method_Draw( PyObject * self )
{
/*@ If forced drawing is disable queue a redraw event instead */
if( EXPP_disable_force_draw ) {
@@ -958,10 +989,6 @@
Py_RETURN_NONE;
}
- if( PyTuple_Size(args) )
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected empty argument list" );
-
scrarea_do_windraw( curarea );
screen_swapbuffers( );
@@ -1200,13 +1227,13 @@
disable_where_script( 1 );
spacescript_do_pywin_buttons( curarea->spacedata.first,
- (unsigned short)uiButGetRetVal( but ) );
+ (unsigned short)uiButGetRetVal( but ) - EXPP_BUTTON_EVENTS_OFFSET);
/* XXX useless right now, investigate better before a bcon 5 */
ret = M_Window_Redraw( 0, ref );
Py_DECREF(ref);
- if (ret) { Py_DECREF(ret); }
+ Py_XDECREF(ret);
disable_where_script( 0 );
@@ -1232,6 +1259,9 @@
UI_METHOD_ERRORCHECK;
+ if(realtime && uiblock)
+ realtime = 0; /* realtime dosnt work with UIBlock */
+
but = newbutton( );
if( PyFloat_Check( inio ) ) {
@@ -1966,17 +1996,26 @@
}
+static PyMethodDef bpycallback_weakref_dealloc[] = {
+ {"pycallback_weakref_dealloc", pycallback_weakref_dealloc, METH_O, ""}
+};
+
PyObject *Draw_Init( void )
{
PyObject *submodule, *dict;
-
+
+ /* Weakref management - used for callbacks so we can
+ * tell when a callback has been removed that a UI button referenced */
+ callback_list = PyList_New(0);
+ pycallback_weakref_dealloc__pyfunc = PyCFunction_New(bpycallback_weakref_dealloc, NULL);
+
if( PyType_Ready( &Button_Type) < 0)
Py_RETURN_NONE;
submodule = Py_InitModule3( "Blender.Draw", Draw_methods, Draw_doc );
dict = PyModule_GetDict( submodule );
-
+
#define EXPP_ADDCONST(x) \
EXPP_dict_set_item_str(dict, #x, PyInt_FromLong(x))
More information about the Bf-blender-cvs
mailing list