Skip to content

Commit

Permalink
Tweak stuff such that executeString has the darkradiant objects readi…
Browse files Browse the repository at this point in the history
…ly imported
  • Loading branch information
codereader committed Jul 19, 2017
1 parent 9bc1bcc commit 0190e31
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 52 deletions.
47 changes: 15 additions & 32 deletions plugins/script/ScriptingSystem.cpp
Expand Up @@ -94,6 +94,14 @@ class DarkRadiantModule
_registrationCallback(GetModule(), GetGlobals());
}

py::object main = py::module::import("__main__");
py::dict globals = main.attr("__dict__").cast<py::dict>();

for (auto& i : globals)
{
GetGlobals()[i.first] = i.second;
}

return _module->ptr();
}
catch (py::error_already_set& e)
Expand Down Expand Up @@ -203,8 +211,11 @@ ExecutionResultPtr ScriptingSystem::executeString(const std::string& scriptStrin

try
{
std::string fullScript = "import darkradiant as DR\nfrom darkradiant import *\n";
fullScript.append(scriptString);

// Attempt to run the specified script
py::exec(scriptString);
py::exec(fullScript, DarkRadiantModule::GetGlobals());
}
catch (py::error_already_set& ex)
{
Expand Down Expand Up @@ -248,6 +259,9 @@ void ScriptingSystem::initialise()
{
try
{
// Import the darkradiant module
py::module::import("darkradiant");

// Construct the console writer interface
PythonConsoleWriterClass consoleWriter(DarkRadiantModule::GetModule(), "PythonConsoleWriter");
consoleWriter.def(py::init<bool, std::string&>());
Expand All @@ -265,37 +279,6 @@ void ScriptingSystem::initialise()
}
}

#if 0
// Add the registered interfaces
try {
for (Interfaces::iterator i = _interfaces.begin(); i != _interfaces.end(); ++i) {
// Handle each interface in its own try/catch block
try
{
i->second->registerInterface(_mainObjects->mainNamespace);
}
catch (const boost::python::error_already_set&)
{
rError() << "Error while initialising interface "
<< i->first << ": " << std::endl;

PyErr_Print();
PyErr_Clear();

rMessage() << std::endl;
}
}
}
catch (const boost::python::error_already_set&) {
// Dump the error to the console, this will invoke the PythonConsoleWriter
PyErr_Print();
PyErr_Clear();

// Python is usually not appending line feeds...
rMessage() << std::endl;
}
#endif

_initialised = true;

// Start the init script
Expand Down
86 changes: 66 additions & 20 deletions plugins/script/interfaces/SceneGraphInterface.h
Expand Up @@ -7,6 +7,7 @@
#include "iselection.h"
#include "debugging/ScenegraphUtils.h"

#include <pybind11/pybind11.h>
#include <boost/python.hpp>

namespace script {
Expand Down Expand Up @@ -117,38 +118,82 @@ class SceneNodeVisitorWrapper :
public boost::python::wrapper<scene::NodeVisitor>
{
public:
bool pre(const scene::INodePtr& node) {
// Wrap this method to python
return this->get_override("pre")(ScriptSceneNode(node));
}
using NodeVisitor::NodeVisitor;

void post(const scene::INodePtr& node) {
if (this->get_override("post")) {
// Call the overriden method
this->get_override("post")(ScriptSceneNode(node));
}
else {
// No override, call base class default
scene::NodeVisitor::post(node);
}
}

void post_default(const scene::INodePtr& node) {
// Default method: Just call the base class
scene::NodeVisitor::post(node);
bool pre(const scene::INodePtr& node) override
{
// Wrap this method to python
PYBIND11_OVERLOAD_PURE(
int, /* Return type */
NodeVisitor, /* Parent class */
pre, /* Name of function in C++ (must match Python name) */
ScriptSceneNode(node) /* Argument(s) */
);
}

void post(const scene::INodePtr& node) override
{
PYBIND11_OVERLOAD(
void, /* Return type */
NodeVisitor, /* Parent class */
post, /* Name of function in C++ (must match Python name) */
ScriptSceneNode(node) /* Argument(s) */
);
}
};

class SceneGraphInterface :
public IScriptInterface
{
public:
ScriptSceneNode root() {
ScriptSceneNode root()
{
return ScriptSceneNode(GlobalSceneGraph().root());
}

void registerInterface(py::module& scope, py::dict& globals) override
{
// Expose the scene::Node interface
py::class_<ScriptSceneNode> sceneNode(scope, "SceneNode");

sceneNode.def(py::init<const scene::INodePtr&>());
sceneNode.def("addToContainer", &ScriptSceneNode::addToContainer);
sceneNode.def("removeFromParent", &ScriptSceneNode::removeFromParent);
sceneNode.def("getWorldAABB", &ScriptSceneNode::getWorldAABB, py::return_value_policy::reference);
sceneNode.def("isNull", &ScriptSceneNode::isNull);
sceneNode.def("getParent", &ScriptSceneNode::getParent);
sceneNode.def("getNodeType", &ScriptSceneNode::getNodeType);
sceneNode.def("traverse", &ScriptSceneNode::traverse);
sceneNode.def("traverseChildren", &ScriptSceneNode::traverseChildren);
sceneNode.def("setSelected", &ScriptSceneNode::setSelected);
sceneNode.def("invertSelected", &ScriptSceneNode::invertSelected);
sceneNode.def("isSelected", &ScriptSceneNode::isSelected);

py::class_<scene::NodeVisitor, SceneNodeVisitorWrapper> visitor(scope, "SceneNodeVisitor");
visitor.def(py::init<>());
visitor.def("pre", &scene::NodeVisitor::pre);
visitor.def("post", &scene::NodeVisitor::post);

#if 0
// Expose the scene::NodeVisitor interface
nspace["SceneNodeVisitor"] =
boost::python::class_<SceneNodeVisitorWrapper, boost::noncopyable>("SceneNodeVisitor")
.def("pre", boost::python::pure_virtual(&scene::NodeVisitor::pre))
.def("post", &scene::NodeVisitor::post, &SceneNodeVisitorWrapper::post_default) // respect default impl.
;
#endif
// Add the module declaration to the given python namespace
py::class_<SceneGraphInterface> sceneGraphInterface(scope, "SceneGraph");
sceneGraphInterface.def("root", &SceneGraphInterface::root);

// Now point the Python variable "GlobalSceneGraph" to this instance
globals["GlobalSceneGraph"] = this;
}

#if 0
// IScriptInterface implementation
void registerInterface(boost::python::object& nspace) {
void registerInterface(boost::python::object& nspace)
{
// Expose the scene::Node interface
nspace["SceneNode"] = boost::python::class_<ScriptSceneNode>(
"SceneNode", boost::python::init<const scene::INodePtr&>())
Expand Down Expand Up @@ -181,6 +226,7 @@ class SceneGraphInterface :
// Now point the Python variable "GlobalSceneGraph" to this instance
nspace["GlobalSceneGraph"] = boost::python::ptr(this);
}
#endif
};
typedef std::shared_ptr<SceneGraphInterface> SceneGraphInterfacePtr;

Expand Down

0 comments on commit 0190e31

Please sign in to comment.