diff options
author | Mitchell Stokes <mogurijin@gmail.com> | 2010-08-28 06:07:55 +0400 |
---|---|---|
committer | Mitchell Stokes <mogurijin@gmail.com> | 2010-08-28 06:07:55 +0400 |
commit | 5c23537daa5c669b672528b0ed2bcaef2038f766 (patch) | |
tree | d8dafae80815cdd6d05e23ededc87df0098b2eb3 | |
parent | 5729b991fa06734a7a7d58b4ff0f2feab5db8bca (diff) |
Committing patch [#23278] (by me)
This patch allows a user to pass binary data to LibLoad() to load a blend file from memory instead of a file path. I don't know how useful this will be for others, but I've used it so far for:
* Decrypting .blend files and loading them without having to store the .blend on the hard drive
* Pulling .blend data out of an archive and loading it (again skipping the hard drive)
So, it seems the biggest use for this is skipping a bit of file IO (and possibly some security problems).
Example usage:
import bge
with f as open('myfile.blend', 'rb'):
data = f.read()
bge.logic.LibLoad('Name', 'Scene', data)
-rw-r--r-- | source/blender/blenloader/BLO_readfile.h | 13 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readblenentry.c | 9 | ||||
-rw-r--r-- | source/gameengine/Converter/KX_BlenderSceneConverter.cpp | 20 | ||||
-rw-r--r-- | source/gameengine/Converter/KX_BlenderSceneConverter.h | 4 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PythonInit.cpp | 21 | ||||
-rw-r--r-- | source/gameengine/PyDoc/bge.logic.rst | 6 |
6 files changed, 64 insertions, 9 deletions
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index eeced13b57b..719a3c065ae 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -123,6 +123,19 @@ BLO_blendhandle_from_file( char *file); /** + * Open a blendhandle from memory. + * + * @param mem The data to load from. + * @param memsize The size of the data. + * @return A handle on success, or NULL on failure. + */ + + BlendHandle* +BLO_blendhandle_from_memory( + void *mem, + int memsize); + +/** * Gets the names of all the datablocks in a file * of a certain type (ie. All the scene names in * a file). diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index d66d802c8ee..da441214b37 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -76,6 +76,15 @@ BlendHandle *BLO_blendhandle_from_file(char *file) return bh; } +BlendHandle *BLO_blendhandle_from_memory(void *mem, int memsize) +{ + BlendHandle *bh; + + bh= (BlendHandle*)blo_openblendermemory(mem, memsize, NULL); + + return bh; +} + void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp) { FileData *fd= (FileData*) bh; diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index b4ddc4f9e54..1ce6876dda1 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -932,13 +932,28 @@ Main* KX_BlenderSceneConverter::GetMainDynamicPath(const char *path) return NULL; } -bool KX_BlenderSceneConverter::LinkBlendFile(const char *path, char *group, KX_Scene *scene_merge, char **err_str) +bool KX_BlenderSceneConverter::LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str) +{ + BlendHandle *bpy_openlib = BLO_blendhandle_from_memory(data, length); + + // Error checking is done in LinkBlendFile + return LinkBlendFile(bpy_openlib, path, group, scene_merge, err_str); +} + +bool KX_BlenderSceneConverter::LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str) +{ + BlendHandle *bpy_openlib = BLO_blendhandle_from_file( (char *)path ); + + // Error checking is done in LinkBlendFile + return LinkBlendFile(bpy_openlib, path, group, scene_merge, err_str); +} + +bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str) { bContext *C; Main *main_newlib; /* stored as a dynamic 'main' until we free it */ Main *main_tmp= NULL; /* created only for linking, then freed */ LinkNode *names = NULL; - BlendHandle *bpy_openlib = NULL; /* ptr to the open .blend file */ int idcode= BKE_idcode_from_name(group); short flag= 0; /* dont need any special options */ ReportList reports; @@ -956,7 +971,6 @@ bool KX_BlenderSceneConverter::LinkBlendFile(const char *path, char *group, KX_S return false; } - bpy_openlib = BLO_blendhandle_from_file( (char *)path ); if(bpy_openlib==NULL) { snprintf(err_local, sizeof(err_local), "could not open blendfile \"%s\"\n", path); *err_str= err_local; diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h index 23d506c98ff..20f3f863563 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.h +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h @@ -142,7 +142,9 @@ public: struct Main* GetMainDynamicPath(const char *path); vector<struct Main*> &GetMainDynamic(); - bool LinkBlendFile(const char *path, char *group, KX_Scene *scene_merge, char **err_str); + bool LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str); + bool LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str); + bool LinkBlendFile(struct BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str); bool MergeScene(KX_Scene *to, KX_Scene *from); RAS_MeshObject *ConvertMeshSpecial(KX_Scene* kx_scene, Main *maggie, const char *name); bool FreeBlendFile(struct Main *maggie); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 3785f715803..00995fffe73 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -626,13 +626,28 @@ static PyObject *gLibLoad(PyObject*, PyObject* args) KX_Scene *kx_scene= gp_KetsjiScene; char *path; char *group; + Py_buffer py_buffer; + py_buffer.buf = NULL; char *err_str= NULL; - if (!PyArg_ParseTuple(args,"ss:LibLoad",&path, &group)) + if (!PyArg_ParseTuple(args,"ss|y*:LibLoad",&path, &group, &py_buffer)) return NULL; - if(kx_scene->GetSceneConverter()->LinkBlendFile(path, group, kx_scene, &err_str)) { - Py_RETURN_TRUE; + if (!py_buffer.buf) + { + if(kx_scene->GetSceneConverter()->LinkBlendFilePath(path, group, kx_scene, &err_str)) { + Py_RETURN_TRUE; + } + } + else + { + + if(kx_scene->GetSceneConverter()->LinkBlendFileMemory(py_buffer.buf, py_buffer.len, path, group, kx_scene, &err_str)) { + PyBuffer_Release(&py_buffer); + Py_RETURN_TRUE; + } + + PyBuffer_Release(&py_buffer); } if(err_str) { diff --git a/source/gameengine/PyDoc/bge.logic.rst b/source/gameengine/PyDoc/bge.logic.rst index a10733569f3..a7eb5635d0f 100644 --- a/source/gameengine/PyDoc/bge.logic.rst +++ b/source/gameengine/PyDoc/bge.logic.rst @@ -173,14 +173,16 @@ General functions Restarts the current game by reloading the .blend file (the last saved version, not what is currently running). -.. function:: LibLoad(blend, type) +.. function:: LibLoad(blend, type, data) Converts the all of the datablocks of the given type from the given blend. - :arg blend: The path to the blend file + :arg blend: The path to the blend file (or the name to use for the library if data is supplied) :type blend: string :arg type: The datablock type (currently only "Scene" and "Mesh" are supported) :type type: string + :arg data: Binary data from a blend file (optional) + :type data: bytes .. function:: LibNew(name, type, data) |