[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19653] branches/blender2.5/blender: Changed the script UI registration to import rather then run each python script ,

Campbell Barton ideasman42 at gmail.com
Sat Apr 11 07:46:48 CEST 2009


Revision: 19653
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19653
Author:   campbellbarton
Date:     2009-04-11 07:46:40 +0200 (Sat, 11 Apr 2009)

Log Message:
-----------
Changed the script UI registration to import rather then run each python script,
this means it caches the compiled pyc files after importing fro the first time.

My times for importing 501 buttons_objects.py files were.
- running each as a script 1.9sec
- importing for the first time 1.8sec
- importing a second time (using pyc files) 0.57sec

Also added "bpy" to sys.modules so it can be imported.

Modified Paths:
--------------
    branches/blender2.5/blender/release/ui/buttons_objects.py
    branches/blender2.5/blender/source/blender/python/BPY_extern.h
    branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c
    branches/blender2.5/blender/source/blender/python/intern/bpy_operator.c
    branches/blender2.5/blender/source/blender/python/intern/bpy_operator.h
    branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c
    branches/blender2.5/blender/source/creator/creator.c
    branches/blender2.5/blender/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp

Modified: branches/blender2.5/blender/release/ui/buttons_objects.py
===================================================================
--- branches/blender2.5/blender/release/ui/buttons_objects.py	2009-04-11 02:18:24 UTC (rev 19652)
+++ branches/blender2.5/blender/release/ui/buttons_objects.py	2009-04-11 05:46:40 UTC (rev 19653)
@@ -1,3 +1,4 @@
+import bpy
 
 class OBJECT_PT_transform(bpy.types.Panel):
 	__label__ = "Transform"
@@ -121,4 +122,3 @@
 bpy.ui.addPanel(OBJECT_PT_display, "BUTTONS_WINDOW", "WINDOW")
 bpy.ui.addPanel(OBJECT_PT_duplication, "BUTTONS_WINDOW", "WINDOW")
 bpy.ui.addPanel(OBJECT_PT_animation, "BUTTONS_WINDOW", "WINDOW")
-

Modified: branches/blender2.5/blender/source/blender/python/BPY_extern.h
===================================================================
--- branches/blender2.5/blender/source/blender/python/BPY_extern.h	2009-04-11 02:18:24 UTC (rev 19652)
+++ branches/blender2.5/blender/source/blender/python/BPY_extern.h	2009-04-11 05:46:40 UTC (rev 19653)
@@ -99,7 +99,7 @@
 	/* 2.5 UI Scripts */
 	int BPY_run_python_script( struct bContext *C, const char *filename, struct Text *text ); // 2.5 working
 	int BPY_run_script_space_draw(struct bContext *C, struct SpaceScript * sc); // 2.5 working
-	void BPY_run_ui_scripts(struct bContext *C);
+	void BPY_run_ui_scripts(void);
 //	int BPY_run_script_space_listener(struct bContext *C, struct SpaceScript * sc, struct ARegion *ar, struct wmNotifier *wmn); // 2.5 working
 	
 	

Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c
===================================================================
--- branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c	2009-04-11 02:18:24 UTC (rev 19652)
+++ branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c	2009-04-11 05:46:40 UTC (rev 19653)
@@ -26,6 +26,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "BLI_util.h"
+#include "BLI_string.h"
 
 #include "BKE_context.h"
 #include "BKE_text.h"
@@ -39,9 +40,28 @@
 }
 
 /*****************************************************************************
+* Description: Creates the bpy module and adds it to sys.modules for importing
+*****************************************************************************/
+static void BPY_init_modules( void )
+{
+	PyObject *mod;
+	
+	mod = PyModule_New("bpy");
+	
+	PyModule_AddObject( mod, "data", BPY_rna_module() );
+	/* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
+	PyModule_AddObject( mod, "types", BPY_rna_types() );
+	PyModule_AddObject( mod, "ops", BPY_operator_module() );
+	PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experemental, consider this a test, especially PyCObject is not meant to be perminant
+	
+	/* add the module so we can import it */
+	PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod);
+	Py_DECREF(mod);
+}
+
+/*****************************************************************************
 * Description: This function creates a new Python dictionary object.
 *****************************************************************************/
-
 static PyObject *CreateGlobalDictionary( bContext *C )
 {
 	PyObject *mod;
@@ -51,23 +71,11 @@
 	PyDict_SetItemString( dict, "__name__", item );
 	Py_DECREF(item);
 	
-	/* add bpy to global namespace */
-	mod = PyModule_New("bpy");
-	PyDict_SetItemString( dict, "bpy", mod );
-	Py_DECREF(mod);
-	
-	PyModule_AddObject( mod, "data", BPY_rna_module() );
-	/* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
-	PyModule_AddObject( mod, "types", BPY_rna_types() );
-	PyModule_AddObject( mod, "ops", BPY_operator_module(C) );
-	PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experemental, consider this a test, especially PyCObject is not meant to be perminant
-	
 	// XXX - evil, need to access context
 	item = PyCObject_FromVoidPtr( C, NULL );
 	PyDict_SetItemString( dict, "__bpy_context__", item );
 	Py_DECREF(item);
 	
-	
 	// XXX - put somewhere more logical
 	{
 		PyMethodDef *ml;
@@ -83,13 +91,18 @@
 		}
 	}
 	
+	/* add bpy to global namespace */
+	mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
+	PyDict_SetItemString( dict, "bpy", mod );
+	Py_DECREF(mod);
+	
 	return dict;
 }
 
 void BPY_start_python( void )
 {
 	PyThreadState *py_tstate = NULL;
-
+	
 	Py_Initialize(  );
 	
 	//PySys_SetArgv( argc_copy, argv_copy );
@@ -97,8 +110,11 @@
 	/* Initialize thread support (also acquires lock) */
 	PyEval_InitThreads();
 	
-	// todo - sys paths - our own imports
 	
+	/* bpy.* and lets us import it */
+	BPY_init_modules(); 
+
+	
 	py_tstate = PyGILState_GetThisThreadState();
 	PyEval_ReleaseThread(py_tstate);
 	
@@ -304,16 +320,30 @@
 }
 #endif
 
+// #define TIME_REGISTRATION
+
+#ifdef TIME_REGISTRATION
+#include "PIL_time.h"
+#endif
+
 /* XXX this is temporary, need a proper script registration system for 2.5 */
-void BPY_run_ui_scripts(bContext *C)
+void BPY_run_ui_scripts(void)
 {
+#ifdef TIME_REGISTRATION
+	double time = PIL_check_seconds_timer();
+#endif
 	DIR *dir; 
 	struct dirent *de;
-	struct stat status;
 	char *file_extension;
 	char path[FILE_MAX];
 	char *dirname= BLI_gethome_folder("ui");
-
+	int filelen; /* filename length */
+	
+	PyGILState_STATE gilstate;
+	PyObject *mod;
+	PyObject *sys_path_orig;
+	PyObject *sys_path_new;
+	
 	if(!dirname)
 		return;
 	
@@ -321,23 +351,49 @@
 
 	if(!dir)
 		return;
-
-	if (dir != NULL) {
-		while((de = readdir(dir)) != NULL) {
-			BLI_make_file_string("/", path, dirname, de->d_name);
+	
+	gilstate = PyGILState_Ensure();
+	
+	/* backup sys.path */
+	sys_path_orig= PySys_GetObject("path");
+	Py_INCREF(sys_path_orig); /* dont free it */
+	
+	sys_path_new= PyList_New(1);
+	PyList_SET_ITEM(sys_path_new, 0, PyUnicode_FromString(dirname));
+	PySys_SetObject("path", sys_path_new);
+	Py_DECREF(sys_path_new);
+	
+	
+	while((de = readdir(dir)) != NULL) {
+		/* We could stat the file but easier just to let python
+		 * import it and complain if theres a problem */
+		
+		file_extension = strstr(de->d_name, ".py");
+		
+		if(file_extension && *(file_extension + 3) == '\0') {
+			filelen = strlen(de->d_name);
+			BLI_strncpy(path, de->d_name, filelen-2); /* cut off the .py on copy */
 			
-			stat(path, &status);
-
-			/* run if it is a .py file */
-			if(S_ISREG(status.st_mode)) {
-				file_extension = strstr(de->d_name, ".py");
-
-				if(file_extension && *(file_extension + 3) == '\0')
-					BPY_run_python_script(C, path, NULL);
+			mod= PyImport_ImportModuleLevel(path, NULL, NULL, NULL, 0);
+			if (mod) {
+				Py_DECREF(mod);			
 			}
+			else {
+				PyErr_Print();
+				fprintf(stderr, "unable to import \"%s\"  %s/%s\n", path, dirname, de->d_name);
+			}
+			
 		}
+	}
 
-		closedir(dir);
-	}
+	closedir(dir);
+	
+	PySys_SetObject("path", sys_path_orig);
+	Py_DECREF(sys_path_orig);
+	
+	PyGILState_Release(gilstate);
+#ifdef TIME_REGISTRATION
+	printf("script time %f\n", (PIL_check_seconds_timer()-time));
+#endif
 }
 

Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_operator.c
===================================================================
--- branches/blender2.5/blender/source/blender/python/intern/bpy_operator.c	2009-04-11 02:18:24 UTC (rev 19652)
+++ branches/blender2.5/blender/source/blender/python/intern/bpy_operator.c	2009-04-11 05:46:40 UTC (rev 19653)
@@ -262,7 +262,7 @@
 
 PyTypeObject pyop_base_Type = {NULL};
 
-PyObject *BPY_operator_module( bContext *C )
+PyObject *BPY_operator_module( void )
 {
 	pyop_base_Type.tp_name = "OperatorBase";
 	pyop_base_Type.tp_basicsize = sizeof( BPy_OperatorBase );

Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_operator.h
===================================================================
--- branches/blender2.5/blender/source/blender/python/intern/bpy_operator.h	2009-04-11 02:18:24 UTC (rev 19652)
+++ branches/blender2.5/blender/source/blender/python/intern/bpy_operator.h	2009-04-11 05:46:40 UTC (rev 19653)
@@ -40,7 +40,7 @@
 	PyObject_HEAD /* required python macro   */
 } BPy_OperatorBase;
 
-PyObject *BPY_operator_module(bContext *C );
+PyObject *BPY_operator_module(void);
 
 /* fill in properties from a python dict */
 int PYOP_props_from_dict(PointerRNA *ptr, PyObject *kw);

Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c
===================================================================
--- branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c	2009-04-11 02:18:24 UTC (rev 19652)
+++ branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c	2009-04-11 05:46:40 UTC (rev 19653)
@@ -1526,11 +1526,14 @@
 		- myClass = type(name='myClass', bases=(myBase,), dict={'some':'value'})
 		*/
 		char name[256], *nameptr;
+		const char *descr= RNA_struct_ui_description(ptr);
 
 		PyObject *args = PyTuple_New(3);
 		PyObject *bases = PyTuple_New(1);
 		PyObject *dict = PyDict_New();
+		PyObject *item;
 		
+		
 		nameptr= RNA_property_string_get_alloc(ptr, nameprop, name, sizeof(name));
 		
 		// arg 1
@@ -1544,6 +1547,12 @@
 		PyTuple_SET_ITEM(args, 1, bases);
 		
 		// arg 3 - add an instance of the rna 
+		if(descr) {
+			item= PyUnicode_FromString(descr);
+			PyDict_SetItemString(dict, "__doc__", item);
+			Py_DECREF(item);
+		}
+		
 		PyTuple_SET_ITEM(args, 2, dict); // fill with useful subclass things!
 		
 		if (PyErr_Occurred()) {
@@ -1552,23 +1561,19 @@
 		}
 		
 		newclass = PyObject_CallObject((PyObject *)&PyType_Type, args);
-		// Set this later
-		
+		Py_DECREF(args);
 
 		if (newclass) {
-			PyObject *rna;
 			RNA_struct_py_type_set(ptr->data, (void *)newclass); /* Store for later use */
 
 			/* Not 100% needed but useful,
 			 * having an instance within a type looks wrong however this instance IS an rna type */
-			rna = pyrna_struct_CreatePyObject(ptr);
-			PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "__rna__", rna);
-			Py_DECREF(rna);
+			item = pyrna_struct_CreatePyObject(ptr);
+			PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "__rna__", item);
+			Py_DECREF(item);
 			/* done with rna instance */
 		}
 		
-		Py_DECREF(args);
-		
 		if (name != nameptr)
 			MEM_freeN(nameptr);
 	}

Modified: branches/blender2.5/blender/source/creator/creator.c
===================================================================
--- branches/blender2.5/blender/source/creator/creator.c	2009-04-11 02:18:24 UTC (rev 19652)
+++ branches/blender2.5/blender/source/creator/creator.c	2009-04-11 05:46:40 UTC (rev 19653)
@@ -529,7 +529,7 @@
 	 */
 	BPY_post_start_python();
 
-	BPY_run_ui_scripts(C);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list