Skip to content

Commit

Permalink
UPBGE: Implement libload target scene python argument.
Browse files Browse the repository at this point in the history
The user can now specify the scene to merge to a libload by
setting the "scene" argument in bge.logic.LibLoad.

Sdfgeoff feature request for LibLoad(..., scenemerge).
  • Loading branch information
panzergame committed Jun 6, 2017
1 parent a0aa88e commit 18d5bb1
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 5 deletions.
4 changes: 3 additions & 1 deletion doc/python_api/rst/bge.logic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ General functions

Restarts the current game by reloading the .blend file (the last saved version, not what is currently running).

.. function:: LibLoad(blend, type, data, load_actions=False, verbose=False, load_scripts=True, async=False)
.. function:: LibLoad(blend, type, data, load_actions=False, verbose=False, load_scripts=True, async=False, scene=None)

Converts the all of the datablocks of the given type from the given blend.

Expand All @@ -203,6 +203,8 @@ General functions
:type load_scripts: bool
:arg async: Whether or not to do the loading asynchronously (in another thread). Only the "Scene" type is currently supported for this feature.
:type async: bool
:arg scene: Scene to merge loaded data to, if `None` use the current scene.
:type scene: :class:`bge.types.KX_Scene` or string

:rtype: :class:`bge.types.KX_LibLoadStatus`

Expand Down
16 changes: 12 additions & 4 deletions source/gameengine/Ketsji/KX_PythonInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,8 @@ static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *)

static PyObject *gLibLoad(PyObject *, PyObject *args, PyObject *kwds)
{
KX_Scene *kx_scene= KX_GetActiveScene();
KX_Scene *kx_scene = nullptr;
PyObject *pyscene = Py_None;
char *path;
char *group;
Py_buffer py_buffer;
Expand All @@ -632,11 +633,18 @@ static PyObject *gLibLoad(PyObject *, PyObject *args, PyObject *kwds)
short options=0;
int load_actions=0, verbose=0, load_scripts=1, async=0;

static const char *kwlist[] = {"path", "group", "buffer", "load_actions", "verbose", "load_scripts", "async", nullptr};
static const char *kwlist[] = {"path", "group", "buffer", "load_actions", "verbose", "load_scripts", "async", "scene", nullptr};

if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|y*iiIi:LibLoad", const_cast<char**>(kwlist),
&path, &group, &py_buffer, &load_actions, &verbose, &load_scripts, &async))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|y*iiIiO:LibLoad", const_cast<char**>(kwlist),
&path, &group, &py_buffer, &load_actions, &verbose, &load_scripts, &async, &pyscene))
return nullptr;

if (!ConvertPythonToScene(pyscene, &kx_scene, true, "invalid scene")) {
return nullptr;
}
if (!kx_scene) {
kx_scene = KX_GetActiveScene();
}

/* setup options */
if (load_actions != 0)
Expand Down
56 changes: 56 additions & 0 deletions source/gameengine/Ketsji/KX_Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2497,4 +2497,60 @@ KX_PYMETHODDEF_DOC(KX_Scene, get, "")
return def;
}

bool ConvertPythonToScene(PyObject *value, KX_Scene **scene, bool py_none_ok, const char *error_prefix)
{
if (value == nullptr) {
PyErr_Format(PyExc_TypeError, "%s, python pointer nullptr, should never happen", error_prefix);
*scene = nullptr;
return false;
}

if (value == Py_None) {
*scene = nullptr;

if (py_none_ok) {
return true;
}
else {
PyErr_Format(PyExc_TypeError, "%s, expected KX_Scene or a KX_Scene name, None is invalid", error_prefix);
return false;
}
}

if (PyUnicode_Check(value)) {
*scene = (KX_Scene *)KX_GetActiveEngine()->CurrentScenes()->FindValue(std::string(_PyUnicode_AsString(value)));

if (*scene) {
return true;
}
else {
PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any in game", error_prefix, _PyUnicode_AsString(value));
return false;
}
}

if (PyObject_TypeCheck(value, &KX_Scene::Type)) {
*scene = static_cast<KX_Scene *>BGE_PROXY_REF(value);

// Sets the error.
if (*scene == nullptr) {
PyErr_Format(PyExc_SystemError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix);
return false;
}

return true;
}

*scene = nullptr;

if (py_none_ok) {
PyErr_Format(PyExc_TypeError, "%s, expect a KX_Scene, a string or None", error_prefix);
}
else {
PyErr_Format(PyExc_TypeError, "%s, expect a KX_Scene or a string", error_prefix);
}

return false;
}

#endif // WITH_PYTHON
4 changes: 4 additions & 0 deletions source/gameengine/Ketsji/KX_Scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,10 @@ class KX_Scene : public CValue, public SCA_IScene
//}
};

#ifdef WITH_PYTHON
bool ConvertPythonToScene(PyObject *value, KX_Scene **scene, bool py_none_ok, const char *error_prefix);
#endif

typedef std::vector<KX_Scene*> KX_SceneList;

#endif /* __KX_SCENE_H__ */

0 comments on commit 18d5bb1

Please sign in to comment.