diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2015-01-19 16:41:18 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2015-01-19 16:41:18 (GMT) |
commit | ff86d690dc02d7dd495000331d378e7d8eb688ac (patch) | |
tree | 5214786f7e575952d3cba0919e5071f3a783050b /src/uscxml/transform/ChartToFSM.h.new | |
parent | 42437db418574f2a80d098e568b9498a21343800 (diff) | |
download | uscxml-ff86d690dc02d7dd495000331d378e7d8eb688ac.zip uscxml-ff86d690dc02d7dd495000331d378e7d8eb688ac.tar.gz uscxml-ff86d690dc02d7dd495000331d378e7d8eb688ac.tar.bz2 |
Plenty of smaller fixes and adaptations
Diffstat (limited to 'src/uscxml/transform/ChartToFSM.h.new')
-rw-r--r-- | src/uscxml/transform/ChartToFSM.h.new | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/src/uscxml/transform/ChartToFSM.h.new b/src/uscxml/transform/ChartToFSM.h.new new file mode 100644 index 0000000..2ec2f44 --- /dev/null +++ b/src/uscxml/transform/ChartToFSM.h.new @@ -0,0 +1,303 @@ +/** + * @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/InterpreterRC.h" +#include <DOM/Document.hpp> +#include <DOM/Node.hpp> +#include <XPath/XPath.hpp> +#include <ostream> +#include <list> + +namespace uscxml { +class GlobalState; +class GlobalTransition; +class ChartToFSM; + +class USCXML_API Complexity { +public: + + enum Variant { + IGNORE_NOTHING, + IGNORE_HISTORY, + IGNORE_NESTED_DATA, + IGNORE_HISTORY_AND_NESTED_DATA, + }; + + Complexity() : value(0), nestedData(0) {} + Complexity(uint64_t value) : value(value), nestedData(0) {} + + Complexity& operator+=(const Complexity& rhs) { + value += rhs.value; + nestedData += rhs.nestedData; + history.insert(history.end(), rhs.history.begin(), rhs.history.end()); + return *this; + } + + Complexity& operator*=(const Complexity& rhs) { + value *= rhs.value; + nestedData += rhs.nestedData; + history.insert(history.end(), rhs.history.begin(), rhs.history.end()); + return *this; + } + + static uint64_t stateMachineComplexity(const Arabica::DOM::Element<std::string>& root, Complexity::Variant variant = IGNORE_NOTHING); + +protected: + static Complexity calculateStateMachineComplexity(const Arabica::DOM::Element<std::string>& root); + + uint64_t value; + uint64_t nestedData; + std::list<uint64_t> history; +}; + +class USCXML_API GlobalState { +public: + + GlobalState() {} + GlobalState(const Arabica::DOM::Node<std::string>& 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, + const std::string& xmlNSPrefix, + ChartToFSM* flattener); + + std::set<int> activeStatesRefs; + std::set<int> alreadyEnteredStatesRefs; + std::map<std::string, std::set<int> > historyStatesRefs; + + std::list<GlobalTransition*> sortedOutgoing; + std::string stateId; + std::string activeId; + + unsigned long activeIndex; + unsigned long index; + bool isFinal; + + ChartToFSM* interpreter; + + Arabica::XPath::NodeSet<std::string> getActiveStates(); + Arabica::XPath::NodeSet<std::string> getAlreadyEnteredStates(); + std::map<std::string, Arabica::XPath::NodeSet<std::string> > getHistoryStates(); + +}; + + +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) + return onEntry < other.onEntry; + if (onExit < other.onExit) + return onExit < other.onExit; + if (transition < other.transition) + return transition < other.transition; + if (entered < other.entered) + return entered < other.entered; + if (exited < other.exited) + return exited < other.exited; + if (invoke < other.invoke) + return invoke < other.invoke; + if (uninvoke < other.uninvoke) + return uninvoke < other.uninvoke; + return false; + } + + bool operator==(const Action& other) const { + return !(other < *this) && !(*this < other); + } + bool operator!=(const Action& other) const { + return !operator==(other); + } + + typedef std::list<GlobalTransition::Action>::iterator iter_t; + + Arabica::DOM::Element<std::string> onEntry; + Arabica::DOM::Element<std::string> onExit; + Arabica::DOM::Element<std::string> transition; + Arabica::DOM::Element<std::string> entered; + Arabica::DOM::Element<std::string> exited; + Arabica::DOM::Element<std::string> invoke; + Arabica::DOM::Element<std::string> uninvoke; + + }; + + GlobalTransition(const Arabica::XPath::NodeSet<std::string>& transitions, DataModel dataModel, ChartToFSM* flattener); + 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 + bool hasExecutableContent; + + uint32_t eventsRaised; // internal events this transition will raise + uint32_t eventsSent; // external events this transition will send + uint32_t eventsChainRaised; // maximum number of internal events raised when taking this transition in a chain + uint32_t eventsChainSent; // maximum number of external events raised when taking this transition in a chain + + std::set<int> startTransitionRefs; // indices of eventful transitions that might trigger this transition + + std::set<int> transitionRefs; // indizes of constituting transitions + Arabica::XPath::NodeSet<std::string> getTransitions() const; + + 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 + std::string members; // a convenience string listing all constituting transitions + + // executable content we gathered when we took the transition + std::list<Action> actions; + + std::string transitionId; + std::string source; + std::string destination; + std::string activeDestination; + + GlobalTransition* historyBase; // we have a base transition that left our source with no history (-> we are a history transition) + std::list<GlobalTransition*> historyTrans; // transitions from the same source but different histories + std::set<std::string> histTargets; // constituting targets to history states + + long index; + ChartToFSM* interpreter; + + bool operator< (const GlobalTransition& other) const; + +protected: + std::list<std::string> getCommonEvents(const Arabica::XPath::NodeSet<std::string>& transitions); +}; + + +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: + + InterpreterState interpret(); + + GlobalState* _start; + Arabica::DOM::Document<std::string> _flatDoc; + std::map<std::string, GlobalState*> _globalConf; + std::map<std::string, GlobalState*> _activeConf; // potentially enabled transition sets per active configuration + std::map<std::string, Arabica::DOM::Element<std::string> > _historyTargets; // ids of all history states + + uint32_t getMinInternalQueueLength(uint32_t defaultVal); + uint32_t getMinExternalQueueLength(uint32_t defaultVal); + + bool _keepInvalidTransitions; + +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); + + // invoke and uninvoke + virtual void invoke(const Arabica::DOM::Element<std::string>& element); + virtual void cancelInvoke(const Arabica::DOM::Element<std::string>& element); + + // override to do nothing + void send(const Arabica::DOM::Element<std::string>& element) {} + void internalDoneSend(const Arabica::DOM::Element<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 getPotentialTransitionsForConf(const Arabica::XPath::NodeSet<std::string>& conf, std::map<std::string, GlobalTransition*>& outMap); +// void labelTransitions(); + + void indexTransitions(const Arabica::DOM::Element<std::string>& root); + void annotateRaiseAndSend(const Arabica::DOM::Element<std::string>& root); + bool hasForeachInBetween(const Arabica::DOM::Node<std::string>& ancestor, const Arabica::DOM::Node<std::string>& child); + void updateRaisedAndSendChains(GlobalState* state, GlobalTransition* source, std::set<GlobalTransition*> visited); + + void reassembleFromFlat(); + + std::list<GlobalTransition*> sortTransitions(std::list<GlobalTransition*> list); + + // we need this static as we use it in a sort function + static std::map<Arabica::DOM::Node<std::string>, Arabica::DOM::Node<std::string> > _transParents; + + static bool filterSameState(const Arabica::XPath::NodeSet<std::string>& transitions); + + uint64_t _perfTransProcessed; + uint64_t _perfTransTotal; + uint64_t _perfTransUsed; + uint64_t _perfStatesProcessed; + uint64_t _perfStatesSkippedProcessed; + uint64_t _perfStatesSkippedTotal; + uint64_t _perfStatesCachedProcessed; + uint64_t _perfStatesCachedTotal; + uint64_t _perfMicroStepProcessed; + uint64_t _perfMicroStepTotal; + uint64_t _lastTimeStamp; + + size_t _lastTransientStateId; + size_t _lastStateIndex; + size_t _lastActiveIndex; + size_t _lastTransIndex; + + bool _alreadyFlat; + + bool _skipEventChainCalculations; + size_t _maxEventSentChain; + size_t _maxEventRaisedChain; + size_t _doneEventRaiseTolerance; + + GlobalTransition* _currGlobalTransition; + + friend class GlobalTransition; + friend class GlobalState; +}; + +} + +#endif /* end of include guard: CHARTTOFSM_H_IOKPYEBY */ |