Skip to content

Commit

Permalink
Migrate EntityInterface
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Jul 20, 2017
1 parent c7530dc commit 07d8080
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 55 deletions.
2 changes: 1 addition & 1 deletion install/scripts/test.py
Expand Up @@ -118,7 +118,7 @@ def visit(self, key, value):
keyvalues = worldspawnent.getKeyValuePairs('t')

for kv in keyvalues:
print('Keyvalue ' + kv.first + ' = ' + kv.second)
print('Keyvalue ' + kv[0] + ' = ' + kv[1])

# Test the commandsystem
GlobalCommandSystem.execute('texscale "0 0.1"')
Expand Down
2 changes: 1 addition & 1 deletion plugins/script/interfaces/CommandSystemInterface.cpp
Expand Up @@ -22,7 +22,7 @@ void CommandSystemInterface::removeCommand(const std::string& name)
GlobalCommandSystem().removeCommand(name);
}

void CommandSystemInterface::registerInterface(pybind11::module& scope, py::dict& globals)
void CommandSystemInterface::registerInterface(py::module& scope, py::dict& globals)
{
pybind11::class_<CommandSystemInterface> commandSys(scope, "CommandSystem");

Expand Down
70 changes: 29 additions & 41 deletions plugins/script/interfaces/EntityInterface.cpp
@@ -1,13 +1,15 @@
#include "EntityInterface.h"

#include <pybind11/stl_bind.h>

#include "ientity.h"
#include "ieclass.h"
#include "itextstream.h"

#include "../SceneNodeBuffer.h"
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

namespace script {
namespace script
{

// Constructor, checks if the passed node is actually an entity
ScriptEntityNode::ScriptEntityNode(const scene::INodePtr& node) :
Expand Down Expand Up @@ -117,56 +119,42 @@ ScriptSceneNode EntityInterface::createEntity(const std::string& eclassName) {
return ScriptSceneNode(node);
}

void EntityInterface::registerInterface(boost::python::object& nspace) {
void EntityInterface::registerInterface(py::module& scope, py::dict& globals)
{
// Add the EntityNode interface
nspace["EntityNode"] = boost::python::class_<ScriptEntityNode,
boost::python::bases<ScriptSceneNode> >("EntityNode", boost::python::init<const scene::INodePtr&>() )
.def("getKeyValue", &ScriptEntityNode::getKeyValue)
.def("setKeyValue", &ScriptEntityNode::setKeyValue)
.def("forEachKeyValue", &ScriptEntityNode::forEachKeyValue)
.def("isInherited", &ScriptEntityNode::isInherited)
.def("getEntityClass", &ScriptEntityNode::getEntityClass)
.def("isModel", &ScriptEntityNode::isModel)
.def("isOfType", &ScriptEntityNode::isOfType)
.def("getKeyValuePairs", &ScriptEntityNode::getKeyValuePairs)
;
py::class_<ScriptEntityNode, ScriptSceneNode> entityNode(scope, "EntityNode");
entityNode.def(py::init<const scene::INodePtr&>());
entityNode.def("getKeyValue", &ScriptEntityNode::getKeyValue);
entityNode.def("setKeyValue", &ScriptEntityNode::setKeyValue);
entityNode.def("forEachKeyValue", &ScriptEntityNode::forEachKeyValue);
entityNode.def("isInherited", &ScriptEntityNode::isInherited);
entityNode.def("getEntityClass", &ScriptEntityNode::getEntityClass);
entityNode.def("isModel", &ScriptEntityNode::isModel);
entityNode.def("isOfType", &ScriptEntityNode::isOfType);
entityNode.def("getKeyValuePairs", &ScriptEntityNode::getKeyValuePairs);

// Declare a KeyValuePair (pair of strings)
boost::python::class_< std::pair<std::string, std::string> >(
"EntityKeyValuePair", boost::python::init<std::string, std::string>())
.def_readwrite("first", &std::pair<std::string, std::string>::first)
.def_readwrite("second", &std::pair<std::string, std::string>::second)
;
py::class_< std::pair<std::string, std::string> > kvPair(scope, "EntityKeyValuePair");
kvPair.def_readwrite("first", &std::pair<std::string, std::string>::first);
kvPair.def_readwrite("second", &std::pair<std::string, std::string>::second);

// Declare the KeyValuePairs vector
boost::python::class_<Entity::KeyValuePairs>("EntityKeyValuePairs")
.def(boost::python::vector_indexing_suite<Entity::KeyValuePairs, true>())
;

// Add the "isEntity" and "getEntity" method to all ScriptSceneNodes
boost::python::object sceneNode = nspace["SceneNode"];

boost::python::objects::add_to_namespace(sceneNode,
"isEntity", boost::python::make_function(&ScriptEntityNode::isEntity));

boost::python::objects::add_to_namespace(sceneNode,
"getEntity", boost::python::make_function(&ScriptEntityNode::getEntity));
py::bind_vector<Entity::KeyValuePairs>(scope, "EntityKeyValuePairs");

// Expose the Entity::Visitor interface
nspace["EntityVisitor"] =
boost::python::class_<EntityVisitorWrapper, boost::noncopyable>("EntityVisitor")
.def("visit", boost::python::pure_virtual(&EntityVisitorWrapper::visit))
;
py::class_<EntityVisitor, EntityVisitorWrapper> visitor(scope, "EntityVisitor");
visitor.def(py::init<>());
visitor.def("visit", &EntityVisitor::visit);

// Add the EntityCreator module declaration to the given python namespace
nspace["GlobalEntityCreator"] = boost::python::class_<EntityInterface>("GlobalEntityCreator")
// Add both overloads to createEntity
.def("createEntity", static_cast<ScriptSceneNode (EntityInterface::*)(const std::string&)>(&EntityInterface::createEntity))
.def("createEntity", static_cast<ScriptSceneNode (EntityInterface::*)(const ScriptEntityClass&)>(&EntityInterface::createEntity))
;
py::class_<EntityInterface> entityCreator(scope, "EntityCreator");

// Add both overloads to createEntity
entityCreator.def("createEntity", static_cast<ScriptSceneNode(EntityInterface::*)(const std::string&)>(&EntityInterface::createEntity));
entityCreator.def("createEntity", static_cast<ScriptSceneNode(EntityInterface::*)(const ScriptEntityClass&)>(&EntityInterface::createEntity));

// Now point the Python variable "GlobalEntityCreator" to this instance
nspace["GlobalEntityCreator"] = boost::python::ptr(this);
globals["GlobalEntityCreator"] = this;
}

} // namespace script
25 changes: 13 additions & 12 deletions plugins/script/interfaces/EntityInterface.h
@@ -1,15 +1,14 @@
#ifndef _ENTITY_INTERFACE_H_
#define _ENTITY_INTERFACE_H_
#pragma once

#include <boost/python.hpp>
#include "iscript.h"

#include "ientity.h"

#include "EClassInterface.h"
#include "SceneGraphInterface.h"

namespace script {
namespace script
{

// Visitor object
class EntityVisitor
Expand Down Expand Up @@ -48,13 +47,18 @@ class ScriptEntityNode :

// Wrap around the EntityClassVisitor interface
class EntityVisitorWrapper :
public EntityVisitor,
public boost::python::wrapper<EntityVisitor>
public EntityVisitor
{
public:
void visit(const std::string& key, const std::string& value) {
void visit(const std::string& key, const std::string& value) override
{
// Wrap this method to python
this->get_override("visit")(key, value);
PYBIND11_OVERLOAD_PURE(
void, /* Return type */
EntityVisitor, /* Parent class */
visit, /* Name of function in C++ (must match Python name) */
key, value /* Argument(s) */
);
}
};

Expand All @@ -73,10 +77,7 @@ class EntityInterface :
ScriptSceneNode createEntity(const std::string& eclassName);

// IScriptInterface implementation
void registerInterface(boost::python::object& nspace);
void registerInterface(py::module& scope, py::dict& globals) override;
};
typedef std::shared_ptr<EntityInterface> EntityInterfacePtr;

} // namespace script

#endif /* _ENTITY_INTERFACE_H_ */
5 changes: 5 additions & 0 deletions plugins/script/interfaces/SceneGraphInterface.cpp
Expand Up @@ -7,6 +7,7 @@

#include "ModelInterface.h"
#include "BrushInterface.h"
#include "EntityInterface.h"

namespace script
{
Expand Down Expand Up @@ -143,6 +144,10 @@ void SceneGraphInterface::registerInterface(py::module& scope, py::dict& globals
sceneNode.def("isBrush", &ScriptBrushNode::isBrush);
sceneNode.def("getBrush", &ScriptBrushNode::getBrush);

// Add the "is/get" entity methods
sceneNode.def("isEntity", &ScriptEntityNode::isEntity);
sceneNode.def("getEntity", &ScriptEntityNode::getEntity);

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

0 comments on commit 07d8080

Please sign in to comment.