StateModelLayoutMediator.h
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package
19  * @author
20  * @date
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 #pragma once
25 
26 #include <map>
27 #include <memory>
28 #include <string>
29 
30 #include <QList>
31 #include <QObject>
32 #include <QPointF>
33 #include <QSizeF>
34 #include <QString>
35 
36 #include "../model/SignalType.h"
37 #include "../model/State.h"
38 #include "../model/Transition.h"
39 #include "../model/stateinstance/StateInstance.h"
40 #include "GraphvizConverter.h"
41 #include "Layout.h"
43 
44 namespace armarx
45 {
46 
47  using NodeMap = std::map<statechartmodel::StateInstancePtr, std::string>;
48  using EdgeList = QList<statechartmodel::TransitionCPtr>;
49 
50  class StateModelLayoutMediator : public QObject
51  {
52  Q_OBJECT
53 
54  public:
55  /**
56  * @brief LayoutWorker Sets state and id as specified. Initializes an empty Graph.
57  * @param state The state which this worker layouts.
58  * @param id The mediator's ID for communication with the LayoutController.
59  */
60  StateModelLayoutMediator(statechartmodel::StatePtr state, size_t mediator_id);
61 
62  /**
63  * @brief getState Returns the state associated with this mediator.
64  * @return The state that is layouted by the mediator's worker.
65  */
67  /**
68  * @brief getID Returns this mediator's id.
69  * @return ID for communication with the LayoutController
70  */
71  size_t getID() const;
72 
73  /**
74  * @brief isConnected Indicates whether this mediator is connected to a worker.
75  * @return True if it is connected to a worker.
76  */
77  bool isConnected();
78 
79  template <typename ElementType>
80  bool
81  hasGraphAttribute(ElementType* element, const std::string& attributeName) const
82  {
83  ARMARX_CHECK_EXPRESSION(element);
84  char* value = agget(element, const_cast<char*>(attributeName.c_str()));
85  return value != NULL;
86  }
87 
88  template <typename ElementType>
89  std::string
90  getGraphAttribute(ElementType* element, const std::string& attributeName) const
91  {
92  ARMARX_CHECK_EXPRESSION(element);
93  char* value = agget(element, const_cast<char*>(attributeName.c_str()));
95  << "Could not get attribute '" << attributeName << "'' from element";
96  return std::string(value);
97  }
98 
99  template <typename ElementType, typename ValueType>
100  int
102  const std::string& attributeName,
103  const ValueType& value) const
104  {
105  ARMARX_CHECK_EXPRESSION(element);
106  // ARMARX_INFO_S << "Setting " << attributeName << " to " << ValueToString(value);
107  return agsafeset(element,
108  const_cast<char*>(attributeName.c_str()),
109  const_cast<char*>(ValueToString(value).c_str()),
110  const_cast<char*>(""));
111  }
112 
113  QRectF boundingRectForAgraph(Agraph_t* graph) const;
114  signals:
115  /**
116  * @brief supportPointsChanged Notifies of changed support points of the given transition.
117  * @param transition Transition whose support points have changed.
118  * @param suppPoints New support points.
119  */
121  const SupportPoints& suppPoints,
122  const QPointPtr& labelCenterPoint,
123  const FloatPtr& labelFontPointSize);
124 
125  /**
126  * @brief layout Tells worker to layout the graph.
127  * @param layoutAll True: layout nodes and edgese. False: layout only edges.
128  */
129  void layout(bool layoutAll);
130  /**
131  * @brief layoutingFinished Notifies that the latest layout task was finished.
132  */
133  void layoutingFinished();
134 
135  /**
136  * @brief scheduleMe To be called when its graph should be layouted. Is meant for the Controller
137  * to schedule this mediator in its layout queue.
138  * @param id This mediator's id.
139  * @param layoutAll Indicates whether the whole graph (including nodes) should be layouted or only
140  * the edges.
141  */
142  void scheduleMe(size_t id, bool layoutAll);
143 
144  /**
145  * @brief deleteMe To be emitted when this mediator and its worker ought to be deleted because
146  * their corresponding state was deleted.
147  * @param id This mediator's id.
148  */
149  void deleteMe(size_t id);
150  /**
151  * @brief mediatorDeleted Tells worker that is has to be deleted.
152  */
153  void mediatorDeleted();
154 
155  /**
156  * @brief substateFound To be emitted when a substate is found when building up the graph for the
157  * first time.
158  * @param substate The substate that was discovered.
159  * @param signalType Type of change to the substate. Should be eAdded.
160  */
162  statechartmodel::SignalType signalType);
163 
164  public slots:
165  /**
166  * @brief buildUpGraph To be called when the corresponding worker initialized the graph. Traverses
167  * the state and adds all transitions and states to the graph as well as to EdgeList and NodeMap.
168  * @param graph The graphviz graph that shall represent the state.
169  */
170  void buildUpGraph(LockableGraphPtr graph);
171 
172 
173  void stateChanged(statechartmodel::SignalType signalType);
174 
175  /**
176  * @brief substateAdded To be called when a substate of state has changed.
177  * @param substate The changed substate.
178  * @param signalType The type of signal (added, removed, moved etc.).
179  */
181  statechartmodel::SignalType signalType);
182 
183  /**
184  * @brief transitionAdded To be called when a transition of state has changed.
185  * @param transition The changed transition.
186  * @param signalType The type of signal (added, removed, moved etc.).
187  */
189  statechartmodel::SignalType signalType);
190 
191  /**
192  * @brief layout Tells the worker to layout edges and, if layoutAlgo is true, nodes of the graph.
193  * Signals changes of positions to the state.
194  * @param layoutAll If true, nodes and edges are layouted, if false, node positions are assumed
195  * to be fixed and only edges are routed.
196  */
197  void startLayouting(bool layoutAll, int counter);
198 
199  /**
200  * @brief workerFinishedLayouting To be called when the worker is finished layouting.
201  * Notifies the controller.
202  */
204 
205  /**
206  * @brief stateDeleted To be called when the corresponding state is deleted.
207  */
208  void stateDeleted();
209 
210  private:
211  bool updateInitialTransition(statechartmodel::TransitionCPtr transition,
212  statechartmodel::SignalType signalType);
213 
214 
215  QPointF convertPositionFromGraphViz(QPointF gvPos) const;
216  float convertScaleFromGraphViz() const;
217  QPointF convertPositionToGraphViz(QPointF statePos) const;
218 
219  /**
220  * @brief IsConnectedToWorker Indicates whether this mediator is already connected to a worker.
221  * Necessary for the createAllWorkers() function of LayoutController.
222  */
223  bool isConnectedToWorker;
224  /**
225  * @brief id ID of this mediator. Used for communication with the LayoutController.
226  */
227  size_t id;
228 
229  /**
230  * @brief state The state whose subgraph is layouted by this mediator's worker.
231  */
233 
234  /**
235  * @brief converter Converts strings from graphviz to the corresponding point or splineType.
236  */
237  //TODO: Funktionen aus GraphvizConverter allein stehend machen. Converter hier und in SplinePath
238  // eliminieren
239  GraphvizConverter converter;
240 
241  /**
242  * @brief graph Graphviz graph that represents the subgraph of state and a mutex to lock it.
243  */
244  LockableGraphPtr m_graph;
245  /**
246  * @brief substateMap maps the substates of state to the name of their corresponding graphviz node.
247  * Necessary for changing the name of a node.
248  */
249  NodeMap substateMap;
250  /**
251  * @brief transitionMap maps the transitions of state to the label of their corresponding graphviz
252  * edge. Necessary for informing the state of all transition changes.
253  */
254  EdgeList transitionList;
255 
256  NodePtr invisibleStartNode;
257  EdgePtr initialTransition;
258 
259  QRectF graphVizBB;
260 
261  QSizeF dpi;
262  int layoutRepetition;
263 
264  /**
265  * @brief addNode Adds a node with the given name to the graph and to substateMap.
266  * @param substate The substate for which a node is added.
267  */
268  void addNode(statechartmodel::StateInstancePtr substate);
269  /**
270  * @brief removeNode Removes a node and its adjacent edges from the graph and from substateMap/
271  * transitionMap.
272  * @param substate The substate for which the node is removed.
273  */
274  void removeNode(statechartmodel::StateInstancePtr substate);
275  /**
276  * @brief setNodeAttribute Sets the attribute of the node belonging to substate.
277  * @param substate Substate that is represented by the node whose attribute is to be set.
278  * @param attributeName Name of the attribute, e.g. "pos".
279  * @param attributeValue Value of the attribute.
280  */
281  void setNodeAttribute(statechartmodel::StateInstancePtr substate,
282  const std::string& attributeName,
283  const std::string& attributeValue);
284  /**
285  * @brief getNodeAttribute Returns the attribute of the node belonging to substate.
286  * @param substate Substate that is represented by the node whose attribute is returned.
287  * @param attributeName Name of the attribute, e.g. "pos".
288  * @return Value of the attribute.
289  */
290  std::string getNodeAttribute(statechartmodel::StateInstancePtr substate,
291  const std::string& attributeName);
292  bool hasNodeAttribute(armarx::statechartmodel::StateInstancePtr substate,
293  const std::string& attributeName);
294 
295  /**
296  * @brief getNodeName Returns the name of the given node. NOT THREAD-SAFE! LOCK GRAPH BEFORE USAGE!
297  * @param node A node of the graph.
298  * @return
299  */
300  std::string getNodeName(NodePtr node);
301  /**
302  * @brief getNode Return the node with the given name. NOT THREAD-SAFE! LOCK GRAPH BEFORE USAGE!
303  * @param name Name of the node.
304  * @return Returns the node with the given name or NULL if no such node exists.
305  */
306  NodePtr getNode(const std::string& name);
307  /**
308  * @brief getNode Return the node belonging to the substate. NOT THREAD-SAFE! LOCK GRAPH BEFORE USAGE!
309  * @param substate Substate whose node is returned.
310  * @return Returns the node belonging to substate or NULL if no such node exists.
311  */
312  NodePtr getNode(statechartmodel::StateInstancePtr substate);
313 
314 
315  /**
316  * @brief addEdge Adds a node to the graph with source, destination and name as specified by
317  * transition and to transitionList.
318  * @param transition The transition to be represented by the edge
319  * @return Pointer to the newly created edge
320  */
321  void addEdge(statechartmodel::TransitionCPtr transition);
322  /**
323  * @brief removeEdge Removes the node corresponding to transition from the graph and transitionList.
324  * @param transition Transition for which the edge is removed.
325  */
326  void removeEdge(statechartmodel::TransitionCPtr transition);
327  /**
328  * @brief setEdgeAttribute Sets the attribute of the edge belonging to transition.
329  * @param transition Transition represented by the edge whose attribute is set.
330  * @param attributeName Name of the attribute, e.g. "pos".
331  * @param attributeValue Value of the attribute.
332  */
333  void setEdgeAttribute(statechartmodel::TransitionCPtr transition,
334  std::string attributeName,
335  std::string attributeValue);
336  /**
337  * @brief getEdgeAttribute Gets the attribute of the edge belonging to transition.
338  * @param transition Transition represented by the edge whose attribute is returned.
339  * @param attributeName Name of the attribute, e.g. "pos".
340  * @return Value of the attribute.
341  */
342  std::string getEdgeAttribute(statechartmodel::TransitionCPtr transition,
343  std::string attributeName);
344  bool hasEdgeAttribute(statechartmodel::TransitionCPtr transition,
345  std::string attributeName);
346  /**
347  * @brief getEdge Return the edge belonging to the transition. NOT THREAD-SAFE! LOCK GRAPH BEFORE USAGE!
348  * @param transition Transition whose edge is returned.
349  * @return Returns the edge belonging to transition or NULL if none exists.
350  */
351  EdgePtr getEdge(statechartmodel::TransitionCPtr transition);
352 
353 
354  /**
355  * @brief updatePositionAndDimension Compares the stored and the new position of substate and
356  * updates it if necessary.
357  * @param substate Substate whose position is updated.
358  */
359  bool updateNodePositionAndDimension(statechartmodel::StateInstancePtr substate);
360  /**
361  * @brief updateName Compares the stored and the new name of substate and updates it
362  * if necessary.
363  * @param substate Substate whose name is updated.
364  */
365  void updateNodeName(statechartmodel::StateInstancePtr substate);
366  /**
367  * @brief updateLabel If necessary, updates the label of the edge belonging to this transition.
368  * @param transition Transitions whose name changed.
369  */
370  void updateEdgeLabel(statechartmodel::TransitionCPtr transition);
371  /**
372  * @brief updateTargetAndSource Compares the old and the new target and source nodes of the transition
373  * and updates them if necessary.
374  * @param transition Transition whose target or source state might have changed.
375  */
376  void updateEdgeTargetAndSource(statechartmodel::TransitionCPtr transition);
377  /**
378  * @brief updateEdgePosition If necessary updates the position of the edge belonging to
379  * transition.
380  * @param transition Transition whose position might have changed.
381  */
382  void updateEdgePosition(statechartmodel::TransitionCPtr transition);
383 
384  /**
385  * @brief broadcastSubstatePositions Sends signals to the state for every substate containing their
386  * present position
387  */
388  void broadcastSubstatePositions();
389  /**
390  * @brief broadcastTransitionSupportPoints Sends signals to state for every transition containing
391  * their present support points.
392  */
393  void broadcastTransitionSupportPoints();
394 
395  /**
396  * @brief transitionRepresentable Returns true if transition can be represented in a graphviz graph.
397  * @param transition The transition who shall be represented.
398  * @return True if transition has a source and destination state. 'Detached' edges don't exist
399  * in graphviz.
400  */
401  bool transitionRepresentable(statechartmodel::TransitionCPtr transition);
402  };
403 } //namespace armarx
armarx::StateModelLayoutMediator::supportPointsChanged
void supportPointsChanged(statechartmodel::TransitionCPtr transition, const SupportPoints &suppPoints, const QPointPtr &labelCenterPoint, const FloatPtr &labelFontPointSize)
supportPointsChanged Notifies of changed support points of the given transition.
armarx::StateModelLayoutMediator
Definition: StateModelLayoutMediator.h:50
armarx::StateModelLayoutMediator::workerFinishedLayouting
void workerFinishedLayouting()
workerFinishedLayouting To be called when the worker is finished layouting.
Definition: StateModelLayoutMediator.cpp:286
GraphvizConverter.h
armarx::LockableGraphPtr
std::shared_ptr< LockableGraph > LockableGraphPtr
Definition: Layout.h:64
armarx::StateModelLayoutMediator::getGraphAttribute
std::string getGraphAttribute(ElementType *element, const std::string &attributeName) const
Definition: StateModelLayoutMediator.h:90
armarx::StateModelLayoutMediator::scheduleMe
void scheduleMe(size_t id, bool layoutAll)
scheduleMe To be called when its graph should be layouted.
armarx::StateModelLayoutMediator::transitionChanged
void transitionChanged(statechartmodel::TransitionCPtr transition, statechartmodel::SignalType signalType)
transitionAdded To be called when a transition of state has changed.
Definition: StateModelLayoutMediator.cpp:212
armarx::FloatPtr
std::shared_ptr< float > FloatPtr
Definition: Transition.h:39
armarx::StateModelLayoutMediator::getState
statechartmodel::StatePtr getState() const
getState Returns the state associated with this mediator.
Definition: StateModelLayoutMediator.cpp:65
armarx::StateModelLayoutMediator::buildUpGraph
void buildUpGraph(LockableGraphPtr graph)
buildUpGraph To be called when the corresponding worker initialized the graph.
Definition: StateModelLayoutMediator.cpp:77
armarx::NodeMap
std::map< statechartmodel::StateInstancePtr, std::string > NodeMap
Definition: StateModelLayoutMediator.h:47
armarx::StateModelLayoutMediator::substateChanged
void substateChanged(statechartmodel::StateInstancePtr substate, statechartmodel::SignalType signalType)
substateAdded To be called when a substate of state has changed.
Definition: StateModelLayoutMediator.cpp:154
StateModelLayoutMediator.h
armarx::StateModelLayoutMediator::stateDeleted
void stateDeleted()
stateDeleted To be called when the corresponding state is deleted.
Definition: StateModelLayoutMediator.cpp:306
armarx::statechartmodel::StateInstancePtr
std::shared_ptr< StateInstance > StateInstancePtr
Definition: StateInstance.h:146
armarx::QPointPtr
std::shared_ptr< QPointF > QPointPtr
Definition: Transition.h:40
armarx::StateModelLayoutMediator::startLayouting
void startLayouting(bool layoutAll, int counter)
layout Tells the worker to layout edges and, if layoutAlgo is true, nodes of the graph.
Definition: StateModelLayoutMediator.cpp:266
Layout.h
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::StateModelLayoutMediator::deleteMe
void deleteMe(size_t id)
deleteMe To be emitted when this mediator and its worker ought to be deleted because their correspond...
armarx::ValueToString
std::string ValueToString(const T &value)
Definition: StringHelpers.h:61
armarx::StateModelLayoutMediator::layout
void layout(bool layoutAll)
layout Tells worker to layout the graph.
armarx::StateModelLayoutMediator::setGraphAttribute
int setGraphAttribute(ElementType *element, const std::string &attributeName, const ValueType &value) const
Definition: StateModelLayoutMediator.h:101
armarx::StateModelLayoutMediator::StateModelLayoutMediator
StateModelLayoutMediator(statechartmodel::StatePtr state, size_t mediator_id)
LayoutWorker Sets state and id as specified.
Definition: StateModelLayoutMediator.cpp:50
armarx::ElementTypes::ElementType
ElementType
Definition: AbstractObjectSerializer.h:32
armarx::StateModelLayoutMediator::hasGraphAttribute
bool hasGraphAttribute(ElementType *element, const std::string &attributeName) const
Definition: StateModelLayoutMediator.h:81
armarx::EdgeList
QList< statechartmodel::TransitionCPtr > EdgeList
Definition: StateModelLayoutMediator.h:48
armarx::StateModelLayoutMediator::getID
size_t getID() const
getID Returns this mediator's id.
Definition: StateModelLayoutMediator.cpp:71
armarx::StateModelLayoutMediator::mediatorDeleted
void mediatorDeleted()
mediatorDeleted Tells worker that is has to be deleted.
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
armarx::StateModelLayoutMediator::stateChanged
void stateChanged(statechartmodel::SignalType signalType)
Definition: StateModelLayoutMediator.cpp:121
armarx::NodePtr
Agnode_t * NodePtr
Definition: Layout.h:42
armarx::statechartmodel::SignalType
SignalType
The SignalType enum.
Definition: SignalType.h:33
armarx::StateModelLayoutMediator::layoutingFinished
void layoutingFinished()
layoutingFinished Notifies that the latest layout task was finished.
armarx::statechartmodel::TransitionCPtr
std::shared_ptr< const Transition > TransitionCPtr
Definition: Transition.h:91
armarx::GraphvizConverter
Definition: GraphvizConverter.h:43
armarx::statechartmodel::StatePtr
std::shared_ptr< State > StatePtr
Definition: State.h:48
armarx::StateModelLayoutMediator::isConnected
bool isConnected()
isConnected Indicates whether this mediator is connected to a worker.
armarx::EdgePtr
Agedge_t * EdgePtr
Definition: Layout.h:43
armarx::StateModelLayoutMediator::boundingRectForAgraph
QRectF boundingRectForAgraph(Agraph_t *graph) const
Definition: StateModelLayoutMediator.cpp:275
armarx::SupportPoints
Definition: Transition.h:42
armarx::StateModelLayoutMediator::substateFound
void substateFound(statechartmodel::StateInstancePtr substate, statechartmodel::SignalType signalType)
substateFound To be emitted when a substate is found when building up the graph for the first time.
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27