diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-02-28 14:00:53 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-02-28 14:00:53 (GMT) |
commit | c1ccbef7a59df33e6ff0c9a4609caab7e668ba77 (patch) | |
tree | 23d94e90f346db5d4ecff7afb6a0283fc5fe8eba /src/uscxml/plugins | |
parent | 49c3c43d18c9cce6de305aae77cc8bd839506129 (diff) | |
download | uscxml-c1ccbef7a59df33e6ff0c9a4609caab7e668ba77.zip uscxml-c1ccbef7a59df33e6ff0c9a4609caab7e668ba77.tar.gz uscxml-c1ccbef7a59df33e6ff0c9a4609caab7e668ba77.tar.bz2 |
Prepared everything for FE-Design demo
Diffstat (limited to 'src/uscxml/plugins')
9 files changed, 256 insertions, 73 deletions
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp index dfa8585..d791b9e 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp @@ -320,6 +320,10 @@ v8::Handle<v8::Value> V8DataModel::evalAsValue(const std::string& expr) { exceptionEvent.data.compound["filename"] = Data(filename, Data::VERBATIM); std::string sourceLine(*v8::String::AsciiValue(message->GetSourceLine())); + size_t startpos = sourceLine.find_first_not_of(" \t"); + if(std::string::npos != startpos) // removoe leading white space + sourceLine = sourceLine.substr(startpos); + exceptionEvent.data.compound["sourceline"] = Data(sourceLine, Data::VERBATIM); std::stringstream ssLineNumber; diff --git a/src/uscxml/plugins/element/postpone/PostponeElement.cpp b/src/uscxml/plugins/element/postpone/PostponeElement.cpp index 644cb1d..5dc1c60 100644 --- a/src/uscxml/plugins/element/postpone/PostponeElement.cpp +++ b/src/uscxml/plugins/element/postpone/PostponeElement.cpp @@ -41,11 +41,22 @@ void PostponeElement::enterElement(const Arabica::DOM::Node<std::string>& node) } // when will we refire the event? - if (!HAS_ATTR(node, "until")) { - LOG(ERROR) << "Postpone element requires until attribute "; + std::string until; + try { + if (HAS_ATTR(node, "untilexpr")) { + until = _interpreter->getDataModel().evalAsString(ATTR(node, "untilexpr")); + } else if (HAS_ATTR(node, "until")) { + until = ATTR(node, "until"); + } + } catch (Event e) { + LOG(ERROR) << "Syntax error in postpone element untilexpr:" << std::endl << e << std::endl; + return; + } + + if (until.length() == 0) { + LOG(ERROR) << "Postpone element requires until or untilexpr attribute "; return; } - std::string until = ATTR(node, "until"); Event currEvent = _interpreter->getCurrentEvent(); Resubmitter::postpone(currEvent, until, _interpreter); @@ -63,13 +74,16 @@ void PostponeElement::Resubmitter::onStableConfiguration(Interpreter* interprete std::list<std::pair<std::string, Event> >::iterator eventIter = _postponedEvents.begin(); while(eventIter != _postponedEvents.end()) { try { + LOG(INFO) << "Reevaluating: >> " << eventIter->first << " <<"; if (interpreter->getDataModel().evalAsBool(eventIter->first)) { + LOG(INFO) << " -> is TRUE"; interpreter->receive(eventIter->second, true); _postponedEvents.erase(eventIter); break; } + LOG(INFO) << " -> is FALSE"; } catch (Event e) { - LOG(ERROR) << "Syntax error in until attribute of postpone element:" << std::endl << e << std::endl; + LOG(ERROR) << "Syntax error while evaluating until attribute of postpone element:" << std::endl << e << std::endl; _postponedEvents.erase(eventIter++); continue; } diff --git a/src/uscxml/plugins/element/response/ResponseElement.cpp b/src/uscxml/plugins/element/response/ResponseElement.cpp index 7f1a479..62ebf34 100644 --- a/src/uscxml/plugins/element/response/ResponseElement.cpp +++ b/src/uscxml/plugins/element/response/ResponseElement.cpp @@ -52,28 +52,103 @@ void ResponseElement::enterElement(const Arabica::DOM::Node<std::string>& node) return; } httpReply.status = strTo<int>(statusStr);; - + // extract the content Arabica::XPath::NodeSet<std::string> contents = Interpreter::filterChildElements(_interpreter->getXMLPrefixForNS(getNamespace()) + "content", node); if (contents.size() > 0) { - if (HAS_ATTR(contents[0], "expr")) { + if (HAS_ATTR(contents[0], "expr")) { // -- content is evaluated string from datamodel ------ if (_interpreter->getDataModel()) { try { std::string contentValue = _interpreter->getDataModel().evalAsString(ATTR(contents[0], "expr")); httpReply.content = contentValue; } catch (Event e) { LOG(ERROR) << "Syntax error with expr in content child of response element:" << std::endl << e << std::endl; + return; } } else { LOG(ERROR) << "content element has expr attribute but no datamodel is specified."; + return; + } + } else if (HAS_ATTR(contents[0], "file") || HAS_ATTR(contents[0], "fileexpr")) { // -- content is from file ------ + URL file; + if (HAS_ATTR(contents[0], "fileexpr")) { + if (_interpreter->getDataModel()) { + try { + file = "file://" + _interpreter->getDataModel().evalAsString(ATTR(contents[0], "fileexpr")); + } catch (Event e) { + LOG(ERROR) << "Syntax error with fileexpr in content child of response element:" << std::endl << e << std::endl; + return; + } + } + } else { + file = "file://" + ATTR(contents[0], "fileexpr"); } - } else if (contents[0].hasChildNodes()) { + if (file) { + httpReply.content = file.getInContent(); + size_t lastDot; + if ((lastDot = file.path().find_last_of(".")) != std::string::npos) { + std::string extension = file.path().substr(lastDot + 1); + std::string mimeType = HTTPServer::mimeTypeForExtension(extension); + if (mimeType.length() > 0) { + httpReply.headers["Content-Type"] = mimeType; + } + } + } + } else if (contents[0].hasChildNodes()) { // -- content embedded as child nodes ------ httpReply.content = contents[0].getFirstChild().getNodeValue(); } else { LOG(ERROR) << "content element does not specify any content."; + return; } } + // process headers + Arabica::XPath::NodeSet<std::string> headers = Interpreter::filterChildElements(_interpreter->getXMLPrefixForNS(getNamespace()) + "header", node); + for (int i = 0; i < headers.size(); i++) { + std::string name; + if (HAS_ATTR(headers[i], "name")) { + name = ATTR(headers[i], "name"); + } else if(HAS_ATTR(headers[i], "nameexpr")) { + if (_interpreter->getDataModel()) { + try { + name = _interpreter->getDataModel().evalAsString(ATTR(headers[i], "nameexpr")); + } catch (Event e) { + LOG(ERROR) << "Syntax error with nameexpr in header child of response element:" << std::endl << e << std::endl; + return; + } + } else { + LOG(ERROR) << "header element has nameexpr attribute but no datamodel is specified."; + return; + } + } else { + LOG(ERROR) << "header element has no name or nameexpr attribute."; + return; + } + + std::string value; + if (HAS_ATTR(headers[i], "value")) { + value = ATTR(headers[i], "value"); + } else if(HAS_ATTR(headers[i], "expr")) { + if (_interpreter->getDataModel()) { + try { + value = _interpreter->getDataModel().evalAsString(ATTR(headers[i], "expr")); + } catch (Event e) { + LOG(ERROR) << "Syntax error with expr in header child of response element:" << std::endl << e << std::endl; + return; + } + } else { + LOG(ERROR) << "header element has expr attribute but no datamodel is specified."; + return; + } + } else { + LOG(ERROR) << "header element has no value or expr attribute."; + return; + } + + httpReply.headers[name] = value; + } + + // send the reply HTTPServer::reply(httpReply); servlet->getRequests().erase(requestId); diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.cpp b/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.cpp index e34517d..b7477df 100644 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.cpp +++ b/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.cpp @@ -24,7 +24,11 @@ bool connect(pluma::Host& host) { } #endif -DirMonInvoker::DirMonInvoker() : _reportExisting(false), _recurse(false), _thread(NULL) { +DirMonInvoker::DirMonInvoker() : + _reportExisting(true), + _reportHidden(false), + _recurse(false), + _thread(NULL) { } DirMonInvoker::~DirMonInvoker() { @@ -51,13 +55,31 @@ void DirMonInvoker::cancel(const std::string sendId) { } void DirMonInvoker::invoke(const InvokeRequest& req) { - if (req.params.find("dir") != req.params.end() && boost::iequals(req.params.find("reportexisting")->second, "true")) - _reportExisting = true; + if (req.params.find("dir") != req.params.end() && boost::iequals(req.params.find("reportexisting")->second, "false")) + _reportExisting = false; if (req.params.find("recurse") != req.params.end() && boost::iequals(req.params.find("recurse")->second, "true")) _recurse = true; - if (req.params.find("suffix") != req.params.end()) - _suffix = req.params.find("suffix")->second; - + if (req.params.find("reporthidden") != req.params.end() && boost::iequals(req.params.find("reporthidden")->second, "true")) + _reportHidden = true; + + std::string suffixList; + if (req.params.find("suffix") != req.params.end()) { + suffixList = req.params.find("suffix")->second; + } else if (req.params.find("suffixes") != req.params.end()) { + suffixList = req.params.find("suffixes")->second; + } + + if (suffixList.size() > 0) { + // seperate path into components + std::stringstream ss(suffixList); + std::string item; + while(std::getline(ss, item, ' ')) { + if (item.length() == 0) + continue; + _suffixes.insert(item); + } + } + std::multimap<std::string, std::string>::const_iterator dirIter = req.params.find("dir"); while(dirIter != req.params.upper_bound("dir")) { URL url(dirIter->second); @@ -89,14 +111,20 @@ void DirMonInvoker::reportExisting() { } void DirMonInvoker::handleFileAction(FW::WatchID watchid, const FW::String& dir, const FW::String& filename, FW::Action action) { - if (!boost::algorithm::ends_with(filename, _suffix)) - return; - - struct stat fileStat; - if (stat(filename.c_str(), &fileStat) != 0) { - LOG(ERROR) << "Error with stat on directory entry " << filename << ": " << strerror(errno); - return; - } + + if (_suffixes.size() > 0) { + bool validSuffix = false; + std::set<std::string>::iterator suffixIter = _suffixes.begin(); + while(suffixIter != _suffixes.end()) { + if (boost::algorithm::ends_with(filename, *suffixIter)) { + validSuffix = true; + break; + } + suffixIter++; + } + if (!validSuffix) + return; + } Event event; event.invokeid = _invokeId; @@ -117,39 +145,56 @@ void DirMonInvoker::handleFileAction(FW::WatchID watchid, const FW::String& dir, break; } + // basename is the filename with suffix std::string basename; size_t lastSep; if ((lastSep = filename.find_last_of(PATH_SEPERATOR)) != std::string::npos) { lastSep++; basename = filename.substr(lastSep, filename.length() - lastSep); - } else { - basename = filename; + event.data.compound["file"].compound["name"] = Data(basename, Data::VERBATIM); } - - std::string extension; + + // return if this is a hidden file + if (boost::algorithm::starts_with(basename, ".") && !_reportHidden) + return; + + struct stat fileStat; + if (action != FW::Actions::Delete) { + if (stat(filename.c_str(), &fileStat) != 0) { + LOG(ERROR) << "Error with stat on directory entry " << filename << ": " << strerror(errno); + return; + } else { + event.data.compound["file"].compound["mtime"] = toStr(fileStat.st_mtime); + event.data.compound["file"].compound["ctime"] = toStr(fileStat.st_ctime); + event.data.compound["file"].compound["atime"] = toStr(fileStat.st_atime); + event.data.compound["file"].compound["size"] = toStr(fileStat.st_size); + } + } + + // extension is the suffix and strippedName the basename without the suffix size_t lastDot; if ((lastDot = basename.find_last_of(".")) != std::string::npos) { - lastDot++; - extension = basename.substr(lastDot, basename.length() - lastDot); + std::string extension = basename.substr(lastDot + 1); + event.data.compound["file"].compound["extension"] = Data(extension, Data::VERBATIM); + std::string strippedName = basename.substr(0, lastDot); + event.data.compound["file"].compound["strippedName"] = Data(strippedName, Data::VERBATIM); } - std::string relPath; + // relpath is the path to the file relative to the dir if (boost::algorithm::starts_with(filename, dir)) { - relPath = filename.substr(dir.length()); - } else { - relPath = filename; + std::string relPath = filename.substr(dir.length()); + event.data.compound["file"].compound["relPath"] = Data(relPath, Data::VERBATIM); + + // relDir is the relpath without the basename + if ((lastSep = relPath.find_last_of(PATH_SEPERATOR)) != std::string::npos) { + lastSep++; + std::string relDir = relPath.substr(0, lastSep); + event.data.compound["file"].compound["relDir"] = Data(relDir, Data::VERBATIM); + } } - event.data.compound["file"].compound["name"] = Data(basename, Data::VERBATIM); event.data.compound["file"].compound["path"] = Data(filename, Data::VERBATIM); - event.data.compound["file"].compound["relPath"] = Data(relPath, Data::VERBATIM); event.data.compound["file"].compound["dir"] = Data(dir, Data::VERBATIM); - event.data.compound["file"].compound["extension"] = Data(extension, Data::VERBATIM); - - event.data.compound["file"].compound["mtime"] = toStr(fileStat.st_mtime); - event.data.compound["file"].compound["ctime"] = toStr(fileStat.st_ctime); - event.data.compound["file"].compound["atime"] = toStr(fileStat.st_atime); - event.data.compound["file"].compound["size"] = toStr(fileStat.st_size); returnEvent(event); } diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.h b/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.h index 1437759..04e670d 100644 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.h +++ b/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.h @@ -39,8 +39,9 @@ public: protected: bool _reportExisting; + bool _reportHidden; bool _recurse; - std::string _suffix; + std::set<std::string> _suffixes; bool _isRunning; tthread::thread* _thread; diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.cpp b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.cpp index 726cd08..0337770 100644 --- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.cpp +++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.cpp @@ -3,15 +3,31 @@ #include "uscxml/config.h" #include <osg/MatrixTransform> +#include <osg/Node> +#include <osg/Group> #include <osgDB/ReadFile> #include <osgDB/WriteFile> #include <osgDB/Registry> #include <osgGA/TrackballManipulator> +#include <osg/ShapeDrawable> + +#include <boost/lexical_cast.hpp> #ifdef BUILD_AS_PLUGINS #include <Pluma/Connector.hpp> #endif +#define EVAL_PARAM_EXPR(param, expr, key) \ +if (param.find(key) == param.end() && param.find(expr) != param.end() && _interpreter->getDataModel()) \ + param.insert(std::make_pair(key, _interpreter->getDataModel().evalAsString(param.find(expr)->second))); + +#define CAST_PARAM(param, var, key, type) \ +if (param.find(key) != param.end()) { \ + try { var = boost::lexical_cast<type>(param.find(key)->second); } \ + catch(...) { LOG(ERROR) << "Attribute " key " of sendrequest to osgconverter is of invalid format: " << param.find(key)->second; } \ +} + + namespace uscxml { #ifdef BUILD_AS_PLUGINS @@ -23,6 +39,7 @@ bool connect(pluma::Host& host) { #endif OSGConverter::OSGConverter() : _isRunning(false) { +// osg::setNotifyLevel(osg::DEBUG_FP); } OSGConverter::~OSGConverter() { @@ -94,20 +111,14 @@ void OSGConverter::send(const SendRequest& req) { } } - if (actualReq.params.find("height") == actualReq.params.end()) { - // no explicit height - if (actualReq.params.find("heightexpr") != actualReq.params.end() && _interpreter->getDataModel()) { - actualReq.params.insert(std::make_pair("height", _interpreter->getDataModel().evalAsString(actualReq.params.find("heightexpr")->second))); - } - } - - if (actualReq.params.find("width") == actualReq.params.end()) { - // no explicit width - if (actualReq.params.find("widthexpr") != actualReq.params.end() && _interpreter->getDataModel()) { - actualReq.params.insert(std::make_pair("width", _interpreter->getDataModel().evalAsString(actualReq.params.find("widthexpr")->second))); - } - } + EVAL_PARAM_EXPR(actualReq.params, "heightexpr", "height"); + EVAL_PARAM_EXPR(actualReq.params, "widthexpr", "width"); + EVAL_PARAM_EXPR(actualReq.params, "pitchexpr", "pitch"); + EVAL_PARAM_EXPR(actualReq.params, "rollexpr", "roll"); + EVAL_PARAM_EXPR(actualReq.params, "yawexpr", "yaw"); + EVAL_PARAM_EXPR(actualReq.params, "zoomexpr", "zoom"); +// process(actualReq); _workQueue.push(actualReq); } @@ -139,9 +150,13 @@ void OSGConverter::run(void* instance) { } void OSGConverter::process(const SendRequest& req) { - - int width = (req.params.find("width") != req.params.end() ? strTo<int>(req.params.find("width")->second) : 640); - int height = (req.params.find("height") != req.params.end() ? strTo<int>(req.params.find("height")->second) : 480); + +// std::cout << req; + + int width = 640; + int height = 480; + CAST_PARAM(req.params, width, "width", int); + CAST_PARAM(req.params, height, "height", int); assert(req.params.find("source") != req.params.end()); assert(req.params.find("dest") != req.params.end()); @@ -191,10 +206,10 @@ void OSGConverter::process(const SendRequest& req) { viewer.getCamera()->setClearColor(osg::Vec4f(1.0f,1.0f,1.0f,1.0f)); viewer.getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - ((osg::MatrixTransform*)sceneGraph.get())->setMatrix(requestToModelPose(req)); - viewer.getCamera()->setViewMatrix(requestToCamPose(req)); +// viewer.getCamera()->setViewMatrix(requestToCamPose(req)); -// viewer.home(); + viewer.home(); + ((osg::MatrixTransform*)sceneGraph.get())->setMatrix(requestToModelPose(req)); // perform one viewer iteration viewer.realize(); @@ -202,19 +217,32 @@ void OSGConverter::process(const SendRequest& req) { } } -osg::Matrix OSGConverter::requestToModelPose(const SendRequest& req) { - double pitch = (req.params.find("pitch") != req.params.end() ? strTo<int>(req.params.find("pitch")->second) : 0); - double roll = (req.params.find("roll") != req.params.end() ? strTo<int>(req.params.find("roll")->second) : 0); - double yaw = (req.params.find("yaw") != req.params.end() ? strTo<int>(req.params.find("yaw")->second) : 0); - - return eulerToMatrix(pitch, roll, yaw); -// osg::Matrix m; -// m.makeIdentity(); -// return m; +osg::Matrix OSGConverter::requestToModelPose(const SendRequest& req) { + double pitch = 0; + double roll = 0; + double yaw = 0; + double zoom = 1; + CAST_PARAM(req.params, pitch, "pitch", double); + CAST_PARAM(req.params, roll, "roll", double); + CAST_PARAM(req.params, yaw, "yaw", double); + CAST_PARAM(req.params, zoom, "zoom", double); + + osg::Matrix m = osg::Matrix::scale(zoom, zoom, zoom) * eulerToMatrix(pitch, roll, yaw); + +#if 0 + dumpMatrix(m); +#endif + return m; } osg::Matrix OSGConverter::requestToCamPose(const SendRequest& req) { - return eulerToMatrix(0, 0, 0); +// double zoom = 1; +// CAST_PARAM(req.params, zoom, "zoom", double); +// osg::Matrix scale = osg::Matrix::scale(zoom, zoom, zoom); +// return scale; + osg::Matrix identity; + identity.makeIdentity(); + return identity; } osg::ref_ptr<osg::Node> OSGConverter::setupGraph(const std::string filename) { @@ -240,7 +268,9 @@ osg::ref_ptr<osg::Node> OSGConverter::setupGraph(const std::string filename) { } _models[filename] = std::make_pair(now, model); } + _models[filename].first = now; +#if 1 // remove old models from cache std::map<std::string, std::pair<long, osg::ref_ptr<osg::Node> > >::iterator modelIter = _models.begin(); while(modelIter != _models.end()) { @@ -251,12 +281,13 @@ osg::ref_ptr<osg::Node> OSGConverter::setupGraph(const std::string filename) { modelIter++; } } - } +#endif + } + osg::ref_ptr<osg::MatrixTransform> root = new osg::MatrixTransform(); osg::ref_ptr<osg::Node> model = _models[filename].second; - _models[filename].first = now; // translation matrix to move model into center osg::ref_ptr<osg::MatrixTransform> modelCenter = new osg::MatrixTransform(); @@ -268,7 +299,7 @@ osg::ref_ptr<osg::Node> OSGConverter::setupGraph(const std::string filename) { // add to model pose matrix root->addChild(modelCenter); - + return root; } @@ -299,7 +330,7 @@ osg::Matrix OSGConverter::eulerToMatrix(double pitch, double roll, double yaw) { m(0,3) = m(1,3) = m(2,3) = m(3,0) = m(3,1) = m(3,2) = 0; m(3,3) = 1; - + return m; } @@ -331,6 +362,15 @@ void OSGConverter::matrixToEuler(const osg::Matrix& m, double& pitch, double& ro yaw = fmod( angle_z, 2 * M_PI ); } +void OSGConverter::dumpMatrix(const osg::Matrix& m) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + std::cout << ", " << m(i, j); + } + std::cout << std::endl; + } +} + void OSGConverter::NameRespectingWriteToFile::operator()(const osg::Image& image, const unsigned int context_id) { osgDB::writeImageFile(image, _filename); } diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.h b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.h index e96a4e9..67b0da6 100644 --- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.h +++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.h @@ -34,6 +34,7 @@ public: osg::Matrix requestToModelPose(const SendRequest& req); osg::Matrix requestToCamPose(const SendRequest& req); + static void dumpMatrix(const osg::Matrix& m); static osg::Matrix eulerToMatrix(double pitch, double roll, double yaw); static void matrixToEuler(const osg::Matrix& m, double& pitch, double& roll, double& yaw); diff --git a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp index f89c1b0..16947a7 100644 --- a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp +++ b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp @@ -41,6 +41,7 @@ void HeartbeatInvoker::cancel(const std::string sendId) { } void HeartbeatInvoker::invoke(const InvokeRequest& req) { + _invokeId = req.invokeid; _event.invokeid = _invokeId; std::string intervalStr; double interval = 0; diff --git a/src/uscxml/plugins/invoker/http/HTTPServletInvoker.cpp b/src/uscxml/plugins/invoker/http/HTTPServletInvoker.cpp index 753877c..a3556c2 100644 --- a/src/uscxml/plugins/invoker/http/HTTPServletInvoker.cpp +++ b/src/uscxml/plugins/invoker/http/HTTPServletInvoker.cpp @@ -1,6 +1,8 @@ #include "HTTPServletInvoker.h" #include <glog/logging.h> +#include "uscxml/config.h" + #ifdef BUILD_AS_PLUGINS #include <Pluma/Connector.hpp> #endif |