[Bf-blender-cvs] [fb49c5a] master: BGE: fix crash and return boolean on scene.replace()

Benoit Bolsee noreply at git.blender.org
Sat Aug 23 12:37:32 CEST 2014


Commit: fb49c5aa5662da3c2434c75ea6283408c01d6c23
Author: Benoit Bolsee
Date:   Sat Aug 23 12:31:32 2014 +0200
Branches: master
https://developer.blender.org/rBfb49c5aa5662da3c2434c75ea6283408c01d6c23

BGE: fix crash and return boolean on scene.replace()

Scene replacement with invalid scene name was crashing blender,
now it's a no-op.
KS_Scene.replace() to return a boolean to indicate if the scene
is valid and is scheduled for replacement. This allows more
robust game management.

===================================================================

M	doc/python_api/rst/bge_types/bge.types.KX_Scene.rst
M	source/gameengine/Ketsji/KX_KetsjiEngine.cpp
M	source/gameengine/Ketsji/KX_KetsjiEngine.h
M	source/gameengine/Ketsji/KX_Scene.cpp

===================================================================

diff --git a/doc/python_api/rst/bge_types/bge.types.KX_Scene.rst b/doc/python_api/rst/bge_types/bge.types.KX_Scene.rst
index 75630ae..f2dad58 100644
--- a/doc/python_api/rst/bge_types/bge.types.KX_Scene.rst
+++ b/doc/python_api/rst/bge_types/bge.types.KX_Scene.rst
@@ -152,6 +152,8 @@ base class --- :class:`PyObjectPlus`
 
       :arg scene: The name of the scene to replace this scene with.
       :type scene: string
+      :return: True if the scene exists and was scheduled for addition, False otherwise.
+      :rtype: boolean
 
    .. method:: suspend()
 
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 5a2cb0c..14772cd 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -1732,9 +1732,20 @@ void KX_KetsjiEngine::AddScheduledScenes()
 
 
 
-void KX_KetsjiEngine::ReplaceScene(const STR_String& oldscene,const STR_String& newscene)
-{
-	m_replace_scenes.push_back(std::make_pair(oldscene,newscene));
+bool KX_KetsjiEngine::ReplaceScene(const STR_String& oldscene,const STR_String& newscene)
+{
+    // Don't allow replacement if the new scene doesn't exists.
+    // Allows smarter game design (used to have no check here).
+    // Note that it creates a small backward compatbility issue
+    // for a game that did a replace followed by a lib load with the
+    // new scene in the lib => it won't work anymore, the lib
+    // must be loaded before doing the replace.
+    if (m_sceneconverter->GetBlenderSceneForName(newscene) != NULL)
+    {
+        m_replace_scenes.push_back(std::make_pair(oldscene,newscene));
+        return true;
+    }
+    return false;
 }
 
 // replace scene is not the same as removing and adding because the
@@ -1758,13 +1769,19 @@ void KX_KetsjiEngine::ReplaceScheduledScenes()
 			KX_SceneList::iterator sceneit;
 			for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
 			{
-				KX_Scene* scene = *sceneit;
+                KX_Scene* scene = *sceneit;
 				if (scene->GetName() == oldscenename)
 				{
-					m_sceneconverter->RemoveScene(scene);
-					KX_Scene* tmpscene = CreateScene(newscenename);
-					m_scenes[i]=tmpscene;
-					PostProcessScene(tmpscene);
+                    // avoid crash if the new scene doesn't exist, just do nothing
+                    Scene *blScene = m_sceneconverter->GetBlenderSceneForName(newscenename);
+                    if (blScene) {
+                        m_sceneconverter->RemoveScene(scene);
+                        KX_Scene* tmpscene = CreateScene(blScene);
+                        m_scenes[i]=tmpscene;
+                        PostProcessScene(tmpscene);
+                    } else {
+                        printf("warning: scene %s could not be found, not replaced!\n",newscenename.ReadPtr());
+                    }
 				}
 				i++;
 			}
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 2bc5bad..2b80e3b 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -258,7 +258,7 @@ public:
 	void			ConvertAndAddScene(const STR_String& scenename,bool overlay);
 
 	void			RemoveScene(const STR_String& scenename);
-	void			ReplaceScene(const STR_String& oldscene,const STR_String& newscene);
+    bool			ReplaceScene(const STR_String& oldscene,const STR_String& newscene);
 	void			SuspendScene(const STR_String& scenename);
 	void			ResumeScene(const STR_String& scenename);
 
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 5745e3a..625bbee 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -2501,16 +2501,18 @@ KX_PYMETHODDEF_DOC(KX_Scene, restart,
 
 KX_PYMETHODDEF_DOC(KX_Scene, replace,
 				   "replace(newScene)\n"
-				   "Replaces this scene with another one.\n")
+                   "Replaces this scene with another one.\n"
+                   "Return True if the new scene exists and scheduled for replacement, False otherwise.\n")
 {
 	char* name;
 	
 	if (!PyArg_ParseTuple(args, "s:replace", &name))
 		return NULL;
 	
-	KX_GetActiveEngine()->ReplaceScene(m_sceneName, name);
+    if (KX_GetActiveEngine()->ReplaceScene(m_sceneName, name))
+        Py_RETURN_TRUE;
 	
-	Py_RETURN_NONE;
+    Py_RETURN_FALSE;
 }
 
 KX_PYMETHODDEF_DOC(KX_Scene, suspend,




More information about the Bf-blender-cvs mailing list