changeset 13340:eb510dd290bf

Adding pending requests.
author Jacob Dawid <jacob.dawid@googlemail.com>
date Wed, 06 Apr 2011 13:59:10 +0200
parents cf95d1db42c6
children 6442fb2e1dfa
files gui//client.cpp gui//client.h gui//mainwindow.cpp gui//octaveterminal.cpp gui//octaveterminal.h
diffstat 5 files changed, 84 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/gui//client.cpp
+++ b/gui//client.cpp
@@ -30,6 +30,10 @@
     connect(&m_process, SIGNAL(readyReadStandardError()), this, SLOT(reemitErrorAvailable()));
 }
 
+QMutex *Client::accessMutex() {
+    return &m_access;
+}
+
 void Client::send(QString content) {
     m_process.write(content.toLocal8Bit());
 }
--- a/gui//client.h
+++ b/gui//client.h
@@ -23,11 +23,15 @@
 #include <QProcess>
 #include <QObject>
 #include <QThread>
+#include <QMutex>
 
 class Client : public QObject {
     Q_OBJECT
     friend class ClientManager;
 
+public:
+    QMutex *accessMutex();
+
 public slots:
     void send(QString content);
 
@@ -48,6 +52,63 @@
     QString m_command;
     QProcess m_process;
     QThread m_thread;
+    QMutex m_access;
+};
+
+class PendingRequest : public QObject {
+    Q_OBJECT
+public:
+    PendingRequest(Client *client)
+        : QObject(),
+          m_client(client),
+          m_dataBuffer(""),
+          m_errorBuffer("") {
+        client->accessMutex()->lock();
+        connect(client, SIGNAL(dataAvailable(QString)), this, SLOT(receiveData(QString)));
+        connect(client, SIGNAL(errorAvailable(QString)), this, SLOT(receiveError(QString)));
+    }
+
+    virtual ~PendingRequest() {
+        m_client->accessMutex()->unlock();
+    }
+
+    QString fetchData() {
+        QString content = m_dataBuffer, m_dataBuffer = "";
+        return content;
+    }
+
+    QString fetchError() {
+        QString content = m_errorBuffer, m_errorBuffer = "";
+        return content;
+    }
+
+    void query(QString request) {
+        QMetaObject::invokeMethod(m_client, "send", Q_ARG(QString, request));
+    }
+
+signals:
+    void dataIncome();
+
+private slots:
+    void receiveData(QString data) {
+        QRegExp octavePrompt("octave:[0-9]+>");
+        m_dataBuffer += data;
+        if(octavePrompt.indexIn(m_dataBuffer) != -1)
+            emit dataIncome();
+    }
+
+    void receiveError(QString error) {
+        QRegExp octavePrompt("octave:[0-9]+>");
+        m_errorBuffer += error;
+        if(octavePrompt.indexIn(m_dataBuffer) != -1)
+            emit dataIncome();
+    }
+
+private:
+    Client *m_client;
+    QString m_dataBuffer;
+    QString m_errorBuffer;
+    QString m_request;
 };
 
 #endif // CLIENT_H
--- a/gui//mainwindow.cpp
+++ b/gui//mainwindow.cpp
@@ -42,7 +42,7 @@
 void MainWindow::addOctaveTerminal() {
     OctaveTerminal *octaveTerminal = new OctaveTerminal;
     m_mdiArea->addSubWindow(octaveTerminal);
-    Client *octaveClient = ClientManager::clientManager().startProcess("octave --interactive");
+    Client *octaveClient = ClientManager::clientManager().startProcess("octave --interactive --verbose");
     octaveTerminal->assignClient(octaveClient);
 }
 
--- a/gui//octaveterminal.cpp
+++ b/gui//octaveterminal.cpp
@@ -50,9 +50,7 @@
 }
 
 void OctaveTerminal::sendCommand(QString command) {
-    m_octaveOutput->setFontUnderline(true);
-    m_octaveOutput->append(command);
-    QMetaObject::invokeMethod(m_client, "send", Q_ARG(QString, command + "\n"));
+    addRequest(command + "\n");
 }
 
 void OctaveTerminal::blockUserInput() {
@@ -66,21 +64,25 @@
 
 void OctaveTerminal::assignClient(Client *client) {
     m_client = client;
-    connect(client, SIGNAL(dataAvailable(QString)), this, SLOT(handleDataFromClient(QString)));
-    connect(client, SIGNAL(errorAvailable(QString)), this, SLOT(handleErrorFromClient(QString)));
     allowUserInput();
 }
 
 void OctaveTerminal::showEnvironment() {
-    m_client->send("who\n");
+    addRequest("who\n");
 }
 
-void OctaveTerminal::handleDataFromClient(QString data) {
-    m_octaveOutput->setFontUnderline(false);
+void OctaveTerminal::handleAnsweredRequest() {
+    allowUserInput();
+    QString data = m_pendingRequest->fetchData();
+    QString error = m_pendingRequest->fetchError();
     m_octaveOutput->append(data);
+    m_octaveOutput->append(error);
+    delete m_pendingRequest;
 }
 
-void OctaveTerminal::handleErrorFromClient(QString error) {
-    m_octaveOutput->setFontUnderline(false);
-    m_octaveOutput->append(error);
+void OctaveTerminal::addRequest(QString command) {
+    blockUserInput();
+    m_pendingRequest = new PendingRequest(m_client);
+    connect(m_pendingRequest, SIGNAL(dataIncome()), this, SLOT(handleAnsweredRequest()));
+    m_pendingRequest->query(command);
 }
--- a/gui//octaveterminal.h
+++ b/gui//octaveterminal.h
@@ -27,6 +27,7 @@
 #include <QMenu>
 #include <QToolBar>
 #include <QKeyEvent>
+#include <QQueue>
 
 #include "client.h"
 #include "terminalhighlighter.h"
@@ -115,17 +116,17 @@
 
     void assignClient(Client* client);
     void showEnvironment();
-
-protected slots:
-    void handleDataFromClient(QString data);
-    void handleErrorFromClient(QString error);
+    void handleAnsweredRequest();
 
 private:
+    void addRequest(QString command);
+
     QToolBar *m_mainToolBar;
     QTextBrowser *m_octaveOutput;
     TerminalCommandLine *m_commandLine;
     Client *m_client;
     TerminalHighlighter *m_terminalHighlighter;
+    PendingRequest *m_pendingRequest;
 };
 
 #endif // OCTAVETERMINAL_H