summaryrefslogtreecommitdiffstats
path: root/src/uscxml/plugins/invoker
diff options
context:
space:
mode:
Diffstat (limited to 'src/uscxml/plugins/invoker')
-rw-r--r--src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp74
-rw-r--r--src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h19
-rw-r--r--src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp95
-rw-r--r--src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.h54
-rw-r--r--src/uscxml/plugins/invoker/sample/SampleInvoker.cpp1
-rw-r--r--src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp81
-rw-r--r--src/uscxml/plugins/invoker/umundo/UmundoInvoker.h11
7 files changed, 286 insertions, 49 deletions
diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp
index 2712be3..7a0e63a 100644
--- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp
+++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp
@@ -45,6 +45,13 @@ void OSGInvoker::sendToParent(SendRequest& req) {
void OSGInvoker::invoke(InvokeRequest& req) {
tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
+ // register default event handlers
+ Arabica::DOM::Events::EventTarget<std::string> evTarget = Arabica::DOM::Events::EventTarget<std::string>(req.dom);
+ evTarget.addEventListener("DOMSubtreeModified", *this, false);
+ evTarget.addEventListener("DOMNodeInserted", *this, false);
+ evTarget.addEventListener("DOMNodeRemoved", *this, false);
+ evTarget.addEventListener("DOMAttrModified", *this, false);
+
Arabica::XPath::NodeSet<std::string> content = Interpreter::filterChildElements("content", req.dom);
std::set<std::string> validChilds;
@@ -62,7 +69,19 @@ void OSGInvoker::runOnMainThread() {
_mutex.unlock();
}
}
-
+
+void OSGInvoker::handleEvent(Arabica::DOM::Events::Event<std::string>& event) {
+// std::cout << "Handling Event!" << std::endl;
+ Arabica::DOM::Node<std::string> node(event.getTarget());
+ if (_nodes.find(node) != _nodes.end()) {
+ osg::Node* osgNode = _nodes[node];
+ if (false) {
+ } else if (boost::iequals(LOCALNAME(node), "rotation")) {
+ updateRotation(osgNode, event);
+ }
+ }
+}
+
void OSGInvoker::processDisplay(const Arabica::DOM::Node<std::string>& element) {
// std::cout << element << std::endl;
@@ -108,13 +127,17 @@ void OSGInvoker::processViewport(const Arabica::DOM::Node<std::string>& element)
compDisp->addView(name, viewPort, sceneView);
std::set<std::string> validChilds;
+ validChilds.insert("camera");
validChilds.insert("translation");
validChilds.insert("rotation");
validChilds.insert("scale");
validChilds.insert("node");
- processChildren(validChilds, element);
+ processChildren(validChilds, element);
}
+void OSGInvoker::processCamera(const Arabica::DOM::Node<std::string>& element) {}
+void OSGInvoker::updateCamera(osg::Node* node, Arabica::DOM::Events::Event<std::string>& event) {}
+
void OSGInvoker::processTranslation(const Arabica::DOM::Node<std::string>& element) {
assert(_nodes.find(element.getParentNode()) != _nodes.end());
osg::Node* node = _nodes[element.getParentNode()];
@@ -146,7 +169,31 @@ void OSGInvoker::processTranslation(const Arabica::DOM::Node<std::string>& eleme
void OSGInvoker::processRotation(const Arabica::DOM::Node<std::string>& element) {
assert(_nodes.find(element.getParentNode()) != _nodes.end());
osg::Node* node = _nodes[element.getParentNode()];
-
+
+ osg::Matrix rotation = rotationFromElement(element);
+ osg::MatrixTransform* transform = new osg::MatrixTransform();
+ transform->setMatrix(rotation);
+ node->asGroup()->addChild(transform);
+ _nodes[element] = transform;
+
+ std::set<std::string> validChilds;
+ validChilds.insert("translation");
+ validChilds.insert("rotation");
+ validChilds.insert("scale");
+ validChilds.insert("node");
+ processChildren(validChilds, element);
+}
+
+void OSGInvoker::updateRotation(osg::Node* node, Arabica::DOM::Events::Event<std::string>& event) {
+ osg::MatrixTransform* transform = static_cast<osg::MatrixTransform*>(node);
+ if (false) {
+ } else if (boost::iequals(event.getType(), "DOMAttrModified")) {
+ osg::Matrix rotation = rotationFromElement(Arabica::DOM::Node<std::string>(event.getTarget()));
+ transform->setMatrix(rotation);
+ }
+}
+
+osg::Matrix OSGInvoker::rotationFromElement(const Arabica::DOM::Node<std::string>& element) {
double pitch = 0, roll = 0, yaw = 0;
if (HAS_ATTR(element, "pitch")) {
NumAttr pitchAttr = NumAttr(ATTR(element, "pitch"));
@@ -178,24 +225,13 @@ void OSGInvoker::processRotation(const Arabica::DOM::Node<std::string>& element)
yaw = strTo<float>(yawAttr.value);
}
}
-
+
osg::Matrix rotation;
rotation.makeRotate(roll, osg::Vec3(0,1,0), // roll
pitch, osg::Vec3(1,0,0) , // pitch
yaw, osg::Vec3(0,0,1) ); // heading
-
- osg::MatrixTransform* transform = new osg::MatrixTransform();
- transform->setMatrix(rotation);
- node->asGroup()->addChild(transform);
- _nodes[element] = transform;
-
- std::set<std::string> validChilds;
- validChilds.insert("translation");
- validChilds.insert("rotation");
- validChilds.insert("scale");
- validChilds.insert("node");
- processChildren(validChilds, element);
+ return rotation;
}
void OSGInvoker::processScale(const Arabica::DOM::Node<std::string>& element) {
@@ -227,6 +263,9 @@ void OSGInvoker::processScale(const Arabica::DOM::Node<std::string>& element) {
}
void OSGInvoker::processNode(const Arabica::DOM::Node<std::string>& element) {
+ _nodes_t::iterator nodeIter = _nodes.find(element.getParentNode());
+ assert(nodeIter != _nodes.end());
+
assert(_nodes.find(element.getParentNode()) != _nodes.end());
osg::Node* parent = _nodes[element.getParentNode()];
@@ -276,6 +315,9 @@ void OSGInvoker::processChildren(const std::set<std::string>& validChildren, con
} else if (boost::iequals(LOCALNAME(childs.item(i)), "viewport") &&
validChildren.find("viewport") != validChildren.end()) {
processViewport(childs.item(i));
+ } else if (boost::iequals(LOCALNAME(childs.item(i)), "camera") &&
+ validChildren.find("camera") != validChildren.end()) {
+ processCamera(childs.item(i));
} else if (boost::iequals(LOCALNAME(childs.item(i)), "display") &&
validChildren.find("display") != validChildren.end()) {
processDisplay(childs.item(i));
diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h
index cf1556e..90dda31 100644
--- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h
+++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h
@@ -2,6 +2,9 @@
#define OSGINVOKER_H_H6T4R8HU
#include <uscxml/Interpreter.h>
+#include <DOM/Events/MutationEvent.hpp>
+#include <DOM/Events/EventListener.hpp>
+#include <DOM/Events/Event.hpp>
#include "CompositeDisplay.h"
#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
@@ -13,7 +16,7 @@
namespace uscxml {
-class OSGInvoker : public Invoker {
+class OSGInvoker : public Invoker, public Arabica::DOM::Events::EventListener<std::string> {
public:
OSGInvoker();
virtual ~OSGInvoker();
@@ -32,16 +35,30 @@ public:
virtual void cancel(const std::string sendId);
virtual void invoke(InvokeRequest& req);
virtual void sendToParent(SendRequest& req);
+ virtual void handleEvent(Arabica::DOM::Events::Event<std::string>& event);
virtual void runOnMainThread();
protected:
void processDisplay(const Arabica::DOM::Node<std::string>& element);
+ void updateDisplay(osg::Node* node, Arabica::DOM::Events::Event<std::string>& event);
void processViewport(const Arabica::DOM::Node<std::string>& element);
+ void updateViewport(osg::Node* node, Arabica::DOM::Events::Event<std::string>& event);
+ void processCamera(const Arabica::DOM::Node<std::string>& element);
+ void updateCamera(osg::Node* node, Arabica::DOM::Events::Event<std::string>& event);
+
void processTranslation(const Arabica::DOM::Node<std::string>& element);
+ void updateTranslation(osg::Node* node, Arabica::DOM::Events::Event<std::string>& event);
+
void processRotation(const Arabica::DOM::Node<std::string>& element);
+ void updateRotation(osg::Node* node, Arabica::DOM::Events::Event<std::string>& event);
+ static osg::Matrix rotationFromElement(const Arabica::DOM::Node<std::string>& element);
+
void processScale(const Arabica::DOM::Node<std::string>& element);
+ void updateScale(osg::Node* node, Arabica::DOM::Events::Event<std::string>& event);
void processNode(const Arabica::DOM::Node<std::string>& element);
+ void updateNode(osg::Node* node, Arabica::DOM::Events::Event<std::string>& event);
+
void processChildren(const std::set<std::string>& validChildren, const Arabica::DOM::Node<std::string>& element);
void getViewport(const Arabica::DOM::Node<std::string>& element,
diff --git a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp
new file mode 100644
index 0000000..6bc06d9
--- /dev/null
+++ b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp
@@ -0,0 +1,95 @@
+#include "HeartbeatInvoker.h"
+#include <glog/logging.h>
+
+#ifdef BUILD_AS_PLUGINS
+#include <Pluma/Connector.hpp>
+#endif
+
+namespace uscxml {
+
+#ifdef BUILD_AS_PLUGINS
+PLUMA_CONNECTOR
+bool connect(pluma::Host& host) {
+ host.add( new HeartbeatInvokerProvider() );
+ return true;
+}
+#endif
+
+HeartbeatInvoker::HeartbeatInvoker() {
+}
+
+HeartbeatInvoker::~HeartbeatInvoker() {
+};
+
+Invoker* HeartbeatInvoker::create(Interpreter* interpreter) {
+ HeartbeatInvoker* invoker = new HeartbeatInvoker();
+ invoker->_interpreter = interpreter;
+ return invoker;
+}
+
+Data HeartbeatInvoker::getDataModelVariables() {
+ Data data;
+ return data;
+}
+
+void HeartbeatInvoker::send(SendRequest& req) {
+}
+
+void HeartbeatInvoker::cancel(const std::string sendId) {
+ HeartbeatDispatcher::getInstance()->cancelEvent(toStr(this));
+}
+
+void HeartbeatInvoker::sendToParent(SendRequest& req) {
+}
+
+void HeartbeatInvoker::invoke(InvokeRequest& req) {
+ _invokeId = req.invokeid;
+ _event.invokeid = _invokeId;
+ std::string intervalStr;
+ double interval = 0;
+ unsigned long intervalMs = 0;
+ InvokeRequest::params_t::iterator paramIter = req.params.begin();
+ while(paramIter != req.params.end()) {
+ if (boost::iequals(paramIter->first, "interval")) {
+ intervalStr = paramIter->second;
+ NumAttr intervalAttr(paramIter->second);
+ interval = strTo<double>(intervalAttr.value);
+ if (false) {
+ } else if (boost::iequals(intervalAttr.unit, "s")) {
+ intervalMs = interval * 1000;
+ } else if (boost::iequals(intervalAttr.unit, "ms")) {
+ intervalMs = interval;
+ } else {
+ intervalMs = interval;
+ }
+ }
+ if (boost::iequals(paramIter->first, "eventname")) {
+ _event.name = paramIter->second;
+ }
+ paramIter++;
+ }
+ if (_event.name.length() == 0)
+ _event.name = std::string("heartbeat." + intervalStr);
+
+ if (intervalMs > 0) {
+ HeartbeatDispatcher::getInstance()->addEvent(toStr(this), HeartbeatInvoker::dispatch, intervalMs, this, true);
+ }
+}
+
+void HeartbeatInvoker::dispatch(void* instance, std::string name) {
+ HeartbeatInvoker* invoker = (HeartbeatInvoker*)instance;
+ invoker->_interpreter->receive(invoker->_event);
+}
+
+HeartbeatDispatcher* HeartbeatDispatcher::_instance = NULL;
+HeartbeatDispatcher* HeartbeatDispatcher::getInstance() {
+ if (_instance == NULL) {
+ _instance = new HeartbeatDispatcher();
+ _instance->start();
+ }
+ return _instance;
+}
+
+HeartbeatDispatcher::HeartbeatDispatcher() {}
+
+} \ No newline at end of file
diff --git a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.h b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.h
new file mode 100644
index 0000000..9a6cb47
--- /dev/null
+++ b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.h
@@ -0,0 +1,54 @@
+#ifndef HEARTBEATINVOKER_H_W09J90F0
+#define HEARTBEATINVOKER_H_W09J90F0
+
+#include <uscxml/Interpreter.h>
+
+#ifdef BUILD_AS_PLUGINS
+#include "uscxml/plugins/Plugins.h"
+#endif
+
+namespace uscxml {
+
+class HeartbeatInvoker : public Invoker {
+public:
+ HeartbeatInvoker();
+ virtual ~HeartbeatInvoker();
+ virtual Invoker* create(Interpreter* interpreter);
+
+ virtual std::set<std::string> getNames() {
+ std::set<std::string> names;
+ names.insert("heartbeat");
+ names.insert("http://uscxml.tk.informatik.tu-darmstadt.de/#heartbaet");
+ return names;
+ }
+
+ virtual Data getDataModelVariables();
+ virtual void send(SendRequest& req);
+ virtual void cancel(const std::string sendId);
+ virtual void invoke(InvokeRequest& req);
+ virtual void sendToParent(SendRequest& req);
+
+ static void dispatch(void* instance, std::string name);
+
+protected:
+ std::string _invokeId;
+ Event _event;
+
+};
+
+class HeartbeatDispatcher : public DelayedEventQueue {
+public:
+ static HeartbeatDispatcher* getInstance();
+protected:
+ static HeartbeatDispatcher* _instance;
+ HeartbeatDispatcher();
+};
+
+#ifdef BUILD_AS_PLUGINS
+PLUMA_INHERIT_PROVIDER(HeartbeatInvoker, Invoker);
+#endif
+
+}
+
+
+#endif /* end of include guard: HEARTBEATINVOKER_H_W09J90F0 */
diff --git a/src/uscxml/plugins/invoker/sample/SampleInvoker.cpp b/src/uscxml/plugins/invoker/sample/SampleInvoker.cpp
index b5c351c..f115c25 100644
--- a/src/uscxml/plugins/invoker/sample/SampleInvoker.cpp
+++ b/src/uscxml/plugins/invoker/sample/SampleInvoker.cpp
@@ -42,6 +42,7 @@ void SampleInvoker::sendToParent(SendRequest& req) {
}
void SampleInvoker::invoke(InvokeRequest& req) {
+ _invokeId = req.invokeid;
}
} \ No newline at end of file
diff --git a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp
index ee6c903..9957bfa 100644
--- a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp
+++ b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp
@@ -1,5 +1,6 @@
#include "UmundoInvoker.h"
#include <glog/logging.h>
+#include "uscxml/URL.h"
#ifdef BUILD_AS_PLUGINS
#include <Pluma/Connector.hpp>
@@ -15,12 +16,16 @@ bool connect(pluma::Host& host) {
}
#endif
-UmundoInvoker::UmundoInvoker() {
+UmundoInvoker::UmundoInvoker() : _node(NULL), _pub(NULL), _sub(NULL) {
}
UmundoInvoker::~UmundoInvoker() {
- _node.removeSubscriber(_sub);
- _node.removePublisher(_pub);
+ if (_node) {
+ if (_sub)
+ _node->removeSubscriber(*_sub);
+ if (_pub)
+ _node->removePublisher(*_pub);
+ }
};
Invoker* UmundoInvoker::create(Interpreter* interpreter) {
@@ -63,8 +68,8 @@ void UmundoInvoker::send(SendRequest& req) {
} else {
// add all s11n properties
if (!_isService) {
- _pub.prepareMsg(msg, type, pbMsg);
- _pub.send(msg);
+ _pub->prepareMsg(msg, type, pbMsg);
+ _pub->send(msg);
} else {
std::map<umundo::ServiceDescription, umundo::ServiceStub*>::iterator svcIter = _svcs.begin();
while(svcIter != _svcs.end()) {
@@ -107,11 +112,12 @@ void UmundoInvoker::sendToParent(SendRequest& req) {
void UmundoInvoker::invoke(InvokeRequest& req) {
_invokeId = req.invokeid;
+ std::string domain;
std::string channelName;
std::string serviceName;
if (req.params.find("channel") != req.params.end()) {
- channelName = req.params.find("type")->second;
+ channelName = req.params.find("channel")->second;
_isService = false;
} else if (req.params.find("service") != req.params.end()) {
serviceName = req.params.find("service")->second;
@@ -120,34 +126,50 @@ void UmundoInvoker::invoke(InvokeRequest& req) {
LOG(ERROR) << "Invoking umundo needs a service or a channel param";
return;
}
+ if (req.params.find("domain") != req.params.end()) {
+ domain = req.params.find("domain")->second;
+ }
+ _node = getNode(_interpreter, domain);
- _node = getNode(_interpreter);
-
- // add types from .proto or .desc files
- if (req.params.find("types") != req.params.end()) {
+ // add type from .proto or .desc files
+ if (req.params.find("type") != req.params.end()) {
std::pair<InvokeRequest::params_t::iterator, InvokeRequest::params_t::iterator> typeRange = req.params.equal_range("types");
for (InvokeRequest::params_t::iterator it = typeRange.first; it != typeRange.second; it++) {
- Arabica::io::URI srcURI(it->first);
- // if (!_interpreter->makeAbsolute(srcURI)) {
- // LOG(ERROR) << "Relative URI for types in umundo invoker " << *typeIter << " with no base URI set for interpreter";
- // return;
- // }
- umundo::PBSerializer::addProto(srcURI.path());
+ URL typeURI(it->second);
+ if (typeURI.toAbsolute(_interpreter->getBaseURI())) {
+ std::string filename = typeURI.asLocalFile(".proto");
+ umundo::PBSerializer::addProto(filename);
+ } else {
+ LOG(ERROR) << "umundo invoker has relative type src but nor baseURI set with interpreter.";
+ }
}
}
+ // add directory with .proto or .desc files
+ if (req.params.find("types") != req.params.end()) {
+ std::pair<InvokeRequest::params_t::iterator, InvokeRequest::params_t::iterator> typeRange = req.params.equal_range("types");
+ for (InvokeRequest::params_t::iterator it = typeRange.first; it != typeRange.second; it++) {
+ URL typeURI(it->second);
+ if (typeURI.toAbsolute(_interpreter->getBaseURI()) && typeURI.scheme().compare("file") == 0) {
+ umundo::PBSerializer::addProto(typeURI.path());
+ } else {
+ LOG(ERROR) << "invoke element has relative src URI with no baseURI set.";
+ }
+ }
+ }
+
if (!_isService) {
// use umundo to publish objects on a channel
- _pub = umundo::TypedPublisher(channelName);
- _sub = umundo::TypedSubscriber(channelName, this);
+ _pub = new umundo::TypedPublisher(channelName);
+ _sub = new umundo::TypedSubscriber(channelName, this);
- _node.addPublisher(_pub);
- _node.addSubscriber(_sub);
+ _node->addPublisher(*_pub);
+ _node->addSubscriber(*_sub);
} else if (serviceName.length() > 0) {
// use umundo to access services
_svcFilter = umundo::ServiceFilter(serviceName);
- _node.connect(&_svcMgr);
+ _node->connect(&_svcMgr);
_svcMgr.startQuery(_svcFilter, this);
}
}
@@ -233,12 +255,17 @@ void UmundoInvoker::removed(umundo::ServiceDescription desc) {
void UmundoInvoker::changed(umundo::ServiceDescription desc) {
}
-std::map<std::string, umundo::Node> UmundoInvoker::_nodes;
-umundo::Node UmundoInvoker::getNode(Interpreter* interpreter) {
- if ((_nodes.find(interpreter->getName()) == _nodes.end())) {
- _nodes[interpreter->getName()] = umundo::Node();
- }
- return _nodes[interpreter->getName()];
+std::multimap<std::string, std::pair<std::string, umundo::Node*> > UmundoInvoker::_nodes;
+umundo::Node* UmundoInvoker::getNode(Interpreter* interpreter, const std::string& domain) {
+ std::pair<_nodes_t::iterator, _nodes_t::iterator> range = _nodes.equal_range(interpreter->getName());
+ for (_nodes_t::iterator it = range.first; it != range.second; it++) {
+ if (it->second.first.compare(domain) == 0)
+ return it->second.second;
+ }
+ umundo::Node* node = new umundo::Node(domain);
+ std::pair<std::string, std::pair<std::string, umundo::Node*> > pair = std::make_pair(interpreter->getName(), std::make_pair(domain, node));
+ _nodes.insert(pair);
+ return node;
}
bool UmundoInvoker::protobufToData(Data& data, const google::protobuf::Message& msg) {
diff --git a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h
index 72fcc9b..09d07bf 100644
--- a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h
+++ b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h
@@ -49,16 +49,17 @@ protected:
bool dataToProtobuf(google::protobuf::Message* msg, Data& data);
bool protobufToData(Data& data, const google::protobuf::Message& msg);
- umundo::TypedPublisher _pub;
- umundo::TypedSubscriber _sub;
- umundo::Node _node;
+ umundo::Node* _node;
+ umundo::TypedPublisher* _pub;
+ umundo::TypedSubscriber* _sub;
umundo::ServiceFilter _svcFilter;
umundo::ServiceManager _svcMgr;
std::map<umundo::ServiceDescription, umundo::ServiceStub*> _svcs;
- static std::map<std::string, umundo::Node> _nodes;
- static umundo::Node getNode(Interpreter* interpreter);
+ static std::multimap<std::string, std::pair<std::string, umundo::Node*> > _nodes;
+ typedef std::multimap<std::string, std::pair<std::string, umundo::Node*> > _nodes_t;
+ static umundo::Node* getNode(Interpreter* interpreter, const std::string& domain);
};
#ifdef BUILD_AS_PLUGINS