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,

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to