From 854cc87a80ef8526416b931ef735bc6bacb6ede5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Nov 2009 15:01:09 +0000 Subject: [PATCH] option to have scripts run on startup for per blendfile UI's --- release/scripts/ui/space_text.py | 7 +- source/blender/makesrna/intern/rna_text.c | 4 + source/blender/python/BPY_extern.h | 89 ++++++++++--------- .../python/generic/bpy_internal_import.c | 45 ++++++---- .../python/generic/bpy_internal_import.h | 5 +- source/blender/python/intern/bpy_interface.c | 22 +++++ .../blender/windowmanager/intern/wm_files.c | 7 +- source/creator/creator.c | 2 + source/gameengine/Ketsji/KX_PythonInit.cpp | 2 +- 9 files changed, 114 insertions(+), 69 deletions(-) diff --git a/release/scripts/ui/space_text.py b/release/scripts/ui/space_text.py index 0d33f181a06..32e23f1d09c 100644 --- a/release/scripts/ui/space_text.py +++ b/release/scripts/ui/space_text.py @@ -51,6 +51,10 @@ class TEXT_HT_header(bpy.types.Header): row.itemR(st, "word_wrap", text="") row.itemR(st, "syntax_highlight", text="") + row = layout.row() + row.itemO("text.run_script") + row.itemR(text, "use_module") + if text: row = layout.row() if text.filename != "": @@ -64,9 +68,6 @@ class TEXT_HT_header(bpy.types.Header): else: row.itemL(text="Text: Internal") - row = layout.row() - row.itemO("text.run_script") - class TEXT_PT_properties(bpy.types.Panel): bl_space_type = 'TEXT_EDITOR' diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c index 8c9b2b58887..bed686ed360 100644 --- a/source/blender/makesrna/intern/rna_text.c +++ b/source/blender/makesrna/intern/rna_text.c @@ -194,6 +194,10 @@ static void rna_def_text(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Memory", "Text file is in memory, without a corresponding file on disk."); + prop= RNA_def_property(srna, "use_module", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", TXT_ISSCRIPT); + RNA_def_property_ui_text(prop, "Register", "Register this text as a module on loading."); + prop= RNA_def_property(srna, "lines", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "TextLine"); RNA_def_property_ui_text(prop, "Lines", "Lines of text."); diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index 580d39b1e3f..a055060ed07 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -72,72 +72,73 @@ extern "C" { This is necassary to avoid blender buttons storing invalid pointers to freed python data.*/ - void BPy_Set_DrawButtonsList(void *list); - void BPy_Free_DrawButtonsList(void); - +// void BPy_Set_DrawButtonsList(void *list); +// void BPy_Free_DrawButtonsList(void); +// void BPY_pyconstraint_eval(struct bPythonConstraint *con, struct bConstraintOb *cob, struct ListBase *targets); - void BPY_pyconstraint_settings(void *arg1, void *arg2); +// void BPY_pyconstraint_settings(void *arg1, void *arg2); void BPY_pyconstraint_target(struct bPythonConstraint *con, struct bConstraintTarget *ct); void BPY_pyconstraint_update(struct Object *owner, struct bConstraint *con); int BPY_is_pyconstraint(struct Text *text); - void BPY_free_pyconstraint_links(struct Text *text); - +// void BPY_free_pyconstraint_links(struct Text *text); +// void BPY_start_python( int argc, char **argv ); void BPY_end_python( void ); - void init_syspath( int first_time ); - void syspath_append( char *dir ); - void BPY_rebuild_syspath( void ); - int BPY_path_update( void ); - - int BPY_Err_getLinenumber( void ); - const char *BPY_Err_getFilename( void ); - - int BPY_txt_do_python_Text( struct Text *text ); - int BPY_menu_do_python( short menutype, int event ); - int BPY_menu_do_shortcut( short menutype, unsigned short key, unsigned short modifiers ); - int BPY_menu_invoke( struct BPyMenu *pym, short menutype ); +// void init_syspath( int first_time ); +// void syspath_append( char *dir ); +// void BPY_rebuild_syspath( void ); +// int BPY_path_update( void ); +// +// int BPY_Err_getLinenumber( void ); +// const char *BPY_Err_getFilename( void ); +// +// int BPY_txt_do_python_Text( struct Text *text ); +// int BPY_menu_do_python( short menutype, int event ); +// int BPY_menu_do_shortcut( short menutype, unsigned short key, unsigned short modifiers ); +// int BPY_menu_invoke( struct BPyMenu *pym, short menutype ); /* 2.5 UI Scripts */ int BPY_run_python_script( struct bContext *C, const char *filename, struct Text *text, struct ReportList *reports ); // 2.5 working int BPY_run_script_space_draw(const struct bContext *C, struct SpaceScript * sc); // 2.5 working // int BPY_run_script_space_listener(struct bContext *C, struct SpaceScript * sc, struct ARegion *ar, struct wmNotifier *wmn); // 2.5 working void BPY_update_modules( void ); // XXX - annoying, need this for pointers that get out of date - +// int BPY_context_get(struct bContext *C, const char *member, struct bContextDataResult *result); - - int BPY_run_script(struct Script *script); +// +// int BPY_run_script(struct Script *script); void BPY_free_compiled_text( struct Text *text ); - - int BPY_has_onload_script( void ); - - int BPY_is_spacehandler(struct Text *text, char spacetype); - int BPY_del_spacehandler(struct Text *text, struct ScrArea *sa); - int BPY_add_spacehandler(struct Text *txt, struct ScrArea *sa,char spacetype); - int BPY_has_spacehandler(struct Text *text, struct ScrArea *sa); - void BPY_screen_free_spacehandlers(struct bScreen *sc); - int BPY_do_spacehandlers(struct ScrArea *sa, unsigned short event, - short eventValue, unsigned short space_event); - - void BPY_pydriver_update(void); +// +// int BPY_has_onload_script( void ); +// +// int BPY_is_spacehandler(struct Text *text, char spacetype); +// int BPY_del_spacehandler(struct Text *text, struct ScrArea *sa); +// int BPY_add_spacehandler(struct Text *txt, struct ScrArea *sa,char spacetype); +// int BPY_has_spacehandler(struct Text *text, struct ScrArea *sa); +// void BPY_screen_free_spacehandlers(struct bScreen *sc); +// int BPY_do_spacehandlers(struct ScrArea *sa, unsigned short event, +// short eventValue, unsigned short space_event); +// +// void BPY_pydriver_update(void); float BPY_pydriver_eval(struct ChannelDriver *driver); - +// int BPY_button_eval(struct bContext *C, char *expr, double *value); /* format importer hook */ int BPY_call_importloader( char *name ); - - void BPY_spacescript_do_pywin_draw( struct SpaceScript *sc ); - void BPY_spacescript_do_pywin_event( struct SpaceScript *sc, - unsigned short event, short val, char ascii ); - void BPY_clear_script( struct Script *script ); - void BPY_free_finished_script( struct Script *script ); - void BPY_scripts_clear_pyobjects( void ); - - void error_pyscript( void ); - void BPY_DECREF(void *pyob_ptr); /* Py_DECREF() */ +// +// void BPY_spacescript_do_pywin_draw( struct SpaceScript *sc ); +// void BPY_spacescript_do_pywin_event( struct SpaceScript *sc, +// unsigned short event, short val, char ascii ); +// void BPY_clear_script( struct Script *script ); +// void BPY_free_finished_script( struct Script *script ); +// void BPY_scripts_clear_pyobjects( void ); +// +// void error_pyscript( void ); +// void BPY_DECREF(void *pyob_ptr); /* Py_DECREF() */ void BPY_set_context(struct bContext *C); /* void BPY_Err_Handle(struct Text *text); */ /* int BPY_spacetext_is_pywin(struct SpaceText *st); */ + void BPY_load_user_modules(struct bContext *C); #ifdef __cplusplus } /* extern "C" */ diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c index 05c846b16f5..d3b8b19693f 100644 --- a/source/blender/python/generic/bpy_internal_import.c +++ b/source/blender/python/generic/bpy_internal_import.c @@ -54,12 +54,35 @@ void bpy_import_main_set(struct Main *maggie) bpy_import_main= maggie; } +PyObject *bpy_text_import( Text *text ) +{ + char *buf = NULL; + char modulename[24]; + int len; -PyObject *bpy_text_import( char *name, int *found ) + if( !text->compiled ) { + buf = txt_to_buf( text ); + text->compiled = Py_CompileString( buf, text->id.name+2, Py_file_input ); + MEM_freeN( buf ); + + if( PyErr_Occurred( ) ) { + PyErr_Print( ); + PyErr_Clear( ); + PySys_SetObject("last_traceback", NULL); + free_compiled_text( text ); + return NULL; + } + } + + len= strlen(text->id.name+2) - 3; + strncpy(modulename, text->id.name+2, len); + return PyImport_ExecCodeModule(modulename, text->compiled); +} + +PyObject *bpy_text_import_name( char *name, int *found ) { Text *text; char txtname[22]; /* 21+NULL */ - char *buf = NULL; int namelen = strlen( name ); //XXX Main *maggie= bpy_import_main ? bpy_import_main:G.main; Main *maggie= bpy_import_main; @@ -86,21 +109,7 @@ PyObject *bpy_text_import( char *name, int *found ) else *found = 1; - if( !text->compiled ) { - buf = txt_to_buf( text ); - text->compiled = Py_CompileString( buf, text->id.name+2, Py_file_input ); - MEM_freeN( buf ); - - if( PyErr_Occurred( ) ) { - PyErr_Print( ); - PyErr_Clear( ); - PySys_SetObject("last_traceback", NULL); - free_compiled_text( text ); - return NULL; - } - } - - return PyImport_ExecCodeModule( name, text->compiled ); + return bpy_text_import(text); } @@ -195,7 +204,7 @@ static PyObject *blender_import( PyObject * self, PyObject * args, PyObject * k PyErr_Fetch( &exception, &err, &tb ); /* get the python error incase we cant import as blender text either */ /* importing from existing modules failed, see if we have this module as blender text */ - newmodule = bpy_text_import( name, &found ); + newmodule = bpy_text_import_name( name, &found ); if( newmodule ) {/* found module as blender text, ignore above exception */ PyErr_Clear( ); diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h index 4e761fe8da0..0eee6361aab 100644 --- a/source/blender/python/generic/bpy_internal_import.h +++ b/source/blender/python/generic/bpy_internal_import.h @@ -44,7 +44,10 @@ #include "compile.h" /* for the PyCodeObject */ #include "eval.h" /* for PyEval_EvalCode */ -PyObject* bpy_text_import( char *name, int *found ); +struct Text; + +PyObject* bpy_text_import( struct Text *text ); +PyObject* bpy_text_import_name( char *name, int *found ); PyObject* bpy_text_reimport( PyObject *module, int *found ); /* void bpy_text_clear_modules( int clear_all );*/ /* Clear user modules */ extern PyMethodDef bpy_import_meth[]; diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 55dc133dfcb..4b8606a507f 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -65,6 +65,7 @@ #include "BKE_text.h" #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_main.h" #include "BPY_extern.h" @@ -864,7 +865,28 @@ int BPY_button_eval(bContext *C, char *expr, double *value) return error_ret; } +void BPY_load_user_modules(bContext *C) +{ + PyGILState_STATE gilstate; + Text *text; + bpy_context_set(C, &gilstate); + + for(text=CTX_data_main(C)->text.first; text; text= text->id.next) { + if(text->flags & TXT_ISSCRIPT && BLI_testextensie(text->id.name+2, ".py")) { + PyObject *module= bpy_text_import(text); + + if (module==NULL) { + PyErr_Print(); + PyErr_Clear(); + } + else { + Py_DECREF(module); + } + } + } + bpy_context_clear(C, &gilstate); +} int BPY_context_get(bContext *C, const char *member, bContextDataResult *result) { diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 6348e1a2717..a150ca1f8a0 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -89,7 +89,7 @@ #include "GPU_draw.h" -// XXX #include "BPY_extern.h" +#include "BPY_extern.h" #include "WM_api.h" #include "WM_types.h" @@ -274,8 +274,11 @@ void WM_read_file(bContext *C, char *name, ReportList *reports) WM_event_add_notifier(C, NC_WM|ND_FILEREAD, NULL); // refresh_interface_font(); - + CTX_wm_window_set(C, NULL); /* exits queues */ + + /* run any texts that were loaded in and flagged as modules */ + BPY_load_user_modules(C); } else if(retval==1) BKE_write_undo(C, "Import file"); diff --git a/source/creator/creator.c b/source/creator/creator.c index 6535f578cc1..10674d830ba 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -494,6 +494,7 @@ int main(int argc, char **argv) #ifndef DISABLE_PYTHON BPY_set_context(C); /* necessary evil */ BPY_start_python(argc, argv); + BPY_load_user_modules(C); #endif // XXX BRECHT SOLVE @@ -533,6 +534,7 @@ int main(int argc, char **argv) #ifndef DISABLE_PYTHON BPY_set_context(C); /* necessary evil */ BPY_start_python(argc, argv); + BPY_load_user_modules(C); #endif BLI_where_is_temp( btempdir, 0 ); /* call after loading the .B.blend so we can read U.tempdir */ } diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index ae4f3498471..ed422b81ec6 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -1608,7 +1608,7 @@ PyObject *KXpy_import(PyObject *self, PyObject *args) } /* Import blender texts as python modules */ - m= bpy_text_import(name, &found); + m= bpy_text_import_name(name, &found); if (m) return m;