1 /************************************************************************
2  *
3  * Copyright 2011 Jakob Leben (jakob.leben@gmail.com)
4  *
5  * This file is part of SuperCollider Qt GUI.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  ************************************************************************/
21 
22 #include "LanguageClient.h"
23 #include "QcApplication.h"
24 #include "QtCollider.h"
25 #include "QObjectProxy.h"
26 
27 #include <PyrKernel.h>
28 #include <PyrLexer.h>
29 
30 #include <qmath.h>
main(void)31 #include <QWidget>
32 
33 extern double elapsedTime();
34 
35 using namespace QtCollider;
36 
37 LangClient::LangClient(const char* name): SC_TerminalClient(name) {}
38 
39 void LangClient::commandLoop() {
40     int exit_code = QcApplication::instance()->exec();
41     SC_TerminalClient::quit(exit_code);
42 }
43 
44 void LangClient::daemonLoop() { commandLoop(); }
45 
46 void LangClient::sendSignal(Signal sig) {
47     if (sig == sig_sched) {
48         QApplication::postEvent(this, new SCRequestEvent(Event_SCRequest_Tick));
49     } else {
50         SC_TerminalClient::sendSignal(sig);
51         QApplication::postEvent(this, new SCRequestEvent(Event_SCRequest_Work));
52     }
53 }
54 
55 void LangClient::onQuit(int exitCode) {
56     QApplication::postEvent(this, new SCRequestEvent(Event_SCRequest_Quit, exitCode));
57 }
58 
59 void LangClient::onLibraryShutdown() {
60     QWidgetList windows = QApplication::topLevelWidgets();
61     Q_FOREACH (QWidget* w, windows)
62         w->hide();
63 }
64 
65 void LangClient::customEvent(QEvent* e) {
66     int type = e->type();
67     switch (type) {
68     case Event_SCRequest_Tick:
69         tick();
70 
71     case Event_SCRequest_Work:
72         QApplication::removePostedEvents(this, Event_SCRequest_Work);
73         mIoService.poll();
74         break;
75     case Event_SCRequest_Quit: {
76         int code = static_cast<SCRequestEvent*>(e)->data.toInt();
77         qcDebugMsg(1, QStringLiteral("Quit requested with code %1").arg(code));
78         qApp->exit(code);
79         break;
80     }
81     default:;
82     }
83 }
84 
85 void LangClient::tick() {
86     double secs;
87     lock();
88     bool haveNext = tickLocked(&secs);
89     unlock();
90 
91     flush();
92 
93     if (haveNext) {
94         secs -= elapsedTime();
95         secs *= 1000;
96         int ti = qMax(0, qCeil(secs));
97         qcDebugMsg(2, QStringLiteral("next at %1").arg(ti));
98         appClockTimer.start(ti, this);
99     } else
100         appClockTimer.stop();
101 }
102 
103 void LangClient::timerEvent(QTimerEvent* e) {
104     if (e->timerId() == appClockTimer.timerId())
105         tick();
106 }
107