scide: cancel ScRequests when recompiling the class library
[supercollider.git] / editors / sc-ide / core / sc_process.hpp
blob34a710921d4a9db539686b03184f4790fff5a411
1 /*
2 SuperCollider Qt IDE
3 Copyright (c) 2012 Jakob Leben & Tim Blechmann
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifndef SCIDE_SC_PROCESS_HPP_INCLUDED
22 #define SCIDE_SC_PROCESS_HPP_INCLUDED
24 #include "sc_introspection.hpp"
25 #include "settings/manager.hpp"
27 #include <QAction>
28 #include <QByteArray>
29 #include <QDebug>
30 #include <QProcess>
31 #include <QThread>
32 #include <QUuid>
33 #include <QtNetwork/QLocalSocket>
34 #include <QtNetwork/QLocalServer>
36 namespace ScIDE {
38 class Main;
39 class ScIntrospectionParser;
41 class SCProcess:
42 public QProcess
44 Q_OBJECT
46 public:
47 SCProcess( Main *, class ScResponder * responder, Settings::Manager * );
49 enum SCProcessActionRole {
50 StartSCLang = 0,
51 RecompileClassLibrary,
52 StopSCLang,
53 RestartSCLang,
54 RunMain,
55 StopMain,
57 SCProcessActionCount
60 const ScLanguage::Introspection & introspection() { return mIntrospection; }
62 void sendRequest( const QString &id, const QString &command, const QString &data )
64 QString cmd = QString("ScIDE.request(\"%1\",'%2',\"%3\")")
65 .arg(id)
66 .arg(command)
67 .arg(data);
69 evaluateCode(cmd, true);
72 void setActiveDocument(class Document *);
73 void sendActiveDocument();
75 QAction *action(SCProcessActionRole role)
77 return mActions[role];
80 void emitClassLibraryRecompiled()
82 emit classLibraryRecompiled();
85 Q_SIGNALS:
86 void scPost(QString const &);
87 void statusMessage(const QString &);
88 void response(const QString & id, const QString & data);
89 void classLibraryRecompiled();
91 public slots:
92 void recompileClassLibrary (void);
93 void runMain(void) { evaluateCode("thisProcess.run", false); }
94 void stopMain(void) { evaluateCode("thisProcess.stop", false); }
95 void startLanguage (void);
96 void stopLanguage (void);
97 void restartLanguage (void);
98 void onReadyRead(void);
99 void evaluateCode(QString const & commandString, bool silent = false);
101 void swapIntrospection (ScLanguage::Introspection *newIntrospection)
103 // LATER: use c++11/std::move
104 mIntrospection = *newIntrospection;
105 delete newIntrospection;
108 private slots:
109 void onNewIpcConnection();
110 void onIpcData();
111 void finalizeConnection();
113 private:
114 void onSclangStart();
116 void prepareActions(Settings::Manager * settings);
118 QAction * mActions[SCProcessActionCount];
120 ScLanguage::Introspection mIntrospection;
121 ScIntrospectionParser *mIntrospectionParser;
123 QLocalServer *mIpcServer;
124 QLocalSocket *mIpcSocket;
125 QString mIpcServerName;
126 QByteArray mIpcData;
128 QString mCurrentDocumentPath;
131 class ScRequest : public QObject
133 Q_OBJECT
134 public:
135 ScRequest( SCProcess *sc, QObject * parent = 0 ):
136 QObject(parent),
137 mSc(sc)
139 connect(mSc, SIGNAL(response(QString,QString)),
140 this, SLOT(onResponse(QString,QString)));
142 connect(mSc, SIGNAL(classLibraryRecompiled()),
143 this, SLOT(onCancelRequest()));
146 void send( const QString & command, const QString & data )
148 mId = QUuid::createUuid();
149 mCommand = command;
150 mSc->sendRequest(mId.toString(), command, data);
153 void cancel()
155 mId = QUuid();
158 signals:
159 void response( const QString & command, const QString & data );
160 void requestCanceled();
162 private slots:
163 void onCancelRequest()
165 cancel();
166 emit requestCanceled();
167 deleteLater();
170 void onResponse( const QString & responseId, const QString & responseData )
172 if (responseId == mId.toString())
173 emit response(mCommand, responseData);
176 private:
177 QString mCommand;
178 QUuid mId;
179 SCProcess *mSc;
182 class ScResponder : public QObject
184 Q_OBJECT
186 public:
187 ScResponder( QObject * parent = 0):
188 QObject(parent)
191 Q_SIGNALS:
192 void serverRunningChanged( bool serverRunning, const QString & hostName, int port );
193 void newIntrospectionData( const QString & yaml );
195 private Q_SLOTS:
196 void onResponse( const QString & selector, const QString & data );
198 private:
199 void handleOpenFile( const QString & data ) const;
200 void handleServerRunningChanged( const QString & data );
203 class ScIntrospectionParserWorker : public QObject
205 Q_OBJECT
206 signals:
207 void done( ScLanguage::Introspection * output );
208 private slots:
209 void process( const QString & input )
211 try {
212 ScLanguage::Introspection *introspection = new ScLanguage::Introspection (input);
213 emit done(introspection);
214 } catch (std::exception & e) {
215 // LATER: show message in status bar
216 qDebug() << e.what();
219 void quit()
221 thread()->quit();
225 class ScIntrospectionParser : public QThread
227 Q_OBJECT
228 public:
229 ScIntrospectionParser( ScResponder * responder, QObject * parent = 0 ):
230 QThread(parent)
232 connect(responder, SIGNAL(newIntrospectionData(QString)),
233 &mWorker, SLOT(process(QString)), Qt::QueuedConnection);
234 connect(&mWorker, SIGNAL(done(ScLanguage::Introspection*)),
235 this, SIGNAL(done(ScLanguage::Introspection*)), Qt::QueuedConnection);
236 mWorker.moveToThread(this);
238 ~ScIntrospectionParser()
240 QMetaObject::invokeMethod(&mWorker, "quit");
241 wait();
244 signals:
245 void done( ScLanguage::Introspection * );
247 private:
248 ScIntrospectionParserWorker mWorker;
253 #endif