1/****************************************************************************
2**
3** Copyright (C) 2018 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtSCriptTools 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 The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qscriptdebuggerfrontend_p.h"
41#include "qscriptdebuggerfrontend_p_p.h"
42#include "qscriptdebuggercommand_p.h"
43#include "qscriptdebuggerevent_p.h"
44#include "qscriptdebuggerresponse_p.h"
45#include "qscriptdebuggereventhandlerinterface_p.h"
46#include "qscriptdebuggerresponsehandlerinterface_p.h"
47
48#include <QtCore/qcoreevent.h>
49#include <QtCore/qcoreapplication.h>
50
51QT_BEGIN_NAMESPACE
52
53/*!
54 \class QScriptDebuggerFrontend
55 \since 4.5
56 \internal
57
58 \brief The QScriptDebuggerFrontend class is the base class of debugger front-ends.
59*/
60
61// helper class that's used to handle our custom Qt events
62class QScriptDebuggerFrontendEventReceiver : public QObject
63{
64public:
65 QScriptDebuggerFrontendEventReceiver(QScriptDebuggerFrontendPrivate *frontend,
66 QObject *parent = 0);
67 ~QScriptDebuggerFrontendEventReceiver();
68
69 bool event(QEvent *);
70
71private:
72 QScriptDebuggerFrontendPrivate *m_frontend;
73};
74
75QScriptDebuggerFrontendEventReceiver::QScriptDebuggerFrontendEventReceiver(
76 QScriptDebuggerFrontendPrivate *frontend, QObject *parent)
77 : QObject(parent), m_frontend(frontend)
78{
79}
80
81QScriptDebuggerFrontendEventReceiver::~QScriptDebuggerFrontendEventReceiver()
82{
83}
84
85bool QScriptDebuggerFrontendEventReceiver::event(QEvent *e)
86{
87 return m_frontend->event(e);
88}
89
90
91QScriptDebuggerFrontendPrivate::QScriptDebuggerFrontendPrivate()
92{
93 eventHandler = 0;
94 nextCommandId = 0;
95 eventReceiver = new QScriptDebuggerFrontendEventReceiver(this);
96}
97
98QScriptDebuggerFrontendPrivate::~QScriptDebuggerFrontendPrivate()
99{
100 delete eventReceiver;
101}
102
103void QScriptDebuggerFrontendPrivate::postEvent(QEvent *e)
104{
105 QCoreApplication::postEvent(receiver: eventReceiver, event: e);
106}
107
108bool QScriptDebuggerFrontendPrivate::event(QEvent *e)
109{
110 Q_Q(QScriptDebuggerFrontend);
111 if (e->type() == QEvent::User+1) {
112 QScriptDebuggerEventEvent *de = static_cast<QScriptDebuggerEventEvent*>(e);
113 bool handled = q->notifyEvent(event: de->event());
114 if (handled) {
115 q->scheduleCommand(command: QScriptDebuggerCommand::resumeCommand(),
116 /*responseHandler=*/0);
117 }
118 return true;
119 } else if (e->type() == QEvent::User+2) {
120 processCommands();
121 return true;
122 }
123 return false;
124}
125
126void QScriptDebuggerFrontendPrivate::processCommands()
127{
128 Q_Q(QScriptDebuggerFrontend);
129 while (!pendingCommands.isEmpty()) {
130 QScriptDebuggerCommand command(pendingCommands.takeFirst());
131 int id = pendingCommandIds.takeFirst();
132 q->processCommand(id, command);
133 }
134}
135
136QScriptDebuggerFrontend::QScriptDebuggerFrontend()
137 : d_ptr(new QScriptDebuggerFrontendPrivate())
138{
139 d_ptr->q_ptr = this;
140}
141
142QScriptDebuggerFrontend::~QScriptDebuggerFrontend()
143{
144}
145
146QScriptDebuggerFrontend::QScriptDebuggerFrontend(QScriptDebuggerFrontendPrivate &dd)
147 : d_ptr(&dd)
148{
149 d_ptr->q_ptr = this;
150}
151
152QScriptDebuggerEventHandlerInterface *QScriptDebuggerFrontend::eventHandler() const
153{
154 Q_D(const QScriptDebuggerFrontend);
155 return d->eventHandler;
156}
157
158void QScriptDebuggerFrontend::setEventHandler(QScriptDebuggerEventHandlerInterface *eventHandler)
159{
160 Q_D(QScriptDebuggerFrontend);
161 d->eventHandler = eventHandler;
162}
163
164/*!
165 Schedules the given \a command for execution by this front-end,
166 and returns a unique identifier associated with this command.
167
168 Subclasses can call this function to schedule custom commands.
169
170 \sa notifyCommandFinished()
171*/
172int QScriptDebuggerFrontend::scheduleCommand(
173 const QScriptDebuggerCommand &command,
174 QScriptDebuggerResponseHandlerInterface *responseHandler)
175{
176 Q_D(QScriptDebuggerFrontend);
177 int id = ++d->nextCommandId;
178 d->pendingCommands.append(t: command);
179 d->pendingCommandIds.append(t: id);
180 if (responseHandler)
181 d->responseHandlers.insert(akey: id, avalue: responseHandler);
182 if (d->pendingCommands.size() == 1) {
183 QEvent *e = new QEvent(QEvent::Type(QEvent::User+2)); // ProcessCommands
184 d->postEvent(e);
185 }
186 return id;
187}
188
189/*!
190 Subclasses should call this function when the command identified by
191 the given \a id has finished and produced the given \a response.
192
193 \sa processCommand(), notifyEvent()
194*/
195void QScriptDebuggerFrontend::notifyCommandFinished(int id, const QScriptDebuggerResponse &response)
196{
197 Q_D(QScriptDebuggerFrontend);
198 if (d->responseHandlers.contains(akey: id)) {
199 QScriptDebuggerResponseHandlerInterface *handler = d->responseHandlers.take(akey: id);
200 Q_ASSERT(handler != 0);
201 handler->handleResponse(response, commandId: id);
202 }
203}
204
205/*!
206 Subclasses should call this function when the given \a event is
207 received from the back-end.
208
209 \sa notifyCommandFinished(), QScriptDebuggerBackend::event()
210*/
211bool QScriptDebuggerFrontend::notifyEvent(const QScriptDebuggerEvent &event)
212{
213 Q_D(QScriptDebuggerFrontend);
214 if (d->eventHandler)
215 return d->eventHandler->debuggerEvent(event);
216 return false;
217}
218
219int QScriptDebuggerFrontend::scheduledCommandCount() const
220{
221 Q_D(const QScriptDebuggerFrontend);
222 return d->nextCommandId;
223}
224
225/*!
226 \fn void QScriptDebuggerFrontend::processCommand(int id, const QScriptDebuggerCommand &command)
227
228 Subclasses must reimplement this function to process the given \a command
229 identified by \a id. Call notifyCommandFinished() when processing is
230 complete.
231*/
232
233QT_END_NAMESPACE
234

source code of qtscript/src/scripttools/debugging/qscriptdebuggerfrontend.cpp