HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
wave_item.cpp
Go to the documentation of this file.
1 #include <QPainter>
6 #include <QGraphicsScene>
7 #include <QTextStream>
8 #include <math.h>
9 #include <QColor>
10 #include <QScrollBar>
11 #include <QDebug>
12 #include <QThread>
13 
14 namespace hal {
15 
16  const char* WaveItem::sBackgroundColor = "#0D293E" ;
17 
19  : QObject(parent), mData(dat), mLoader(nullptr), mLoadProgress(0), mState(Null),
20  mVisibleRange(false), mLoop(false),
21  mYposition(-1), mRequest(0), mMinTime(0),
22  mMaxTime(1000), mMaxTransition(0),
23  mVisibile(true), mSelected(false)
24  {
25  if (mData) mData->addSubscriber();
26  }
27 
29  {
30  if (mData) mData->removeSubscriber();
31  }
32 
33  void WaveItem::setYposition(int pos)
34  {
35  if (mYposition == pos) return;
36  mYposition = pos;
38  }
39 
41  {
42  mData = wd;
44  }
45 
46  void WaveItem::setWaveVisible(bool vis)
47  {
48  if (mVisibile==vis) return;
49  mVisibile = vis;
51  }
52 
54  {
55  if (mSelected==sel) return;
56  mSelected = sel;
58  }
59 
61  {
62  float tmin, tmax;
63  /* TODO
64  if (scene() && scene()->sceneRect().width() > 1)
65  {
66  tmin = scene()->sceneRect().left();
67  tmax = scene()->sceneRect().right();
68  }
69  else
70  {
71  */
72  tmin = 0;
73  tmax = 1000;
74  //}
75  if (tmin == mMinTime && tmax == mMaxTime) return false;
76  mMinTime = tmin;
77  mMaxTime = tmax;
78  return true;
79  }
80 
81 
83  {
85  setState(Null);
86  }
87 
88  void WaveItem::startGeneratePainted(const QString& workdir, const WaveTransform* trans, const WaveScrollbar* sbar, const WaveDataTimeframe& tframe)
89  {
90  // precondition: mutex lock is set, state is Null
91  mLoadProgress = 0;
92 
93  if (mData->loadPolicy() != WaveData::TooBigToLoad)
94  {
95  if ((u64)mData->data().size() < mData->fileSize())
96  {
97  // load map
99  startLoader(workdir, trans, sbar, tframe);
100  }
101  else
102  {
103  // generate from existing map
104  deletePainted();
105  if (!mData->data().isEmpty())
106  {
107  WaveDataProviderMap wdp(mData->data());
108  wdp.setWaveType(mData->netType(),mData->bits(),mData->valueBase());
109  mPainted.generate(&wdp,trans,sbar,&mLoop);
112  }
113  }
114  }
115  else
116  {
117  // graphics from file
119  startLoader(workdir,trans, sbar, tframe);
120  }
121  }
122 
123  void WaveItem::startLoader(const QString& workdir, const WaveTransform* trans, const WaveScrollbar* sbar, const WaveDataTimeframe& tframe)
124  {
125  Q_ASSERT(mState == Loading);
126  mLoadValidity = WaveZoomShift(trans,sbar);
127  if (mLoader)
128  {
129  qDebug() << mData->fileIndex() << "*** warning *** : loader already running";
130  }
131  mLoader = new WaveLoaderThread(this, workdir, trans, sbar, tframe);
133  mLoader->start();
134  }
135 
137  {
138  if (mState == stat) return;
139  // qDebug() << mFileIndex << "state change" << mState << "->" << stat;
140  mState = stat;
141  if (mState == Painted)
142  {
143  mLoadProgress = 0;
144  mData->setDirty(false);
145  }
146  if (mState == Null)
147  mLoadProgress = 0;
148  }
149 
151  {
152  mLoadProgress += 5;
153  if (mLoadProgress >= mLoadValidity.width())
154  mLoadProgress = 5;
155  }
156 
157  void WaveItem::dump(QTextStream &xout) const
158  {
159  if (isPainted())
160  xout << mData->id() << mData->name() << mState << mData->data().size() << mPainted.numberPrimitives() << mPainted.x0() << mPainted.x1() << "\n";
161  else
162  xout << mData->id() << mData->name() << mState << mData->data().size() << "\n";
163 
164  }
165 
166  int WaveItem::cursorValue(double tCursor, int xpos)
167  {
168  // can deliver stored value
169  int retval = mPainted.cursorValueStored(tCursor,xpos);
170  if (retval != SaleaeDataTuple::sReadError) return retval;
171 
172  // get clock value
173  if (mData->netType() == WaveData::ClockNet)
174  {
175  SimulationInput::Clock clk = static_cast<const WaveDataClock*>(mData)->clock();
176  quint64 ntrans = floor(tCursor/clk.switch_time);
177  retval = clk.start_at_zero ? ntrans % 2 : 1 - ntrans % 2;
178  mPainted.setCursorValue(tCursor,xpos,retval);
180  return retval;
181  }
182 
183  // get value from memory map
184  if (mData->loadPolicy() != WaveData::TooBigToLoad)
185  {
186  if (mData->data().isEmpty())
187  {
188  if (isGroup())
189  {
190  WaveDataGroup* wdGrp = static_cast<WaveDataGroup*>(mData);
191  wdGrp->recalcData();
192  }
193  else if (isBoolean())
194  {
195  WaveDataBoolean* wdBool = static_cast<WaveDataBoolean*>(mData);
196  wdBool->recalcData();
197  }
198  else if (isTrigger())
199  {
200  WaveDataTrigger* wdTrig = static_cast<WaveDataTrigger*>(mData);
201  wdTrig->recalcData();
202  }
203  else
205  }
206  if (!mData->data().isEmpty())
207  {
208  retval = mData->intValue(tCursor);
209  mPainted.setCursorValue(tCursor,xpos,retval);
211  return retval;
212  }
213  }
214 
215  // try get from painted primitives, will store time
216  if (isTrigger())
217  retval = mPainted.cursorValueTrigger(tCursor,xpos);
218  else
219  retval = mPainted.cursorValuePainted(tCursor,xpos);
220  return retval;
221  }
222 
224  {
225  setState(Aborted);
226  mLoop = false;
227  }
228 
230  {
231  mMutex.lock();
232 
233  if (isAborted())
234  {
235  setState(Null);
236  deletePainted();
237  }
238  else if (isFinished())
239  {
240  setState(Painted);
241  }
242  else
243  qDebug() << mData->fileIndex() << "invalid state when terminating thread" << mState << hex << (quintptr) mLoader << dec;
244  mLoader->deleteLater();
245  mLoader = nullptr;
246  mMutex.unlock();
247  if (mState == Painted && mVisibleRange)
248  {
251  }
252  }
253 
255  {
256  mData->loadSaleae();
257  }
258 
259 
261  {
262  int mask = 1 << rq;
263  return (mRequest & mask) != 0;
264  }
265 
267  {
268  int mask = 1 << rq;
269  mRequest |= mask;
270  }
271 
273  {
274  int mask = ~(1 << rq);
275  mRequest &= mask;
276  }
277 
278  bool WaveItem::isDeleted() const
279  {
281  }
282 
283 
284  bool WaveItemIndex::operator==(const WaveItemIndex &other) const
285  {
286  return mType == other.mType && mIndex == other.mIndex && mParentId == other.mParentId;
287  }
288 
289  uint qHash(const WaveItemIndex& wii)
290  {
291  if (!wii.isValid()) return 0;
292  return (wii.parentId() << 20) | ((wii.index()+1) << 3) | wii.intType();
293  }
294 
296  {
297  QSet<u32> ids;
298  for (const WaveItemIndex& wii : keys())
299  {
300  if (wii.isWire()) ids.insert(wii.index());
301  }
302  return ids.size();
303  }
304 
306  {
307  WaveItemIndex wii(iwave, tp, parentId);
308  WaveItem* wi = value(wii);
309  if (!wi)
310  {
311  wi = new WaveItem(wd);
312  insert(wii,wi);
314  }
315  else
316  wi->setWaveData(wd);
317  return wi;
318  }
319 
321  {
322  if (!wi) return;
324  mTrashCan.append(wi);
325  }
326 
328  {
329  auto it = mTrashCan.begin();
330  while (it != mTrashCan.end())
331  {
332  WaveItem* wi = *it;
333  switch (wi->state())
334  {
335  case WaveItem::Null:
336  case WaveItem::Painted:
338  it = mTrashCan.erase(it);
339  wi->deleteLater();
340  break;
341  case WaveItem::Loading:
342  if (wi->hasLoader())
343  wi->abortLoader();
344  ++it;
345  break;
346  default:
347  ++it;
348  break;
349  }
350  }
351  }
352 
353  void WaveItemHash::dump(const char* stub)
354  {
355  Q_UNUSED(stub);
356  // TODO
357  }
358 }
static const int sReadError
Fake data value to indicate all kind of errors.
Definition: saleae_file.h:165
virtual void recalcData()
Definition: wave_data.cpp:1144
bool loadSaleae(const WaveDataTimeframe &tframe=WaveDataTimeframe())
Definition: wave_data.cpp:270
void setDirty(bool dty)
Definition: wave_data.h:117
virtual int intValue(double t) const
Definition: wave_data.cpp:454
virtual LoadPolicy loadPolicy() const
Definition: wave_data.cpp:75
void removeSubscriber()
Definition: wave_data.h:147
void addSubscriber()
Definition: wave_data.h:146
int fileIndex() const
Definition: wave_data.h:109
u64 fileSize() const
Definition: wave_data.h:110
int valueBase() const
Definition: wave_data.h:111
void loadDataUnlessAlreadyLoaded()
Definition: wave_data.cpp:264
const QMap< u64, int > & data() const
Definition: wave_data.h:108
NetType netType() const
Definition: wave_data.h:105
QString name() const
Definition: wave_data.h:104
virtual int bits() const
Definition: wave_data.h:106
u32 id() const
Definition: wave_data.h:103
void setWaveType(WaveData::NetType type, int bts=1, int base=16)
void setCursorValue(u64 tCursor, int xpos, int val)
int numberPrimitives() const
int cursorValuePainted(u64 tCursor, int xpos)
int cursorValueTrigger(u64 tCursor, int xpos)
void generate(WaveDataProvider *wdp, const WaveTransform *trans, const WaveScrollbar *sbar, bool *loop)
int cursorValueStored(u64 tCursor, int xpos) const
int importedWires() const
Definition: wave_item.cpp:295
void dump(const char *stub)
Definition: wave_item.cpp:353
void dispose(WaveItem *wi)
Definition: wave_item.cpp:320
WaveItem * addOrReplace(WaveData *wd, WaveItemIndex::IndexType tp, int iwave, int parentId)
Definition: wave_item.cpp:305
void handleWaveLoaderFinished()
Definition: wave_item.cpp:229
void doneLoading()
bool hasLoader() const
Definition: wave_item.h:124
bool hasRequest(Request rq) const
Definition: wave_item.cpp:260
bool setTimeframe()
Definition: wave_item.cpp:60
void abortLoader()
Definition: wave_item.cpp:223
void setState(State stat)
Definition: wave_item.cpp:136
void setWaveData(WaveData *wd)
Definition: wave_item.cpp:40
bool isAborted() const
Definition: wave_item.h:115
int cursorValue(double tCursor, int xpos)
Definition: wave_item.cpp:166
bool isBoolean() const
Definition: wave_item.h:145
void startLoader(const QString &workdir, const WaveTransform *trans, const WaveScrollbar *sbar, const WaveDataTimeframe &tframe)
Definition: wave_item.cpp:123
State state() const
Definition: wave_item.h:126
@ DeleteAcknowledged
Definition: wave_item.h:74
@ SelectionChanged
Definition: wave_item.h:74
bool isTrigger() const
Definition: wave_item.h:146
void setWaveVisible(bool vis)
Definition: wave_item.cpp:46
bool isFinished() const
Definition: wave_item.h:114
bool isDeleted() const
Definition: wave_item.cpp:278
void setRequest(Request rq)
Definition: wave_item.cpp:266
WaveItem(WaveData *dat, QObject *parent=nullptr)
Definition: wave_item.cpp:18
void startGeneratePainted(const QString &workdir, const WaveTransform *trans, const WaveScrollbar *sbar, const WaveDataTimeframe &tframe)
Definition: wave_item.cpp:88
void dump(QTextStream &xout) const
Definition: wave_item.cpp:157
bool mVisibleRange
Definition: wave_item.h:86
WaveFormPainted mPainted
Definition: wave_item.h:83
QMutex mMutex
Definition: wave_item.h:85
void setYposition(int pos)
Definition: wave_item.cpp:33
bool isPainted() const
Definition: wave_item.h:113
WaveZoomShift mLoadValidity
Definition: wave_item.h:84
void incrementLoadProgress()
Definition: wave_item.cpp:150
bool isGroup() const
Definition: wave_item.h:144
void loadSaleae()
Definition: wave_item.cpp:254
void deletePainted()
Definition: wave_item.cpp:82
void gotCursorValue()
static const char * sBackgroundColor
Definition: wave_item.h:143
void clearRequest(Request rq)
Definition: wave_item.cpp:272
void setWaveSelected(bool sel)
Definition: wave_item.cpp:53
u32 parentId() const
Definition: wave_item.h:61
u32 index() const
Definition: wave_item.h:60
bool isValid() const
Definition: wave_item.h:56
u32 intType() const
Definition: wave_item.h:59
bool operator==(const WaveItemIndex &other) const
Definition: wave_item.cpp:284
uint64_t u64
Definition: defines.h:42
Definition: defines.h:45
uint qHash(const LaneIndex &ri)
QHash::iterator insert(const Key &key, const T &value)
QList< Key > keys() const const
const T value(const Key &key) const const
bool isEmpty() const const
int size() const const
void lock()
void unlock()
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void deleteLater()
QSet::iterator insert(const T &value)
int size() const const
void finished()
void start(QThread::Priority priority)