Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkStateMachineContainer.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3  The Medical Imaging Interaction Toolkit (MITK)
4 
5  Copyright (c) German Cancer Research Center,
6  Division of Medical and Biological Informatics.
7  All rights reserved.
8 
9  This software is distributed WITHOUT ANY WARRANTY; without
10  even the implied warranty of MERCHANTABILITY or FITNESS FOR
11  A PARTICULAR PURPOSE.
12 
13  See LICENSE.txt or http://www.mitk.org for details.
14 
15  ===================================================================*/
16 
18 #include <algorithm>
20 #include <vtkObjectFactory.h>
21 #include <vtkXMLDataElement.h>
22 
23 // us
24 #include "usGetModuleContext.h"
25 #include "usModule.h"
26 #include "usModuleResource.h"
27 #include "usModuleResourceStream.h"
28 
33 // XML StateMachine Tags
34 const std::string NAME = "name";
35 const std::string CONFIG = "statemachine";
36 const std::string STATE = "state";
37 const std::string STATEMODE = "state_mode";
38 const std::string TRANSITION = "transition";
39 const std::string EVENTCLASS = "event_class";
40 const std::string EVENTVARIANT = "event_variant";
41 const std::string STARTSTATE = "startstate";
42 const std::string TARGET = "target";
43 const std::string ACTION = "action";
44 const std::string CONDITION = "condition";
45 const std::string INVERTED = "inverted";
46 
47 namespace mitk
48 {
49  vtkStandardNewMacro(StateMachineContainer);
50 }
51 
52 mitk::StateMachineContainer::StateMachineContainer() : m_StartStateFound(false), m_errors(false)
53 {
54 }
55 
57 {
58 }
59 
63 bool mitk::StateMachineContainer::LoadBehavior(const std::string &fileName, const us::Module *module)
64 {
65  if (module == NULL)
66  {
67  module = us::GetModuleContext()->GetModule();
68  }
69  us::ModuleResource resource = module->GetResource("Interactions/" + fileName);
70  if (!resource.IsValid())
71  {
72  mitkThrow() << ("Resource not valid. State machine pattern not found:" + fileName);
73  }
74  us::ModuleResourceStream stream(resource);
75  this->SetStream(&stream);
76  m_Filename = fileName;
77  return this->Parse() && !m_errors;
78 }
79 
81 {
82  return m_StartState;
83 }
84 
88 void mitk::StateMachineContainer::ConnectStates()
89 {
90  for (StateMachineCollectionType::iterator it = m_States.begin(); it != m_States.end(); ++it)
91  {
92  if ((*it)->ConnectTransitions(&m_States) == false)
93  m_errors = true;
94  }
95 }
96 
97 void mitk::StateMachineContainer::StartElement(const char *elementName, const char **atts)
98 {
99  std::string name(elementName);
100 
101  if (name == CONFIG)
102  {
103  //
104  }
105  else if (name == STATE)
106  {
107  std::string stateName = ReadXMLStringAttribut(NAME, atts);
108  std::transform(stateName.begin(), stateName.end(), stateName.begin(), ::toupper);
109  std::string stateMode = ReadXMLStringAttribut(STATEMODE, atts);
110  std::transform(stateMode.begin(), stateMode.end(), stateMode.begin(), ::toupper);
111  bool isStartState = ReadXMLBooleanAttribut(STARTSTATE, atts);
112 
113  if (isStartState)
114  {
115  m_StartStateFound = true;
116  }
117 
118  // sanitize state modes
119  if (stateMode == "" || stateMode == "REGULAR")
120  {
121  stateMode = "REGULAR";
122  }
123  else if (stateMode != "GRAB_INPUT" && stateMode != "PREFER_INPUT")
124  {
125  MITK_WARN << "Invalid State Modus " << stateMode << ". Mode assumed to be REGULAR";
126  stateMode = "REGULAR";
127  }
128  m_CurrState = mitk::StateMachineState::New(stateName, stateMode);
129 
130  if (isStartState)
131  m_StartState = m_CurrState;
132  }
133  else if (name == TRANSITION)
134  {
135  std::string eventClass = ReadXMLStringAttribut(EVENTCLASS, atts);
136  std::string eventVariant = ReadXMLStringAttribut(EVENTVARIANT, atts);
137  std::string target = ReadXMLStringAttribut(TARGET, atts);
138  std::transform(target.begin(), target.end(), target.begin(), ::toupper);
139 
141  mitk::StateMachineTransition::New(target, eventClass, eventVariant);
142  if (m_CurrState)
143  {
144  m_CurrState->AddTransition(transition);
145  }
146  else
147  {
148  MITK_WARN << "Malformed Statemachine Pattern. Transition has no origin. \n Will be ignored.";
149  MITK_WARN << "Malformed Transition details: target=" << target << ", event class:" << eventClass
150  << ", event variant:" << eventVariant;
151  }
152  m_CurrTransition = transition;
153  }
154 
155  else if (name == ACTION)
156  {
157  std::string actionName = ReadXMLStringAttribut(NAME, atts);
159  if (m_CurrTransition)
160  m_CurrTransition->AddAction(action);
161  else
162  MITK_WARN << "Malformed state machine Pattern. Action without transition. \n Will be ignored.";
163  }
164 
165  else if (name == CONDITION)
166  {
167  if (!m_CurrTransition)
168  MITK_WARN << "Malformed state machine Pattern. Condition without transition. \n Will be ignored.";
169 
170  std::string conditionName = ReadXMLStringAttribut(NAME, atts);
171  std::string inverted = ReadXMLStringAttribut(INVERTED, atts);
172  if (inverted == "" || inverted == "false")
173  {
174  m_CurrTransition->AddCondition(mitk::StateMachineCondition(conditionName, false));
175  }
176  else
177  {
178  m_CurrTransition->AddCondition(mitk::StateMachineCondition(conditionName, true));
179  }
180  }
181 }
182 
183 void mitk::StateMachineContainer::EndElement(const char *elementName)
184 {
185  std::string name(elementName);
186 
187  if (name == CONFIG)
188  {
189  if (m_StartState.IsNull())
190  {
191  MITK_ERROR << "State machine pattern has no start state and cannot be used: " << m_Filename;
192  }
193  ConnectStates();
194  }
195  else if (name == TRANSITION)
196  {
197  m_CurrTransition = NULL;
198  }
199  else if (name == ACTION)
200  {
201  //
202  }
203  else if (name == CONDITION)
204  {
205  //
206  }
207  else if (name == STATE)
208  {
209  m_States.push_back(m_CurrState);
210  m_CurrState = NULL;
211  }
212 }
213 
214 std::string mitk::StateMachineContainer::ReadXMLStringAttribut(std::string name, const char **atts)
215 {
216  if (atts)
217  {
218  const char **attsIter = atts;
219 
220  while (*attsIter)
221  {
222  if (name == *attsIter)
223  {
224  attsIter++;
225  return *attsIter;
226  }
227  attsIter++;
228  attsIter++;
229  }
230  }
231 
232  return std::string();
233 }
234 
235 bool mitk::StateMachineContainer::ReadXMLBooleanAttribut(std::string name, const char **atts)
236 {
237  std::string s = ReadXMLStringAttribut(name, atts);
238  std::transform(s.begin(), s.end(), s.begin(), ::toupper);
239  if (s == "TRUE")
240  return true;
241  else
242  return false;
243 }
const std::string STATE
bool LoadBehavior(const std::string &fileName, const us::Module *module)
Loads XML resource.
#define MITK_ERROR
Definition: mitkLogMacros.h:24
static Pointer New(const std::string &_arg)
const std::string ACTION
const std::string STARTSTATE
const std::string NAME
This class builds up all the necessary structures for a statemachine. and stores one start-state for ...
DataCollection - Class to facilitate loading/accessing structured data.
static Pointer New(const std::string &_arga, const std::string &_argb)
const std::string CONFIG
StateMachineState::Pointer GetStartState() const
Returns the StartState of the StateMachine.
void StartElement(const char *elementName, const char **atts) override
Derived from XMLReader.
#define MITK_WARN
Definition: mitkLogMacros.h:23
Module * GetModule() const
#define mitkThrow()
const std::string INVERTED
vtkStandardNewMacro(AnatomicalStructureColorPresets)
const std::string STATEMODE
const std::string EVENTVARIANT
static Pointer New(const std::string &_arga, const std::string &_argb, const std::string &_argc)
const std::string CONDITION
ModuleResource GetResource(const std::string &path) const
Definition: usModule.cpp:267
Represents a condition, that has to be fulfilled in order to execute a state machine transition after...
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
const std::string EVENTCLASS
void EndElement(const char *elementName) override
Derived from XMLReader.
const std::string TRANSITION
const std::string TARGET