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