Qt 4.8
qdeclarativedebugtrace.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
43 
44 #include <QtCore/qdatastream.h>
45 #include <QtCore/qurl.h>
46 #include <QtCore/qtimer.h>
47 #include <QDebug>
48 
49 #ifdef CUSTOM_DECLARATIVE_DEBUG_TRACE_INSTANCE
50 
51 namespace {
52 
53  class GlobalInstanceDeleter
54  {
55  private:
57  public:
58  GlobalInstanceDeleter(QBasicAtomicPointer<QDeclarativeDebugTrace> &p)
59  : m_pointer(p)
60  {}
61  ~GlobalInstanceDeleter()
62  {
63  delete m_pointer;
64  m_pointer = 0;
65  }
66  };
67 
69 }
70 
71 
72 static QDeclarativeDebugTrace *traceInstance()
73 {
74  return QDeclarativeDebugTrace::globalInstance();
75 }
76 
77 QDeclarativeDebugTrace *QDeclarativeDebugTrace::globalInstance()
78 {
79  if (!s_globalInstance) {
80  // create default QDeclarativeDebugTrace instance if it is not explicitly set by setGlobalInstance(QDeclarativeDebugTrace *instance)
81  // thread safe implementation
83  if (!s_globalInstance.testAndSetOrdered(0, x))
84  delete x;
85  else
86  static GlobalInstanceDeleter cleanup(s_globalInstance);
87  }
88  return s_globalInstance;
89 }
90 
96 void QDeclarativeDebugTrace::setGlobalInstance(QDeclarativeDebugTrace *custom_instance)
97 {
98  if (!s_globalInstance.testAndSetOrdered(0, custom_instance)) {
99  qWarning() << "QDeclarativeDebugTrace::setGlobalInstance() - instance already set.";
100  delete custom_instance;
101  } else {
102  static GlobalInstanceDeleter cleanup(s_globalInstance);
103  }
104 }
105 
106 #else // CUSTOM_DECLARATIVE_DEBUG_TRACE_INSTANCE
108 #endif
109 
110 // convert to a QByteArray that can be sent to the debug client
111 // use of QDataStream can skew results if m_deferredSend == false
112 // (see tst_qdeclarativedebugtrace::trace() benchmark)
114 {
116  //### using QDataStream is relatively expensive
118  ds << time << messageType << detailType;
119  if (messageType == (int)QDeclarativeDebugTrace::RangeData)
120  ds << detailData;
121  if (messageType == (int)QDeclarativeDebugTrace::RangeLocation)
122  ds << detailData << line;
123  return data;
124 }
125 
127 : QDeclarativeDebugService(QLatin1String("CanvasFrameRate")),
128  m_enabled(false), m_deferredSend(true), m_messageReceived(false)
129 {
130  m_timer.start();
131  if (status() == Enabled) {
132  // wait for first message indicating whether to trace or not
133  while (!m_messageReceived)
134  waitForMessage();
135  }
136 }
137 
139 {
141  traceInstance()->addEventImpl(t);
142 }
143 
145 {
147  traceInstance()->startRangeImpl(t);
148 }
149 
151 {
153  traceInstance()->rangeDataImpl(t, data);
154 }
155 
157 {
159  traceInstance()->rangeDataImpl(t, data);
160 }
161 
163 {
165  traceInstance()->rangeLocationImpl(t, fileName, line);
166 }
167 
169 {
171  traceInstance()->rangeLocationImpl(t, fileName, line);
172 }
173 
175 {
177  traceInstance()->endRangeImpl(t);
178 }
179 
181 {
182  if (status() != Enabled || !m_enabled)
183  return;
184 
185  QDeclarativeDebugData ed = {m_timer.nsecsElapsed(), (int)Event, (int)event, QString(), -1};
186  processMessage(ed);
187 }
188 
190 {
191  if (status() != Enabled || !m_enabled)
192  return;
193 
194  QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeStart, (int)range, QString(), -1};
195  processMessage(rd);
196 }
197 
199 {
200  if (status() != Enabled || !m_enabled)
201  return;
202 
203  QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range, rData, -1};
204  processMessage(rd);
205 }
206 
208 {
209  if (status() != Enabled || !m_enabled)
210  return;
211 
212  QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range, rData.toString(QUrl::FormattingOption(0x100)), -1};
213  processMessage(rd);
214 }
215 
217 {
218  if (status() != Enabled || !m_enabled)
219  return;
220 
221  QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range, fileName, line};
222  processMessage(rd);
223 }
224 
226 {
227  if (status() != Enabled || !m_enabled)
228  return;
229 
230  QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range, fileName.toString(QUrl::FormattingOption(0x100)), line};
231  processMessage(rd);
232 }
233 
235 {
236  if (status() != Enabled || !m_enabled)
237  return;
238 
239  QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeEnd, (int)range, QString(), -1};
240  processMessage(rd);
241 }
242 
243 /*
244  Either send the message directly, or queue up
245  a list of messages to send later (via sendMessages)
246 */
248 {
249  if (m_deferredSend)
250  m_data.append(message);
251  else
252  sendMessage(message.toByteArray());
253 }
254 
255 /*
256  Send the messages queued up by processMessage
257 */
259 {
260  if (m_deferredSend) {
261  //### this is a suboptimal way to send batched messages
262  for (int i = 0; i < m_data.count(); ++i)
264  m_data.clear();
265 
266  //indicate completion
269  ds << (qint64)-1 << (int)Complete;
270  sendMessage(data);
271  }
272 }
273 
275 {
276  QByteArray rwData = message;
278 
279  stream >> m_enabled;
280 
281  m_messageReceived = true;
282 
283  if (!m_enabled)
284  sendMessages();
285 }
QString toString(FormattingOptions options=None) const
Returns the human-displayable string representation of the URL.
Definition: qurl.cpp:5896
static void addEvent(EventType)
static void rangeLocation(RangeType, const QString &, int)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
void processMessage(const QDeclarativeDebugData &)
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
The QString class provides a Unicode character string.
Definition: qstring.h:83
virtual bool event(QEvent *)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition: qobject.cpp:1200
#define Q_BASIC_ATOMIC_INITIALIZER(a)
Definition: qbasicatomic.h:218
void rangeDataImpl(RangeType, const QString &)
virtual void messageReceived(const QByteArray &)
void rangeLocationImpl(RangeType, const QString &, int)
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
static FILE * stream
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
Q_CORE_EXPORT void qWarning(const char *,...)
qint64 nsecsElapsed() const
Returns the number of nanoseconds since this QElapsedTimer was last started.
static const char * data(const QByteArray &arr)
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
void clear()
Removes all items from the list.
Definition: qlist.h:764
__int64 qint64
Definition: qglobal.h:942
FormattingOption
The formatting options define how the URL is formatted when written out as text.
Definition: qurl.h:70
static void endRange(RangeType)
static void startRange(RangeType)
Q_GLOBAL_STATIC(QDeclarativeDebugTrace, traceInstance)
QList< QDeclarativeDebugData > m_data
static void cleanup()
Definition: qpicture.cpp:1508
static void rangeData(RangeType, const QString &)
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:71
static QString fileName(const QString &fileUrl)
void start()
Starts this timer.
void sendMessage(const QByteArray &)