Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
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