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.h115
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;