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"
40#include "GraphvizConverter.h"
41#include "Layout.h"
43
44namespace 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 */
78
79 template <typename ElementType>
80 bool
81 hasGraphAttribute(ElementType* element, const std::string& attributeName) const
82 {
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 {
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 {
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 */
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 */
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
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 */
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
void stateChanged(statechartmodel::SignalType signalType)
void mediatorDeleted()
mediatorDeleted Tells worker that is has to be deleted.
bool hasGraphAttribute(ElementType *element, const std::string &attributeName) const
std::string getGraphAttribute(ElementType *element, const std::string &attributeName) const
void buildUpGraph(LockableGraphPtr graph)
buildUpGraph To be called when the corresponding worker initialized the graph.
statechartmodel::StatePtr getState() const
getState Returns the state associated with this mediator.
void startLayouting(bool layoutAll, int counter)
layout Tells the worker to layout edges and, if layoutAlgo is true, nodes of the graph.
int setGraphAttribute(ElementType *element, const std::string &attributeName, const ValueType &value) const
void supportPointsChanged(statechartmodel::TransitionCPtr transition, const SupportPoints &suppPoints, const QPointPtr &labelCenterPoint, const FloatPtr &labelFontPointSize)
supportPointsChanged Notifies of changed support points of the given transition.
QRectF boundingRectForAgraph(Agraph_t *graph) const
void scheduleMe(size_t id, bool layoutAll)
scheduleMe To be called when its graph should be layouted.
void substateChanged(statechartmodel::StateInstancePtr substate, statechartmodel::SignalType signalType)
substateAdded To be called when a substate of state has changed.
bool isConnected()
isConnected Indicates whether this mediator is connected to a worker.
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.
void layout(bool layoutAll)
layout Tells worker to layout the graph.
void transitionChanged(statechartmodel::TransitionCPtr transition, statechartmodel::SignalType signalType)
transitionAdded To be called when a transition of state has changed.
void layoutingFinished()
layoutingFinished Notifies that the latest layout task was finished.
void stateDeleted()
stateDeleted To be called when the corresponding state is deleted.
void workerFinishedLayouting()
workerFinishedLayouting To be called when the worker is finished layouting.
size_t getID() const
getID Returns this mediator's id.
void deleteMe(size_t id)
deleteMe To be emitted when this mediator and its worker ought to be deleted because their correspond...
StateModelLayoutMediator(statechartmodel::StatePtr state, size_t mediator_id)
LayoutWorker Sets state and id as specified.
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
std::shared_ptr< State > StatePtr
Definition State.h:48
std::shared_ptr< StateInstance > StateInstancePtr
std::shared_ptr< const Transition > TransitionCPtr
Definition Transition.h:91
SignalType
The SignalType enum.
Definition SignalType.h:34
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< QPointF > QPointPtr
Definition Transition.h:40
std::shared_ptr< LockableGraph > LockableGraphPtr
Definition Layout.h:64
std::map< statechartmodel::StateInstancePtr, std::string > NodeMap
QList< statechartmodel::TransitionCPtr > EdgeList
ElementTypes::ElementType ElementType
Agnode_t * NodePtr
Definition Layout.h:42
Agedge_t * EdgePtr
Definition Layout.h:43
std::shared_ptr< float > FloatPtr
Definition Transition.h:39
std::string ValueToString(const T &value)