summaryrefslogtreecommitdiffstats
path: root/src/uscxml/transform/ChartToFSM.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/uscxml/transform/ChartToFSM.h')
-rw-r--r--src/uscxml/transform/ChartToFSM.h154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/uscxml/transform/ChartToFSM.h b/src/uscxml/transform/ChartToFSM.h
new file mode 100644
index 0000000..14ec4e7
--- /dev/null
+++ b/src/uscxml/transform/ChartToFSM.h
@@ -0,0 +1,154 @@
+/**
+ * @file
+ * @author 2012-2014 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 <http://www.opensource.org/licenses/bsd-license>.
+ * @endcond
+ */
+
+#ifndef CHARTTOFSM_H_IOKPYEBY
+#define CHARTTOFSM_H_IOKPYEBY
+
+#include "uscxml/DOMUtils.h"
+#include "uscxml/interpreter/InterpreterDraft6.h"
+#include <DOM/Document.hpp>
+#include <DOM/Node.hpp>
+#include <XPath/XPath.hpp>
+#include <ostream>
+
+
+namespace uscxml {
+class GlobalState;
+class GlobalTransition;
+
+class GlobalState {
+public:
+
+ GlobalState() {}
+ GlobalState(const Arabica::XPath::NodeSet<std::string>& activeStates,
+ const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates, // we need to remember for binding=late
+ const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates);
+
+ Arabica::XPath::NodeSet<std::string> activeStates;
+ Arabica::XPath::NodeSet<std::string> alreadyEnteredStates;
+ std::map<std::string, Arabica::XPath::NodeSet<std::string> > historyStates;
+
+ std::map<std::string, GlobalTransition*> incoming;
+ std::map<std::string, GlobalTransition*> outgoing;
+ std::string stateId;
+
+ bool isFinal;
+};
+
+
+class GlobalTransition {
+public:
+ class Action {
+ public:
+ Arabica::DOM::Node<std::string> onEntry;
+ Arabica::DOM::Node<std::string> onExit;
+ Arabica::DOM::Node<std::string> transition;
+ Arabica::DOM::Node<std::string> entered;
+ Arabica::DOM::Node<std::string> exited;
+ Arabica::DOM::Node<std::string> invoke;
+ Arabica::DOM::Node<std::string> uninvoke;
+ };
+
+ GlobalTransition(const Arabica::XPath::NodeSet<std::string>& transitions, DataModel dataModel);
+
+ bool isValid; // constructor will determine, calling code will delete if not
+ bool isEventless; // whether or not all our transitions are eventless
+ bool isTargetless; // whether or not all our transitions are eventless
+ bool isSubset; // there is a superset to this set
+
+ std::vector<long> firstElemPerLevel;
+ std::vector<long> nrElemPerLevel;
+ std::vector<long> prioPerLevel;
+
+ Arabica::XPath::NodeSet<std::string> transitions; // constituting transitions
+
+ std::list<std::string> eventNames; // the list of longest event names that will enable this set
+ std::string eventDesc; // space-seperated eventnames for convenience
+ std::string condition; // conjunction of all the set's conditions
+
+ // executable content we gathered when we took the transition
+ std::list<Action> actions;
+
+ Arabica::XPath::NodeSet<std::string> entered;
+ Arabica::XPath::NodeSet<std::string> exited;
+
+ Arabica::XPath::NodeSet<std::string> invoke;
+ Arabica::XPath::NodeSet<std::string> uninvoke;
+
+ std::string transitionId;
+ std::string source;
+ std::string destination;
+
+protected:
+ std::list<std::string> getCommonEvents(const Arabica::XPath::NodeSet<std::string>& transitions);
+};
+
+class FlatteningInterpreter : public InterpreterDraft6, public InterpreterMonitor {
+public:
+ FlatteningInterpreter(const Arabica::DOM::Document<std::string>& doc);
+ Arabica::DOM::Document<std::string>& getDocument(); // overwrite to return flat FSM
+ void interpret();
+
+protected:
+ // gather executable content per microstep
+ void executeContent(const Arabica::DOM::Node<std::string>& content, bool rethrow = false);
+ void executeContent(const Arabica::DOM::NodeList<std::string>& content, bool rethrow = false);
+ void executeContent(const Arabica::XPath::NodeSet<std::string>& content, bool rethrow = false);
+
+ // invoke and uninvoke
+ virtual void invoke(const Arabica::DOM::Node<std::string>& element);
+ virtual void cancelInvoke(const Arabica::DOM::Node<std::string>& element);
+
+ // override to do nothing
+ void send(const Arabica::DOM::Node<std::string>& element) {}
+ void internalDoneSend(const Arabica::DOM::Node<std::string>& state);
+
+ // InterpreterMonitor
+ virtual void beforeMicroStep(Interpreter interpreter);
+ virtual void onStableConfiguration(Interpreter interpreter);
+ virtual void beforeExitingState(Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing);
+ virtual void beforeEnteringState(Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing);
+ virtual void beforeTakingTransition(Interpreter interpreter, const Arabica::DOM::Element<std::string>& transition, bool moreComing);
+
+ void explode();
+ void labelTransitions();
+ void weightTransitions();
+ void createDocument();
+
+ Arabica::DOM::Node<std::string> globalStateToNode(GlobalState* globalState, const std::string& xmlNs);
+ Arabica::DOM::Node<std::string> globalTransitionToNode(GlobalTransition* globalTransition, const std::string& xmlNs);
+
+ GlobalState* _start;
+ GlobalTransition* _currGlobalTransition;
+
+ int maxDepth;
+ int maxOrder;
+
+ Arabica::DOM::Document<std::string> _flatDoc;
+ std::map<std::string, GlobalState*> _globalConf;
+};
+
+class ChartToFSM {
+public:
+ static Arabica::DOM::Document<std::string> flatten(const Arabica::DOM::Document<std::string>& doc, const std::map<std::string, std::string>& nameSpaceInfo);
+};
+
+}
+
+#endif /* end of include guard: CHARTTOFSM_H_IOKPYEBY */