diff options
Diffstat (limited to 'src/uscxml/transform/ChartToFSM.h')
-rw-r--r-- | src/uscxml/transform/ChartToFSM.h | 115 |
1 files changed, 106 insertions, 9 deletions
diff --git a/src/uscxml/transform/ChartToFSM.h b/src/uscxml/transform/ChartToFSM.h index c4d2da3..1dc8813 100644 --- a/src/uscxml/transform/ChartToFSM.h +++ b/src/uscxml/transform/ChartToFSM.h @@ -61,6 +61,8 @@ public: } static uint64_t stateMachineComplexity(const Arabica::DOM::Element<std::string>& root, Complexity::Variant variant = IGNORE_NOTHING); + static std::list<std::set<Arabica::DOM::Element<std::string> > > getAllConfigurations(const Arabica::DOM::Element<std::string>& root); + static std::map<size_t, size_t> getTransitionHistogramm(const Arabica::DOM::Element<std::string>& root); protected: static Complexity calculateStateMachineComplexity(const Arabica::DOM::Element<std::string>& root); @@ -89,8 +91,8 @@ public: std::string stateId; std::string activeId; - long activeIndex; - long index; + unsigned long activeIndex; + unsigned long index; bool isFinal; ChartToFSM* interpreter; @@ -105,11 +107,40 @@ public: class USCXML_API GlobalTransition { public: + enum InvalidReason { + MIXES_EVENT_SPONTANEOUS, + NO_COMMON_EVENT, + CHILD_ENABLED, + SAME_SOURCE_STATE, + UNCONDITIONAL_SUPERSET, + UNCONDITIONAL_MATCH, + PREEMPTING_MEMBERS + }; + class Action { public: bool operator<(const Action& other) const { + if ((onEntry && !other.onEntry) || (!onEntry && other.onEntry)) + return true; + if ((raiseDone && !other.raiseDone) || (!raiseDone && other.raiseDone)) + return true; + if ((onExit && !other.onExit) || (!onExit && other.onExit)) + return true; + if ((transition && !other.transition) || (!transition && other.transition)) + return true; + if ((entered && !other.entered) || (!entered && other.entered)) + return true; + if ((exited && !other.exited) || (!exited && other.exited)) + return true; + if ((invoke && !other.invoke) || (!invoke && other.invoke)) + return true; + if ((uninvoke && !other.uninvoke) || (!uninvoke && other.uninvoke)) + return true; + if (onEntry < other.onEntry) return onEntry < other.onEntry; + if (raiseDone < other.raiseDone) + return raiseDone < other.raiseDone; if (onExit < other.onExit) return onExit < other.onExit; if (transition < other.transition) @@ -132,6 +163,8 @@ public: return !operator==(other); } + friend USCXML_API std::ostream& operator<< (std::ostream& os, const Action& action); + typedef std::list<GlobalTransition::Action>::iterator iter_t; Arabica::DOM::Element<std::string> onEntry; @@ -141,6 +174,7 @@ public: Arabica::DOM::Element<std::string> exited; Arabica::DOM::Element<std::string> invoke; Arabica::DOM::Element<std::string> uninvoke; + Arabica::DOM::Element<std::string> raiseDone; }; @@ -148,6 +182,9 @@ public: static GlobalTransition* copyWithoutExecContent(GlobalTransition* other); bool isValid; // constructor will determine, calling code will delete if not + std::string invalidMsg; + InvalidReason invalidReason; + 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 @@ -189,17 +226,66 @@ protected: std::list<std::string> getCommonEvents(const Arabica::XPath::NodeSet<std::string>& transitions); }; +USCXML_API std::ostream& operator<< (std::ostream& os, const GlobalTransition::Action& action); + +class TransitionTreeNode { +public: + enum TransitionTreeNodeType { + TYPE_UNDEFINED, + TYPE_PARALLEL, + TYPE_NESTED, + TYPE_TRANSITION + }; + + TransitionTreeNode() + : prevTransition(NULL), + nextTransition(NULL), + firstTransition(NULL), + firstState(NULL), + parent(NULL), + type(TYPE_UNDEFINED) {} + + virtual ~TransitionTreeNode() { + for (std::list<TransitionTreeNode*>::iterator childIter = children.begin(); childIter != children.end(); childIter++) { + delete(*childIter); + } + } + + void dump(int indent = 0); + + TransitionTreeNode* prevTransition; + TransitionTreeNode* nextTransition; + Arabica::DOM::Element<std::string> transition; + + Arabica::DOM::Element<std::string> state; + TransitionTreeNode* firstTransition; + TransitionTreeNode* lastTransition; + TransitionTreeNode* firstState; + + TransitionTreeNode* parent; + std::list<TransitionTreeNode*> children; + std::string nodeId; + + TransitionTreeNodeType type; + + bool operator<(const TransitionTreeNode& other) const { + return nodeId < other.nodeId; + } + +}; class USCXML_API ChartToFSM : public InterpreterRC, public InterpreterMonitor { public: + ChartToFSM(const Interpreter& other); virtual ~ChartToFSM(); + void indexTransitions(); + Arabica::DOM::Document<std::string> getDocument() const; // overwrite to return flat FSM + protected: - ChartToFSM(const Interpreter& other); - Arabica::DOM::Document<std::string> getDocument() const; // overwrite to return flat FSM InterpreterState interpret(); - + GlobalState* _start; Arabica::DOM::Document<std::string> _flatDoc; std::map<std::string, GlobalState*> _globalConf; @@ -209,13 +295,16 @@ protected: uint32_t getMinInternalQueueLength(uint32_t defaultVal); uint32_t getMinExternalQueueLength(uint32_t defaultVal); + bool _keepInvalidTransitions; + bool _transitionsFromTree; + + std::vector<Arabica::DOM::Element<std::string> > indexedTransitions; + std::vector<Arabica::DOM::Element<std::string> > indexedStates; + private: Arabica::XPath::NodeSet<std::string> refsToStates(const std::set<int>&); Arabica::XPath::NodeSet<std::string> refsToTransitions(const std::set<int>&); - std::vector<Arabica::DOM::Element<std::string> > indexedTransitions; - std::vector<Arabica::DOM::Element<std::string> > indexedStates; - // gather executable content per microstep void executeContent(const Arabica::DOM::Element<std::string>& content, bool rethrow = false); @@ -235,8 +324,10 @@ private: virtual void beforeTakingTransition(Interpreter interpreter, const Arabica::DOM::Element<std::string>& transition, bool moreComing); void explode(); - void getPotentialTransitionsForConf(const Arabica::XPath::NodeSet<std::string>& conf, std::map<std::string, GlobalTransition*>& outMap); + void getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath::NodeSet<std::string>& conf, std::map<std::string, GlobalTransition*>& outMap); + void getPotentialTransitionsForConfFromTree(const Arabica::XPath::NodeSet<std::string>& conf, std::map<std::string, GlobalTransition*>& outMap); // void labelTransitions(); + TransitionTreeNode* buildTransTree(const Arabica::DOM::Element<std::string>& root, const std::string& nodeId); void indexTransitions(const Arabica::DOM::Element<std::string>& root); void annotateRaiseAndSend(const Arabica::DOM::Element<std::string>& root); @@ -256,12 +347,14 @@ private: uint64_t _perfTransTotal; uint64_t _perfTransUsed; uint64_t _perfStatesProcessed; + uint64_t _perfStatesTotal; uint64_t _perfStatesSkippedProcessed; uint64_t _perfStatesSkippedTotal; uint64_t _perfStatesCachedProcessed; uint64_t _perfStatesCachedTotal; uint64_t _perfMicroStepProcessed; uint64_t _perfMicroStepTotal; + uint64_t _perfStackSize; uint64_t _lastTimeStamp; size_t _lastTransientStateId; @@ -277,6 +370,10 @@ private: size_t _doneEventRaiseTolerance; GlobalTransition* _currGlobalTransition; + std::map<std::string, std::map<std::string, GlobalTransition*> > _confToTransitions; + + TransitionTreeNode* _transTree; + std::map<Arabica::DOM::Element<std::string>, TransitionTreeNode*> _stateToTransTreeNode; friend class GlobalTransition; friend class GlobalState; |