Fix for [#31396] "bge.logic.LibLoad fails to import text blocks" reported by Leonard...
authorMitchell Stokes <mogurijin@gmail.com>
Thu, 21 Jun 2012 05:41:06 +0000 (05:41 +0000)
committerMitchell Stokes <mogurijin@gmail.com>
Thu, 21 Jun 2012 05:41:06 +0000 (05:41 +0000)
Blender's import function check's the Text datablocks in main for additional modules for importing. However, libloaded scenes were 1) not loading Text datablocks and 2) not letting bpy know about them. Text datablocks are now loaded if a Scene is loaded and bpy can now looking through extra Mains to find additional modules.

source/blender/python/generic/bpy_internal_import.c
source/blender/python/generic/bpy_internal_import.h
source/gameengine/Converter/KX_BlenderSceneConverter.cpp
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_PythonInit.h

index 5999040a2ab371e44d55cfcc1c114743d4dfee0d..3a46c6971cf75fdf067c71868217408fcda33f0b 100644 (file)
@@ -52,6 +52,7 @@
 #include "BKE_main.h"
 
 static Main *bpy_import_main = NULL;
+static ListBase bpy_import_main_list;
 
 /* 'builtins' is most likely PyEval_GetBuiltins() */
 void bpy_import_init(PyObject *builtins)
@@ -92,6 +93,16 @@ void bpy_import_main_set(struct Main *maggie)
        bpy_import_main = maggie;
 }
 
+void bpy_import_main_extra_add(struct Main *maggie)
+{
+       BLI_addhead(&bpy_import_main_list, maggie);
+}
+
+void bpy_import_main_extra_remove(struct Main *maggie)
+{
+       BLI_remlink_safe(&bpy_import_main_list, maggie);
+}
+
 /* returns a dummy filename for a textblock so we can tell what file a text block comes from */
 void bpy_text_filename_get(char *fn, size_t fn_len, Text *text)
 {
@@ -150,6 +161,18 @@ PyObject *bpy_text_import_name(const char *name, int *found)
 
        text = BLI_findstring(&maggie->text, txtname, offsetof(ID, name) + 2);
 
+       if (text) {
+               *found = 1;
+               return bpy_text_import(text);
+       }
+
+       /* If we still haven't found the module try additional modules form bpy_import_main_list */
+       maggie = bpy_import_main_list.first;
+       while (maggie && !text) {
+               text = BLI_findstring(&maggie->text, txtname, offsetof(ID, name) + 2);
+               maggie = maggie->next;
+       }
+
        if (!text)
                return NULL;
        else
index 8b41a575d968b7382a0ee6d0e10ce3e1573a031e..980e6edca03990e79b6e7965bc63e0461b6853d8 100644 (file)
@@ -62,4 +62,8 @@ extern PyMethodDef bpy_reload_meth;
 struct Main *bpy_import_main_get(void);
 void bpy_import_main_set(struct Main *maggie);
 
+/* This is used for importing text from dynamically loaded libraries in the game engine */
+void bpy_import_main_extra_add(struct Main *maggie);
+void bpy_import_main_extra_remove(struct Main *maggie);
+
 #endif                         /* __BPY_INTERNAL_IMPORT_H__ */
index 78e5d7b32c23c41a2711b6709a73509efead9812..3961e6554a724bfe620d5b8f652639d6af0ad51c 100644 (file)
@@ -42,6 +42,7 @@
 #include "KX_PhysicsEngineEnums.h"
 #include "PHY_IPhysicsEnvironment.h"
 #include "KX_KetsjiEngine.h"
+#include "KX_PythonInit.h" // So we can handle adding new text datablocks for Python to import
 #include "KX_IPhysicsController.h"
 #include "BL_Material.h"
 #include "BL_ActionActuator.h"
@@ -173,9 +174,9 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
 #endif
 
        /* free any data that was dynamically loaded */
-       for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) {
-               Main *main= *it;
-               free_main(main);
+       while (m_DynamicMaggie.size() != 0)
+       {
+               FreeBlendFile(m_DynamicMaggie[0]);
        }
 
        m_DynamicMaggie.clear();
@@ -987,6 +988,11 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
 
        load_datablocks(main_newlib, bpy_openlib, path, idcode);
 
+       if (idcode==ID_SCE) {
+               /* assume we want text blocks too */
+               load_datablocks(main_newlib, bpy_openlib, path, ID_TXT);
+       }
+
        /* now do another round of linking for Scenes so all actions are properly loaded */
        if (idcode==ID_SCE && options & LIB_LOAD_LOAD_ACTIONS) {
                load_datablocks(main_newlib, bpy_openlib, path, ID_AC);
@@ -1038,6 +1044,10 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
                        delete other;
                }
 
+               /* Handle any text datablocks */
+
+               addImportMain(main_newlib);
+
                /* Now handle all the actions */
                if (options & LIB_LOAD_LOAD_ACTIONS) {
                        ID *action;
@@ -1330,6 +1340,9 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
                }
        }
 
+       /* make sure this maggie is removed from the import list if it's there (this operation is safe if it isn't in the list) */
+       removeImportMain(maggie);
+
        free_main(maggie);
 
        return true;
index 28c4630c43eb05ceba205d9f131563689d4f87ff..2a648303c524346e70a0299fc481651717c9c73d 100644 (file)
@@ -1821,6 +1821,16 @@ static void restorePySysObjects(void)
 //     PyObject_Print(sys_path, stderr, 0);
 }
 
+void addImportMain(struct Main *maggie)
+{
+       bpy_import_main_extra_add(maggie);
+}
+
+void removeImportMain(struct Main *maggie)
+{
+       bpy_import_main_extra_remove(maggie);
+}
+
 // Copied from bpy_interface.c
 static struct _inittab bge_internal_modules[]= {
        {(char *)"mathutils", PyInit_mathutils},
index d8346018b55544bfffbc67dbd049450995af20a7..866681b9da7d7722ab7e0a668dce3802333885d6 100644 (file)
@@ -61,6 +61,9 @@ int                   saveGamePythonConfig( char **marshal_buffer);
 int                    loadGamePythonConfig(char *marshal_buffer, int marshal_length);
 #endif
 
+void addImportMain(struct Main *maggie);
+void removeImportMain(struct Main *maggie);
+
 class KX_KetsjiEngine;
 class KX_Scene;