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 "../model/SignalType.h"
27 #include "../model/State.h"
28 #include "../model/stateinstance/StateInstance.h"
29 #include "../model/Transition.h"
30 #include "GraphvizConverter.h"
31 #include "Layout.h"
33 
34 #include <QList>
35 #include <QObject>
36 #include <QPointF>
37 #include <QSizeF>
38 #include <QString>
39 
40 #include <map>
41 #include <memory>
42 #include <string>
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 hasGraphAttribute(ElementType* element, const std::string& attributeName) const
81  {
82  ARMARX_CHECK_EXPRESSION(element);
83  char* value = agget(element, const_cast<char*>(attributeName.c_str()));
84  return value != NULL;
85  }
86 
87  template <typename ElementType>
88  std::string getGraphAttribute(ElementType* element, const std::string& attributeName) const
89  {
90  ARMARX_CHECK_EXPRESSION(element);
91  char* value = agget(element, const_cast<char*>(attributeName.c_str()));
92  ARMARX_CHECK_EXPRESSION(value) << "Could not get attribute '" << attributeName << "'' from element";
93  return std::string(value);
94  }
95 
96  template <typename ElementType, typename ValueType>
97  int setGraphAttribute(ElementType* element, const std::string& attributeName, const ValueType& value) const
98  {
99  ARMARX_CHECK_EXPRESSION(element);
100  // ARMARX_INFO_S << "Setting " << attributeName << " to " << ValueToString(value);
101  return agsafeset(element, const_cast<char*>(attributeName.c_str()), const_cast<char*>(ValueToString(value).c_str()), const_cast<char*>(""));
102  }
103  QRectF boundingRectForAgraph(Agraph_t* graph) const;
104  signals:
105  /**
106  * @brief supportPointsChanged Notifies of changed support points of the given transition.
107  * @param transition Transition whose support points have changed.
108  * @param suppPoints New support points.
109  */
110  void supportPointsChanged(statechartmodel::TransitionCPtr transition, const SupportPoints& suppPoints, const QPointPtr& labelCenterPoint, const FloatPtr& labelFontPointSize);
111 
112  /**
113  * @brief layout Tells worker to layout the graph.
114  * @param layoutAll True: layout nodes and edgese. False: layout only edges.
115  */
116  void layout(bool layoutAll);
117  /**
118  * @brief layoutingFinished Notifies that the latest layout task was finished.
119  */
120  void layoutingFinished();
121 
122  /**
123  * @brief scheduleMe To be called when its graph should be layouted. Is meant for the Controller
124  * to schedule this mediator in its layout queue.
125  * @param id This mediator's id.
126  * @param layoutAll Indicates whether the whole graph (including nodes) should be layouted or only
127  * the edges.
128  */
129  void scheduleMe(size_t id, bool layoutAll);
130 
131  /**
132  * @brief deleteMe To be emitted when this mediator and its worker ought to be deleted because
133  * their corresponding state was deleted.
134  * @param id This mediator's id.
135  */
136  void deleteMe(size_t id);
137  /**
138  * @brief mediatorDeleted Tells worker that is has to be deleted.
139  */
140  void mediatorDeleted();
141 
142  /**
143  * @brief substateFound To be emitted when a substate is found when building up the graph for the
144  * first time.
145  * @param substate The substate that was discovered.
146  * @param signalType Type of change to the substate. Should be eAdded.
147  */
149 
150  public slots:
151  /**
152  * @brief buildUpGraph To be called when the corresponding worker initialized the graph. Traverses
153  * the state and adds all transitions and states to the graph as well as to EdgeList and NodeMap.
154  * @param graph The graphviz graph that shall represent the state.
155  */
156  void buildUpGraph(LockableGraphPtr graph);
157 
158 
159  void stateChanged(statechartmodel::SignalType signalType);
160 
161  /**
162  * @brief substateAdded To be called when a substate of state has changed.
163  * @param substate The changed substate.
164  * @param signalType The type of signal (added, removed, moved etc.).
165  */
167 
168  /**
169  * @brief transitionAdded To be called when a transition of state has changed.
170  * @param transition The changed transition.
171  * @param signalType The type of signal (added, removed, moved etc.).
172  */
174 
175  /**
176  * @brief layout Tells the worker to layout edges and, if layoutAlgo is true, nodes of the graph.
177  * Signals changes of positions to the state.
178  * @param layoutAll If true, nodes and edges are layouted, if false, node positions are assumed
179  * to be fixed and only edges are routed.
180  */
181  void startLayouting(bool layoutAll, int counter);
182 
183  /**
184  * @brief workerFinishedLayouting To be called when the worker is finished layouting.
185  * Notifies the controller.
186  */
188 
189  /**
190  * @brief stateDeleted To be called when the corresponding state is deleted.
191  */
192  void stateDeleted();
193 
194  private:
195 
196  bool updateInitialTransition(statechartmodel::TransitionCPtr transition, statechartmodel::SignalType signalType);
197 
198 
199  QPointF convertPositionFromGraphViz(QPointF gvPos) const;
200  float convertScaleFromGraphViz() const;
201  QPointF convertPositionToGraphViz(QPointF statePos) const;
202 
203  /**
204  * @brief IsConnectedToWorker Indicates whether this mediator is already connected to a worker.
205  * Necessary for the createAllWorkers() function of LayoutController.
206  */
207  bool isConnectedToWorker;
208  /**
209  * @brief id ID of this mediator. Used for communication with the LayoutController.
210  */
211  size_t id;
212 
213  /**
214  * @brief state The state whose subgraph is layouted by this mediator's worker.
215  */
217 
218  /**
219  * @brief converter Converts strings from graphviz to the corresponding point or splineType.
220  */
221  //TODO: Funktionen aus GraphvizConverter allein stehend machen. Converter hier und in SplinePath
222  // eliminieren
223  GraphvizConverter converter;
224 
225  /**
226  * @brief graph Graphviz graph that represents the subgraph of state and a mutex to lock it.
227  */
228  LockableGraphPtr m_graph;
229  /**
230  * @brief substateMap maps the substates of state to the name of their corresponding graphviz node.
231  * Necessary for changing the name of a node.
232  */
233  NodeMap substateMap;
234  /**
235  * @brief transitionMap maps the transitions of state to the label of their corresponding graphviz
236  * edge. Necessary for informing the state of all transition changes.
237  */
238  EdgeList transitionList;
239 
240  NodePtr invisibleStartNode;
241  EdgePtr initialTransition;
242 
243  QRectF graphVizBB;
244 
245  QSizeF dpi;
246  int layoutRepetition;
247 
248  /**
249  * @brief addNode Adds a node with the given name to the graph and to substateMap.
250  * @param substate The substate for which a node is added.
251  */
252  void addNode(statechartmodel::StateInstancePtr substate);
253  /**
254  * @brief removeNode Removes a node and its adjacent edges from the graph and from substateMap/
255  * transitionMap.
256  * @param substate The substate for which the node is removed.
257  */
258  void removeNode(statechartmodel::StateInstancePtr substate);
259  /**
260  * @brief setNodeAttribute Sets the attribute of the node belonging to substate.
261  * @param substate Substate that is represented by the node whose attribute is to be set.
262  * @param attributeName Name of the attribute, e.g. "pos".
263  * @param attributeValue Value of the attribute.
264  */
265  void setNodeAttribute(statechartmodel::StateInstancePtr substate, const std::string& attributeName,
266  const std::string& attributeValue);
267  /**
268  * @brief getNodeAttribute Returns the attribute of the node belonging to substate.
269  * @param substate Substate that is represented by the node whose attribute is returned.
270  * @param attributeName Name of the attribute, e.g. "pos".
271  * @return Value of the attribute.
272  */
273  std::string getNodeAttribute(statechartmodel::StateInstancePtr substate, const std::string& attributeName);
274  bool hasNodeAttribute(armarx::statechartmodel::StateInstancePtr substate, const std::string& attributeName);
275 
276  /**
277  * @brief getNodeName Returns the name of the given node. NOT THREAD-SAFE! LOCK GRAPH BEFORE USAGE!
278  * @param node A node of the graph.
279  * @return
280  */
281  std::string getNodeName(NodePtr node);
282  /**
283  * @brief getNode Return the node with the given name. NOT THREAD-SAFE! LOCK GRAPH BEFORE USAGE!
284  * @param name Name of the node.
285  * @return Returns the node with the given name or NULL if no such node exists.
286  */
287  NodePtr getNode(const std::string& name);
288  /**
289  * @brief getNode Return the node belonging to the substate. NOT THREAD-SAFE! LOCK GRAPH BEFORE USAGE!
290  * @param substate Substate whose node is returned.
291  * @return Returns the node belonging to substate or NULL if no such node exists.
292  */
293  NodePtr getNode(statechartmodel::StateInstancePtr substate);
294 
295 
296  /**
297  * @brief addEdge Adds a node to the graph with source, destination and name as specified by
298  * transition and to transitionList.
299  * @param transition The transition to be represented by the edge
300  * @return Pointer to the newly created edge
301  */
302  void addEdge(statechartmodel::TransitionCPtr transition);
303  /**
304  * @brief removeEdge Removes the node corresponding to transition from the graph and transitionList.
305  * @param transition Transition for which the edge is removed.
306  */
307  void removeEdge(statechartmodel::TransitionCPtr transition);
308  /**
309  * @brief setEdgeAttribute Sets the attribute of the edge belonging to transition.
310  * @param transition Transition represented by the edge whose attribute is set.
311  * @param attributeName Name of the attribute, e.g. "pos".
312  * @param attributeValue Value of the attribute.
313  */
314  void setEdgeAttribute(statechartmodel::TransitionCPtr transition, std::string attributeName,
315  std::string attributeValue);
316  /**
317  * @brief getEdgeAttribute Gets the attribute of the edge belonging to transition.
318  * @param transition Transition represented by the edge whose attribute is returned.
319  * @param attributeName Name of the attribute, e.g. "pos".
320  * @return Value of the attribute.
321  */
322  std::string getEdgeAttribute(statechartmodel::TransitionCPtr transition, std::string attributeName);
323  bool hasEdgeAttribute(statechartmodel::TransitionCPtr transition, std::string attributeName);
324  /**
325  * @brief getEdge Return the edge belonging to the transition. NOT THREAD-SAFE! LOCK GRAPH BEFORE USAGE!
326  * @param transition Transition whose edge is returned.
327  * @return Returns the edge belonging to transition or NULL if none exists.
328  */
329  EdgePtr getEdge(statechartmodel::TransitionCPtr transition);
330 
331 
332  /**
333  * @brief updatePositionAndDimension Compares the stored and the new position of substate and
334  * updates it if necessary.
335  * @param substate Substate whose position is updated.
336  */
337  bool updateNodePositionAndDimension(statechartmodel::StateInstancePtr substate);
338  /**
339  * @brief updateName Compares the stored and the new name of substate and updates it
340  * if necessary.
341  * @param substate Substate whose name is updated.
342  */
343  void updateNodeName(statechartmodel::StateInstancePtr substate);
344  /**
345  * @brief updateLabel If necessary, updates the label of the edge belonging to this transition.
346  * @param transition Transitions whose name changed.
347  */
348  void updateEdgeLabel(statechartmodel::TransitionCPtr transition);
349  /**
350  * @brief updateTargetAndSource Compares the old and the new target and source nodes of the transition
351  * and updates them if necessary.
352  * @param transition Transition whose target or source state might have changed.
353  */
354  void updateEdgeTargetAndSource(statechartmodel::TransitionCPtr transition);
355  /**
356  * @brief updateEdgePosition If necessary updates the position of the edge belonging to
357  * transition.
358  * @param transition Transition whose position might have changed.
359  */
360  void updateEdgePosition(statechartmodel::TransitionCPtr transition);
361 
362  /**
363  * @brief broadcastSubstatePositions Sends signals to the state for every substate containing their
364  * present position
365  */
366  void broadcastSubstatePositions();
367  /**
368  * @brief broadcastTransitionSupportPoints Sends signals to state for every transition containing
369  * their present support points.
370  */
371  void broadcastTransitionSupportPoints();
372 
373  /**
374  * @brief transitionRepresentable Returns true if transition can be represented in a graphviz graph.
375  * @param transition The transition who shall be represented.
376  * @return True if transition has a source and destination state. 'Detached' edges don't exist
377  * in graphviz.
378  */
379  bool transitionRepresentable(statechartmodel::TransitionCPtr transition);
380  };
381 } //namespace armarx
382 
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:275
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:88
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:205
armarx::FloatPtr
std::shared_ptr< float > FloatPtr
Definition: Transition.h:40
armarx::StateModelLayoutMediator::getState
statechartmodel::StatePtr getState() const
getState Returns the state associated with this mediator.
Definition: StateModelLayoutMediator.cpp:63
armarx::StateModelLayoutMediator::buildUpGraph
void buildUpGraph(LockableGraphPtr graph)
buildUpGraph To be called when the corresponding worker initialized the graph.
Definition: StateModelLayoutMediator.cpp:75
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:150
StateModelLayoutMediator.h
armarx::StateModelLayoutMediator::stateDeleted
void stateDeleted()
stateDeleted To be called when the corresponding state is deleted.
Definition: StateModelLayoutMediator.cpp:293
armarx::statechartmodel::StateInstancePtr
std::shared_ptr< StateInstance > StateInstancePtr
Definition: StateInstance.h:138
armarx::QPointPtr
std::shared_ptr< QPointF > QPointPtr
Definition: Transition.h:41
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:257
Layout.h
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
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:58
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:97
armarx::StateModelLayoutMediator::StateModelLayoutMediator
StateModelLayoutMediator(statechartmodel::StatePtr state, size_t mediator_id)
LayoutWorker Sets state and id as specified.
Definition: StateModelLayoutMediator.cpp:48
armarx::ElementTypes::ElementType
ElementType
Definition: AbstractObjectSerializer.h:32
armarx::StateModelLayoutMediator::hasGraphAttribute
bool hasGraphAttribute(ElementType *element, const std::string &attributeName) const
Definition: StateModelLayoutMediator.h:80
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:68
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:118
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:94
armarx::GraphvizConverter
Definition: GraphvizConverter.h:43
armarx::statechartmodel::StatePtr
std::shared_ptr< State > StatePtr
Definition: State.h:46
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:265
armarx::SupportPoints
Definition: Transition.h:43
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:28