#include "uscxml/Interpreter.h" #include "uscxml/interpreter/InterpreterMonitor.h" #include "uscxml/interpreter/InterpreterImpl.h" #include "uscxml/interpreter/BasicEventQueue.h" #include "uscxml/interpreter/BasicDelayedEventQueue.h" #include "uscxml/PausableDelayedEventQueue.h" #include "uscxml/ExtendedLuaDataModel.h" #include "uscxml/CustomExecutableContent.h" #include // for evutil_socket_t #include #include #include using namespace uscxml; class MyPausableDelayedEventQueue; std::shared_ptr nestedDelayQueue; class MyPausableDelayedEventQueue : public PausableDelayedEventQueue { MyPausableDelayedEventQueue(DelayedEventQueueCallbacks* callbacks) : PausableDelayedEventQueue(callbacks) { } std::shared_ptr create(DelayedEventQueueCallbacks* callbacks) { // remember as nestedDelayQueue in global scope nestedDelayQueue = std::shared_ptr(new MyPausableDelayedEventQueue(callbacks)); return nestedDelayQueue; } }; // from issue 96: // https://github.com/tklab-tud/uscxml/issues/96 static const char *customDelayedEQ = "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " ""; bool testPausableEventQueue() { Interpreter interpreter = Interpreter::fromXML(customDelayedEQ, ""); PausableDelayedEventQueue* queue = new PausableDelayedEventQueue(interpreter.getImpl().get()); ActionLanguage lang; lang.delayQueue = DelayedEventQueue(std::shared_ptr(queue)); interpreter.setActionLanguage(lang); StateTransitionMonitor mon; mon.copyToInvokers(true); interpreter.addMonitor(&mon); size_t iterations = 10; int now = time(NULL); int startedAt = time(NULL); InterpreterState state = InterpreterState::USCXML_UNDEF; while (state != USCXML_FINISHED && now - startedAt < 5) { state = interpreter.step(200); now = time(NULL); if (nestedDelayQueue) { /* * As soon as we have the nested event queue instantiated, we pause and resume it * We pause for 500ms, and run for 500ms. This will effectively double the time required * for delayed events. * This would usually done in another thread .. */ std::cout << "<- pausing" << std::endl; nestedDelayQueue->pause(); std::this_thread::sleep_for(std::chrono::milliseconds(500)); std::cout << "-> continuing" << std::endl; nestedDelayQueue->resume(); std::this_thread::sleep_for(std::chrono::milliseconds(500)); if (iterations-- == 0) return true; } } return true; } static const char *customLuaExtension = "" " " " " "" ; bool testLuaExtension() { Factory::getInstance()->registerDataModel(new ExtendedLuaDataModel()); Interpreter exLua = Interpreter::fromXML(customLuaExtension, ""); InterpreterState state; while ((state = exLua.step(0)) != USCXML_IDLE) {} return true; } static const char *customExecContent = "" " " " " " " " " " " "" ; bool testCustomExecContent() { Factory::getInstance()->registerExecutableContent(new CustomExecutableContent()); Interpreter exContent = Interpreter::fromXML(customExecContent, ""); InterpreterState state; while ((state = exContent.step(0)) != USCXML_IDLE) {} return true; } class CustomExecutableContentNS : public ExecutableContentImpl { public: ~CustomExecutableContentNS() {}; virtual std::shared_ptr create(uscxml::InterpreterImpl* interpreter) { return std::shared_ptr(new CustomExecutableContentNS()); } virtual std::string getLocalName() { return "custom"; } virtual std::string getNamespace() { return "http://www.example.com/custom"; } virtual void enterElement(XERCESC_NS::DOMElement* node) { std::cout << "Entering customNS element" << std::endl; } virtual void exitElement(XERCESC_NS::DOMElement* node) { std::cout << "Exiting customNS element" << std::endl; } }; static const char *customExecContentNS = "" " " " " " " " " " " "" ; bool testCustomExecContentNS() { Factory::getInstance()->registerExecutableContent(new CustomExecutableContentNS()); Interpreter exContent = Interpreter::fromXML(customExecContentNS, ""); InterpreterState state; while ((state = exContent.step(0)) != USCXML_IDLE) {} return true; } int main(int argc, char** argv) { // testLuaExtension(); // testPausableEventQueue(); testCustomExecContentNS(); }