From 9a70ea561fecf533451f08ee3a490e2a5ba21372 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Mon, 22 May 2017 21:17:48 +0200 Subject: Fixed issue 135 custom executable content --- contrib/src/uscxml/CustomExecutableContent.cpp | 20 ++++++++ contrib/src/uscxml/CustomExecutableContent.h | 48 ++++++++++++++++++ src/uscxml/interpreter/BasicContentExecutor.cpp | 17 +++++++ src/uscxml/interpreter/BasicContentExecutor.h | 2 + src/uscxml/interpreter/ContentExecutorImpl.h | 3 ++ src/uscxml/interpreter/InterpreterImpl.h | 6 +++ src/uscxml/plugins/ExecutableContentImpl.h | 4 +- test/CMakeLists.txt | 9 +++- test/src/test-extensions.cpp | 67 ++++++++++++++++++++++++- 9 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 contrib/src/uscxml/CustomExecutableContent.cpp create mode 100644 contrib/src/uscxml/CustomExecutableContent.h diff --git a/contrib/src/uscxml/CustomExecutableContent.cpp b/contrib/src/uscxml/CustomExecutableContent.cpp new file mode 100644 index 0000000..d97bdfe --- /dev/null +++ b/contrib/src/uscxml/CustomExecutableContent.cpp @@ -0,0 +1,20 @@ +/** + * @file + * @author 2017 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see . + * @endcond + */ + +#include "CustomExecutableContent.h" \ No newline at end of file diff --git a/contrib/src/uscxml/CustomExecutableContent.h b/contrib/src/uscxml/CustomExecutableContent.h new file mode 100644 index 0000000..b153605 --- /dev/null +++ b/contrib/src/uscxml/CustomExecutableContent.h @@ -0,0 +1,48 @@ +/** + * @file + * @author 2017 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see . + * @endcond + */ + +#ifndef CUSTOMEXECUTABLECONTENT_H_346FEA6 +#define CUSTOMEXECUTABLECONTENT_H_346FEA6 + +#include + +#include "uscxml/plugins/ExecutableContentImpl.h" + +class CustomExecutableContent : public uscxml::ExecutableContentImpl { +public: + ~CustomExecutableContent() {}; + virtual std::shared_ptr create(uscxml::InterpreterImpl* interpreter) { + return std::shared_ptr(new CustomExecutableContent()); + } + + virtual std::string getLocalName() { return "custom"; } + + virtual void enterElement(XERCESC_NS::DOMElement* node) { + std::cout << "Entering custom element" << std::endl; + } + virtual void exitElement(XERCESC_NS::DOMElement* node) { + std::cout << "Exiting custom element" << std::endl; + } + +protected: + uscxml::InterpreterImpl* _interpreter; +}; + + +#endif /* end of include guard: CUSTOMEXECUTABLECONTENT_H_346FEA6 */ diff --git a/src/uscxml/interpreter/BasicContentExecutor.cpp b/src/uscxml/interpreter/BasicContentExecutor.cpp index 696b575..8d278ec 100644 --- a/src/uscxml/interpreter/BasicContentExecutor.cpp +++ b/src/uscxml/interpreter/BasicContentExecutor.cpp @@ -369,6 +369,23 @@ void BasicContentExecutor::process(XERCESC_NS::DOMElement* block) { processLog(block); } else if (iequals(tagName, xmlPrefix + "script")) { processScript(block); + } else if (Factory::getInstance()->hasExecutableContent(LOCALNAME(block), X(block->getNamespaceURI()))) { + // custom executable content, ask the factory about it! + if (_customExecContent.find(block) == _customExecContent.end()) { + _customExecContent[block] = _callbacks->createExecutableContent(LOCALNAME(block), X(block->getNamespaceURI())); + } + _customExecContent[block].enterElement(block); + + // process custom element's children? + if (_customExecContent[block].processChildren()) { + std::list childElems = DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, block, false); + if(childElems.size() > 0) { + for(auto elemIter = childElems.begin(); elemIter != childElems.end(); elemIter++) { + process(static_cast(*elemIter)); + } + } + } + _customExecContent[block].exitElement(block); } else { LOG(_callbacks->getLogger(), USCXML_ERROR) << tagName << std::endl; assert(false); diff --git a/src/uscxml/interpreter/BasicContentExecutor.h b/src/uscxml/interpreter/BasicContentExecutor.h index 9019b23..469c28e 100644 --- a/src/uscxml/interpreter/BasicContentExecutor.h +++ b/src/uscxml/interpreter/BasicContentExecutor.h @@ -21,6 +21,7 @@ #define BASICCONTENTEXECUTOR_H_B873199D #include "ContentExecutorImpl.h" +#include "uscxml/plugins/ExecutableContent.h" namespace uscxml { @@ -58,6 +59,7 @@ protected: void processNameLists(std::map& nameMap, XERCESC_NS::DOMElement* element); void processParams(std::multimap& paramMap, XERCESC_NS::DOMElement* element); + std::map _customExecContent; }; } diff --git a/src/uscxml/interpreter/ContentExecutorImpl.h b/src/uscxml/interpreter/ContentExecutorImpl.h index 5b39108..d837273 100644 --- a/src/uscxml/interpreter/ContentExecutorImpl.h +++ b/src/uscxml/interpreter/ContentExecutorImpl.h @@ -25,6 +25,7 @@ #include "uscxml/messages/Event.h" #include "uscxml/interpreter/InterpreterMonitor.h" #include "uscxml/interpreter/Logging.h" +#include "uscxml/plugins/ExecutableContent.h" #include #include @@ -78,6 +79,8 @@ public: virtual Interpreter getInterpreter() = 0; virtual Logger getLogger() = 0; + virtual ExecutableContent createExecutableContent(const std::string& localName, const std::string& nameSpace) = 0; + }; /** diff --git a/src/uscxml/interpreter/InterpreterImpl.h b/src/uscxml/interpreter/InterpreterImpl.h index fd6d393..42d61f2 100644 --- a/src/uscxml/interpreter/InterpreterImpl.h +++ b/src/uscxml/interpreter/InterpreterImpl.h @@ -33,6 +33,7 @@ #include "uscxml/plugins/DataModelImpl.h" #include "uscxml/plugins/IOProcessorImpl.h" #include "uscxml/plugins/InvokerImpl.h" +#include "uscxml/plugins/ExecutableContent.h" #include "uscxml/interpreter/MicroStepImpl.h" #include "uscxml/interpreter/ContentExecutorImpl.h" #include "uscxml/interpreter/EventQueue.h" @@ -213,6 +214,11 @@ public: return _currEvent; } + virtual ExecutableContent createExecutableContent(const std::string& localName, const std::string& nameSpace) { + return Factory::getInstance()->createExecutableContent(localName, nameSpace, this); + } + + /** IOProcessorCallbacks */ diff --git a/src/uscxml/plugins/ExecutableContentImpl.h b/src/uscxml/plugins/ExecutableContentImpl.h index f186e84..81aedf1 100644 --- a/src/uscxml/plugins/ExecutableContentImpl.h +++ b/src/uscxml/plugins/ExecutableContentImpl.h @@ -57,7 +57,9 @@ public: } virtual void enterElement(XERCESC_NS::DOMElement* node) = 0; ///< Invoked when entering the element as part of evaluating executable content. virtual void exitElement(XERCESC_NS::DOMElement* node) = 0; ///< Invoked when exiting the element as part of evaluating executable content. - virtual bool processChildren() = 0; ///< Whether or not the interpreter should process this elements children. + virtual bool processChildren() { + return false; ///< Whether or not the interpreter should process this elements children. + } protected: InterpreterImpl* _interpreter; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 61aa218..7f8187f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -47,7 +47,14 @@ endfunction() # simple one file tests USCXML_TEST_COMPILE(NAME test-utils LABEL general/test-utils FILES src/test-utils.cpp) if(WITH_DM_LUA AND NOT BUILD_AS_PLUGINS) - USCXML_TEST_COMPILE(NAME test-extensions LABEL general/test-extensions FILES src/test-extensions.cpp ../contrib/src/uscxml/PausableDelayedEventQueue.cpp ../contrib/src/uscxml/ExtendedLuaDataModel.cpp) + USCXML_TEST_COMPILE( + NAME test-extensions + LABEL general/test-extensions + FILES + src/test-extensions.cpp + ../contrib/src/uscxml/PausableDelayedEventQueue.cpp + ../contrib/src/uscxml/ExtendedLuaDataModel.cpp + ../contrib/src/uscxml/CustomExecutableContent.cpp) endif() USCXML_TEST_COMPILE(NAME test-url LABEL general/test-url FILES src/test-url.cpp) USCXML_TEST_COMPILE(NAME test-lifecycle LABEL general/test-lifecycle FILES src/test-lifecycle.cpp) diff --git a/test/src/test-extensions.cpp b/test/src/test-extensions.cpp index 626f8e5..4051c68 100644 --- a/test/src/test-extensions.cpp +++ b/test/src/test-extensions.cpp @@ -5,6 +5,7 @@ #include "uscxml/interpreter/BasicDelayedEventQueue.h" #include "uscxml/PausableDelayedEventQueue.h" #include "uscxml/ExtendedLuaDataModel.h" +#include "uscxml/CustomExecutableContent.h" #include // for evutil_socket_t @@ -29,6 +30,7 @@ class MyPausableDelayedEventQueue : public PausableDelayedEventQueue { }; + // from issue 96: // https://github.com/tklab-tud/uscxml/issues/96 @@ -108,7 +110,6 @@ bool testPausableEventQueue() { } - static const char *customLuaExtension = "" "