HAL
standard_graph_layouter.cpp
Go to the documentation of this file.
2 
7 #include "gui/gui_globals.h"
9 
10 #include <QDebug>
11 
12 namespace hal
13 {
14  StandardGraphLayouter::StandardGraphLayouter(GraphContext* context) : GraphLayouter(context), mParseLayout(true), mLayoutBoxes(true)
15  {
16  }
17 
19  {
20  return "Standard Layouter";
21  }
22 
24  {
25  return "<p>PLACEHOLDER</p>";
26  }
27 
28  void StandardGraphLayouter::add(const QSet<u32> modules, const QSet<u32> gates, const QSet<u32> nets, PlacementHint placement)
29  {
30  PlacementHint::PlacementModeType pmtype = placement.mode();
31 
32  if ((pmtype == PlacementHint::PreferLeft || pmtype == PlacementHint::PreferRight) &&
33  (!placement.preferredOrigin().id() || placement.preferredOrigin().type() == Node::None))
34  {
35  log_warning("gui", "Ignoring placement hint {} since no valid reference node was provided.",
36  (pmtype == PlacementHint::PreferLeft ? "PreferLeft" : "PreferRight"));
37  pmtype = PlacementHint::Standard;
38  }
39 
40  switch(pmtype)
41  {
43  addCompact(modules, gates, nets);
44  break;
46  addVertical(modules, gates, nets, true, placement.preferredOrigin());
47  break;
49  addVertical(modules, gates, nets, false, placement.preferredOrigin());
50  break;
52  addGridPosition(modules, gates, nets, placement.gridPosition());
53  break;
54  }
55 // qDebug() << "StandardGraphLayouter::add (box mod gat)" << boxes().size() << modules.size() << gates.size();
56  }
57 
58  void StandardGraphLayouter::addWaitToBeSeated(const QSet<u32>& modules, const QSet<u32>& gates, const QSet<u32>& nets)
59  {
60  Q_UNUSED(nets)
61 
62  CoordinateFromDataMap cfdMap(modules,gates);
63 
64  if (mPositionToNodeMap.isEmpty() &&
65  mParseLayout &&
67  cfdMap.good())
68  {
69  cfdMap.simplify();
70  for (auto it = cfdMap.begin(); it != cfdMap.end(); ++it)
71  setNodePosition(it.key(),it.value());
72  if (cfdMap.isPlacementComplete()) return;
73  }
74  else
75  cfdMap.clear();
76 
77  WaitToBeSeatedList wtbsl;
78  for (QSet<u32>::const_iterator it = modules.constBegin();
79  it != modules.constEnd(); ++it)
80  {
81  if (cfdMap.good() && cfdMap.placedModules().contains(*it))
82  continue; // already placed
83  wtbsl.add(new WaitToBeSeatedEntry(Node::Module, *it));
84  }
85 
86  for (QSet<u32>::const_iterator it = gates.constBegin();
87  it != gates.constEnd(); ++it)
88  {
89  if (cfdMap.good() && cfdMap.placedGates().contains(*it))
90  continue; // already placed
91  wtbsl.add(new WaitToBeSeatedEntry(Node::Gate, *it));
92  }
93 
94  wtbsl.setLinks();
95 
96  PositionGenerator pg;
97 
98  while(!wtbsl.placementDone())
99  {
100  QPoint p(pg.position());
101  while (positionToNodeMap().contains(p))
102  p = pg.next();
103  const WaitToBeSeatedEntry* wtbse = wtbsl.nextPlacement(p);
104  if (! wtbse) return;
105  Node pNode = wtbse->getNode();
106  setNodePosition(pNode, p);
107  }
108  }
109 
110  void StandardGraphLayouter::addCompact(const QSet<u32>& modules, const QSet<u32>& gates, const QSet<u32>& nets)
111  {
112  Q_UNUSED(nets)
113 
114  if (mLayoutBoxes)
115  {
116  addWaitToBeSeated(modules, gates, nets);
117  return;
118  }
119 
120  QList<Node> nodeList;
121  for (u32 id : modules)
122  nodeList.append(Node(id,Node::Module));
123  for (u32 id : gates)
124  nodeList.append(Node(id,Node::Gate));
125 
126  PositionGenerator pg;
127 
128  for (const Node& n : nodeList)
129  {
130  QPoint p(pg.position());
131  while (positionToNodeMap().contains(p))
132  p = pg.next();
133  setNodePosition(n, p);
134  }
135  }
136 
137  void StandardGraphLayouter::addGridPosition(const QSet<u32>& modules, const QSet<u32>& gates,
138  const QSet<u32>& nets, const QHash<Node,QPoint>& pos)
139  {
140  QList<Node> nodeList;
141  QList<Node> nodeNotPlaced;
142 
143  for (u32 id : modules)
144  nodeList.append(Node(id,Node::Module));
145  for (u32 id : gates)
146  nodeList.append(Node(id,Node::Gate));
147 
148  for (Node nd : nodeList)
149  {
150  auto it = pos.find(nd);
151  if (it == pos.constEnd())
152  nodeNotPlaced.append(nd);
153  else
154  {
155  QPoint p = it.value();
156  if (positionToNodeMap().contains(p))
157  nodeNotPlaced.append(nd);
158  else
159  setNodePosition(nd, p);
160  }
161  }
162 
163  if (!nodeNotPlaced.isEmpty())
164  {
165  QSet<u32> modsNotPlaced;
166  QSet<u32> gatsNotPlaced;
167  for (Node nd : nodeNotPlaced)
168  {
169  switch (nd.type()) {
170  case Node::Module:
171  modsNotPlaced.insert(nd.id());
172  break;
173  case Node::Gate:
174  gatsNotPlaced.insert(nd.id());
175  break;
176  default:
177  break;
178  }
179  }
180  addCompact(modsNotPlaced,gatsNotPlaced,nets);
181  }
182  }
183 
184  void StandardGraphLayouter::addVertical(const QSet<u32>& modules, const QSet<u32>& gates, const QSet<u32>& nets, bool left, const Node &preferredOrigin) {
185  Q_UNUSED(nets);
186 
187  int x;
188  int y;
189  NetLayoutPoint originPos = positonForNode(preferredOrigin);
190 
191  if (originPos.isUndefined())
192  {
193  // create a new column right- respectively leftmost of all current nodes
194  x = left ? minXIndex() - 1 : minXIndex() + xValues().size();
195  // center column of new ndoes vertically relative to the entire grid
196  y = minYIndex() + (yValues().size()-1) / 2;
197  }
198  else
199  {
200  // place all new nodes right respectively left of the origin node
201  x = originPos.x() + (left ? -1 : 1);
202  // vertically center the column of new nodes relative to the origin node
203  int totalNodes = modules.size() + gates.size();
204  y = originPos.y() - (totalNodes-1)/2;
205  }
206 
207  for (const u32 mid : modules)
208  {
209  Node n(mid, Node::Module);
210  QPoint p;
211  do
212  {
213  // skip over positions that are already taken
214  p = QPoint(x,y++);
215  }
216  while(positionToNodeMap().contains(p));
217  setNodePosition(n, p);
218  }
219  for (const u32 gid : gates)
220  {
221  Node n(gid, Node::Gate);
222  QPoint p;
223  do
224  {
225  // skip over positions that are already taken
226  p = QPoint(x,y++);
227  }
228  while(positionToNodeMap().contains(p));
229  setNodePosition(n, p);
230  }
231  }
232 
233  void StandardGraphLayouter::remove(const QSet<u32> modules, const QSet<u32> gates, const QSet<u32> nets)
234  {
235  Q_UNUSED(nets)
236 
237  for (u32 id : modules)
239 
240  for (u32 id : gates)
242  }
243 
245  {
246  return mParseLayout;
247  }
248 
250  {
251  mParseLayout = enabled;
252  }
253 
255  {
256  return mLayoutBoxes;
257  }
258 
260  {
261  mLayoutBoxes = enabled;
262  }
263 }
Utility class that stores the nodes that contained existing x and y coordinates.
Logical container for modules, gates, and nets.
Definition: graph_context.h:55
Base class for all specific layouters.
QVector< qreal > yValues() const
void setNodePosition(const Node &n, const QPoint &p)
void removeNodeFromMaps(const Node &n)
QVector< qreal > xValues() const
QMap< QPoint, Node > mPositionToNodeMap
const QMap< QPoint, Node > positionToNodeMap() const
NetLayoutPoint positonForNode(const Node &nd) const
The Node class object represents a module or a gate.
Definition: gui_def.h:61
NodeType type() const
type getter for type information
Definition: gui_def.h:71
@ Module
Definition: gui_def.h:63
@ Gate
Definition: gui_def.h:63
@ None
Definition: gui_def.h:63
u32 id() const
id getter for ID information
Definition: gui_def.h:77
The PlacementHint class object provides hints for the layouter how new box objects are placed on a vi...
Definition: gui_def.h:211
Node preferredOrigin() const
preferredOrigin getter for placement origin if any.
Definition: gui_def.h:246
PlacementModeType mode() const
mode getter for placement mode type
Definition: gui_def.h:238
PlacementModeType
The PlacementModeType enum either most compact arrangement (Standard) or to the left or right of give...
Definition: gui_def.h:217
const QHash< Node, QPoint > & gridPosition() const
Definition: gui_def.h:288
StandardGraphLayouter(GraphContext *context)
void add(const QSet< u32 > modules, const QSet< u32 > gates, const QSet< u32 > nets, PlacementHint placement) override
void remove(const QSet< u32 > modules, const QSet< u32 > gates, const QSet< u32 > nets) override
QString mDescription() const override
#define log_warning(channel,...)
Definition: log.h:76
FileStatusManager * gFileStatusManager
Definition: plugin_gui.cpp:84
n
Definition: test.py:6
quint32 u32
QHash::const_iterator constEnd() const const
QHash::iterator find(const Key &key)
void append(const T &value)
bool isEmpty() const const
QSet::const_iterator constBegin() const const
QSet::const_iterator constEnd() const const
QSet::iterator insert(const T &value)
int size() const const
QTextStream & left(QTextStream &stream)
int size() const const