[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16194] trunk/blender/source/gameengine/ GamePlayer/ghost: GameLogic. globalDict blenderplayer now keeps settings when loading new blend files.

Campbell Barton ideasman42 at gmail.com
Wed Aug 20 08:11:12 CEST 2008


Revision: 16194
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16194
Author:   campbellbarton
Date:     2008-08-20 08:11:11 +0200 (Wed, 20 Aug 2008)

Log Message:
-----------
GameLogic.globalDict blenderplayer now keeps settings when loading new blend files.
workaround for python stopping and starting by storing the dictionary as marshal'd data. this means only python types are supported.
This feature is needed so when switching from a menu to a level blendfile, the configuration isnt lost.

Modified Paths:
--------------
    trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
    trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.h
    trunk/blender/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp

Modified: trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
===================================================================
--- trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.cpp	2008-08-19 22:16:01 UTC (rev 16193)
+++ trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.cpp	2008-08-20 06:11:11 UTC (rev 16194)
@@ -97,8 +97,8 @@
 #include "GHOST_IEventConsumer.h"
 #include "GHOST_IWindow.h"
 #include "GHOST_Rect.h"
+#include "marshal.h"
 
-
 static void frameTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time);
 
 static GHOST_ISystem* fSystem = 0;
@@ -125,7 +125,9 @@
 	  m_networkdevice(0), 
 	  m_audiodevice(0),
 	  m_blendermat(0),
-	  m_blenderglslmat(0)
+	  m_blenderglslmat(0),
+	  m_pyGlobalDictString(0),
+	  m_pyGlobalDictString_Length(0)
 {
 	fSystem = system;
 }
@@ -645,14 +647,23 @@
 		PyObject* dictionaryobject = initGamePlayerPythonScripting("Ketsji", psl_Lowest);
 		m_ketsjiengine->SetPythonDictionary(dictionaryobject);
 		initRasterizer(m_rasterizer, m_canvas);
-		PyDict_SetItemString(dictionaryobject, "GameLogic", initGameLogic(startscene)); // Same as importing the module
+		PyObject *gameLogic = initGameLogic(startscene);
+		PyDict_SetItemString(dictionaryobject, "GameLogic", gameLogic); // Same as importing the module
 		initGameKeys();
 		initPythonConstraintBinding();
 		initMathutils();
 
-
-
-
+		/* Restore the dict */
+		if (m_pyGlobalDictString) {
+			PyObject* pyGlobalDict = PyMarshal_ReadObjectFromString(m_pyGlobalDictString, m_pyGlobalDictString_Length);
+			if (pyGlobalDict) {
+				PyDict_SetItemString(PyModule_GetDict(gameLogic), "globalDict", pyGlobalDict); // Same as importing the module.
+			} else {
+				PyErr_Clear();
+				printf("Error could not marshall string\n");
+			}
+		}
+		
 		m_sceneconverter->ConvertScene(
 			startscenename,
 			startscene,
@@ -688,6 +699,32 @@
 
 void GPG_Application::stopEngine()
 {
+	// get the python dict and convert to a string for future use
+	{
+		SetPyGlobalDictMarshal(NULL, 0);
+		
+		PyObject* gameLogic = PyImport_ImportModule("GameLogic");
+		if (gameLogic) {
+			PyObject* pyGlobalDict = PyDict_GetItemString(PyModule_GetDict(gameLogic), "globalDict"); // Same as importing the module
+			if (pyGlobalDict) {
+				PyObject* pyGlobalDictMarshal = PyMarshal_WriteObjectToString(	pyGlobalDict, 2); // Py_MARSHAL_VERSION == 2 as of Py2.5
+				if (pyGlobalDictMarshal) {
+					m_pyGlobalDictString_Length = PyString_Size(pyGlobalDictMarshal);
+					PyObject_Print(pyGlobalDictMarshal, stderr, 0);
+					m_pyGlobalDictString = static_cast<char *> (malloc(m_pyGlobalDictString_Length));
+					memcpy(m_pyGlobalDictString, PyString_AsString(pyGlobalDictMarshal), m_pyGlobalDictString_Length);
+				} else {
+					printf("Error, GameLogic.globalDict could not be marshal'd\n");
+				}
+			} else {
+				printf("Error, GameLogic.globalDict was removed\n");
+			}
+		} else {
+			printf("Error, GameLogic failed to import GameLogic.globalDict will be lost\n");
+		}
+	}	
+	
+	
 	// when exiting the mainloop
 	exitGamePythonScripting();
 	m_ketsjiengine->StopEngine();

Modified: trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.h
===================================================================
--- trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.h	2008-08-19 22:16:01 UTC (rev 16193)
+++ trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.h	2008-08-20 06:11:11 UTC (rev 16194)
@@ -72,6 +72,29 @@
 			bool StartGameEngine(int stereoMode);
 			void StopGameEngine();
 
+			char*
+		GetPyGlobalDictMarshal()
+		{ 
+			return m_pyGlobalDictString;
+		};
+		
+			void
+		SetPyGlobalDictMarshal( char* pyGlobalDictString, int length )
+		{
+			if (m_pyGlobalDictString && m_pyGlobalDictString != pyGlobalDictString)
+				free(m_pyGlobalDictString);
+			
+			m_pyGlobalDictString = pyGlobalDictString;
+			m_pyGlobalDictString_Length = length;
+		};
+		
+			int
+		GetPyGlobalDictMarshalLength()
+		{ 
+			return m_pyGlobalDictString_Length;
+		};
+
+
 protected:
 	bool	handleWheel(GHOST_IEvent* event);
 	bool	handleButton(GHOST_IEvent* event, bool isDown);
@@ -142,6 +165,12 @@
 
 	bool m_blendermat;
 	bool m_blenderglslmat;
-
+	
+	/*
+	 * GameLogic.globalDict as a string so that loading new blend files can use the same dict.
+	 * Do this because python starts/stops when loading blend files.
+	 */
+	char* m_pyGlobalDictString;
+	int m_pyGlobalDictString_Length;
 };
 

Modified: trunk/blender/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
===================================================================
--- trunk/blender/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp	2008-08-19 22:16:01 UTC (rev 16193)
+++ trunk/blender/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp	2008-08-20 06:11:11 UTC (rev 16194)
@@ -293,7 +293,9 @@
 	GHOST_TUns32 fullScreenHeight= 0;
 	int fullScreenBpp = 32;
 	int fullScreenFrequency = 60;
-
+	char* pyGlobalDictString = NULL; /* store python dict data between blend file loading */
+	int pyGlobalDictString_Length = 0;
+	
 #ifdef __linux__
 #ifdef __alpha__
 	signal (SIGFPE, SIG_IGN);
@@ -625,6 +627,10 @@
 						
 						titlename = maggie->name;
 						
+						// Set the GameLogic.globalDict from marshal'd data, so we can load new blend files
+						// abd keep data in GameLogic.globalDict
+						app.SetPyGlobalDictMarshal(pyGlobalDictString, pyGlobalDictString_Length);
+						
 						// Check whether the game should be displayed full-screen
 						if ((!fullScreenParFound) && (!windowParFound))
 						{
@@ -750,6 +756,12 @@
 							}
 						}
 						app.StopGameEngine();
+						
+						// GameLogic.globalDict has been converted into a buffer
+						// store in pyGlobalDictString so we can restore after python has stopped and started.
+						pyGlobalDictString = app.GetPyGlobalDictMarshal();
+						pyGlobalDictString_Length = app.GetPyGlobalDictMarshalLength();
+						
 						BLO_blendfiledata_free(bfd);
 						
 #ifdef __APPLE__
@@ -772,6 +784,11 @@
 		}
 	}
 
+	if (pyGlobalDictString) {
+		free(pyGlobalDictString);
+		pyGlobalDictString = NULL;
+	}
+	
 	return error ? -1 : 0;
 }
 





More information about the Bf-blender-cvs mailing list