1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation;
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 * Author: John Abraham <john.abraham@gatech.edu>
17 */
18
19 #include "routingstatsscene.h"
20 #include "textbubble.h"
21 #include "statisticsconstants.h"
22 #include "statsmode.h"
23 #include "animatormode.h"
24 #include "timevalue.h"
25
26 namespace netanim
27 {
28
29 RoutingStatsScene * pRoutingStatsScene = 0;
30
RoutingStatsScene()31 RoutingStatsScene::RoutingStatsScene ():QGraphicsScene (0, 0, STATSSCENE_WIDTH_DEFAULT, STATSSCENE_HEIGHT_DEFAULT)
32 {
33 m_lastX = 0;
34 m_lastY = 0;
35 m_lastTime = -1;
36 m_infoWidget = addWidget (new TextBubble ("Info:", "No data available\nDid you load the XML file?"));
37 showInfoWidget ();
38 }
39
40 RoutingStatsScene *
getInstance()41 RoutingStatsScene::getInstance ()
42 {
43 if (!pRoutingStatsScene)
44 {
45 pRoutingStatsScene = new RoutingStatsScene;
46 }
47 return pRoutingStatsScene;
48 }
49
50
51 void
addToProxyWidgetsMap(uint32_t nodeId,QString title,QString content)52 RoutingStatsScene::addToProxyWidgetsMap (uint32_t nodeId, QString title, QString content)
53 {
54
55 if (m_nodeIdProxyWidgets.find (nodeId) == m_nodeIdProxyWidgets.end ())
56 {
57 TextBubble * tb = new TextBubble (title, content);
58 QFont f (tb->font ());
59 f.setPointSizeF (StatsMode::getInstance ()->getCurrentFontSize ());
60 tb->setFont (f);
61 QGraphicsProxyWidget * pw = addWidget (tb);
62
63
64 QFontMetrics fm (f);
65 pw->setMaximumHeight (fm.height () * tb->text ().count ("\n"));
66 pw->adjustSize ();
67 showInfoWidget (false);
68 m_nodeIdProxyWidgets[nodeId] = pw;
69 qreal newX = m_lastX + pw->widget ()->width ();
70 if (newX >= sceneRect ().right ())
71 {
72 m_lastX = 0;
73 m_lastY += pw->widget ()->height () + INTERSTATS_SPACE;
74 }
75 pw->setPos (m_lastX, m_lastY);
76
77 m_lastX = pw->pos ().x () + pw->widget ()->width () + INTERSTATS_SPACE;
78 m_lastY = pw->pos ().y ();
79 m_bottomY = m_lastY + pw->widget ()->height ();
80 //qDebug (QString ("Last X" + QString::number (m_lastX) + " w:" + QString::number (pw->widget ()->width ())));
81 adjustRect ();
82 return;
83 }
84
85 }
86
87 uint32_t
getNodeCount()88 RoutingStatsScene::getNodeCount ()
89 {
90 return m_nodeIdProxyWidgets.size ();
91 }
92
93 void
add(uint32_t nodeId,qreal time,QString rt)94 RoutingStatsScene::add (uint32_t nodeId, qreal time, QString rt)
95 {
96 if (m_nodeIdTimeValues.find (nodeId) == m_nodeIdTimeValues.end ())
97 {
98 TimeValue <QString> tv;
99 tv.add (time, rt);
100 m_nodeIdTimeValues[nodeId] = tv;
101 addToProxyWidgetsMap (nodeId, "", rt);
102 return;
103 }
104 TimeValue <QString> & tv = m_nodeIdTimeValues[nodeId];
105 tv.add (time, rt);
106
107 }
108
109 void
addRp(uint32_t nodeId,QString destination,qreal time,RoutePathElementsVector_t elements)110 RoutingStatsScene::addRp (uint32_t nodeId, QString destination, qreal time, RoutePathElementsVector_t elements)
111 {
112 NodeIdDest_t nd = { nodeId, destination };
113 if (m_rps.find (nd) == m_rps.end ())
114 {
115 TimeValue <RoutePathElementsVector_t> tv;
116 tv.add (time, elements);
117 m_rps[nd] = tv;
118 return;
119 }
120 TimeValue <RoutePathElementsVector_t> & tv = m_rps[nd];
121 tv.add (time, elements);
122 }
123
124 RoutePathVector_t
getRoutePaths(qreal currentTime)125 RoutingStatsScene::getRoutePaths (qreal currentTime)
126 {
127 RoutePathVector_t routePaths;
128 for (NodeIdDestRPMap_t::const_iterator i = m_rps.begin ();
129 i != m_rps.end ();
130 ++i)
131 {
132 NodeIdDest_t nd = i->first;
133 TimeValue <RoutePathElementsVector_t> & v = m_rps[nd];
134 v.setCurrentTime (currentTime);
135 RoutePath_t rp = { nd, v.getCurrent () };
136 routePaths.push_back (rp);
137 }
138 return routePaths;
139 }
140
141 void
clearProxyWidgetsMap()142 RoutingStatsScene::clearProxyWidgetsMap ()
143 {
144 showInfoWidget ();
145 for (NodeIdProxyWidgetMap_t::const_iterator i = m_nodeIdProxyWidgets.begin ();
146 i != m_nodeIdProxyWidgets.end ();
147 ++i)
148 {
149
150 removeItem (i->second);
151 delete (i->second);
152
153 }
154 m_nodeIdProxyWidgets.clear ();
155 }
156
157 void
adjustRect()158 RoutingStatsScene::adjustRect ()
159 {
160 QRectF currentRect = sceneRect ();
161 QRectF newRect = QRectF (currentRect.topLeft (), QPointF (currentRect.bottomRight ().x (), m_bottomY));
162 setSceneRect (newRect);
163 }
164
165 void
test()166 RoutingStatsScene::test ()
167 {
168 for (uint32_t i=0; i < 100; ++i)
169 {
170 //qDebug (sceneRect (), "Scene Rect");
171 //add (i, "10.1.1.1~00:00:00:00:00:06", i+1, "10.1.1.1~00:00:00:00:00:06", "lp.linkDescription");
172 }
173 }
174
175 void
systemReset()176 RoutingStatsScene::systemReset ()
177 {
178 m_lastX = 0;
179 m_lastY = 0;
180 m_bottomY = 0;
181 clearProxyWidgetsMap ();
182 clearNodeIdTimeValues ();
183 }
184
185 void
clearNodeIdTimeValues()186 RoutingStatsScene::clearNodeIdTimeValues ()
187 {
188 m_nodeIdTimeValues.clear ();
189 }
190
191 void
showInfoWidget(bool show)192 RoutingStatsScene::showInfoWidget (bool show)
193 {
194 m_infoWidget->setVisible (show);
195 m_infoWidget->setPos (sceneRect ().width ()/2, sceneRect ().height ()/2);
196 }
197
198 void
updateContent(uint32_t nodeId,QGraphicsProxyWidget * pw)199 RoutingStatsScene::updateContent (uint32_t nodeId, QGraphicsProxyWidget *pw)
200 {
201 //qDebug ("Updating for :" + QString::number (nodeId));
202 TimeValue <QString> & v = m_nodeIdTimeValues[nodeId];
203 v.setCurrentTime (StatsMode::getInstance ()->getCurrentTime ());
204 TextBubble * tb = ( (TextBubble *)pw->widget ());
205 QFont f (tb->font ());
206 f.setPointSizeF (StatsMode::getInstance ()->getCurrentFontSize ());
207 tb->setFont (f);
208 QFontMetrics fm (f);
209 pw->setMaximumHeight (fm.height () * tb->text ().count ("\n"));
210 pw->adjustSize ();
211 tb->setText (v.getCurrent ());
212 }
213
214 void
reloadContent(bool force)215 RoutingStatsScene::reloadContent (bool force)
216 {
217 if (m_nodeIdProxyWidgets.empty ())
218 {
219 return;
220 }
221
222 m_lastX = 0;
223 m_lastY = 0;
224 m_bottomY = 0;
225 qreal currentTime = StatsMode::getInstance ()->getCurrentTime ();
226
227 qreal currentMaxHeight = 0;
228 for (NodeIdProxyWidgetMap_t::const_iterator i = m_nodeIdProxyWidgets.begin ();
229 i != m_nodeIdProxyWidgets.end ();
230 ++i)
231 {
232 QGraphicsProxyWidget * pw = i->second;
233
234 if ((force) || (!m_lastTime) || (m_lastTime != currentTime))
235 {
236 updateContent (i->first, pw);
237 }
238
239
240 bool nodeIsActive = StatsMode::getInstance ()->isNodeActive (i->first);
241 pw->setVisible (nodeIsActive);
242 if (nodeIsActive)
243 {
244 qreal newX = m_lastX + pw->size ().width ();
245 currentMaxHeight = qMax (currentMaxHeight, pw->size ().height ());
246 if (newX >= sceneRect ().right ())
247 {
248 m_lastX = 0;
249 m_lastY += currentMaxHeight + INTERSTATS_SPACE;
250 currentMaxHeight = 0;
251 }
252 pw->setPos (m_lastX, m_lastY);
253 m_lastX = pw->pos ().x () + pw->size ().width () + INTERSTATS_SPACE;
254 m_lastY = pw->pos ().y ();
255 m_bottomY = m_lastY + currentMaxHeight;
256 adjustRect ();
257 }
258
259 }
260
261 m_lastTime = currentTime;
262
263
264 }
265
266 } // namespace netanim
267