Permalink
Browse files

Implement the synchronization necessary to pass input between the GUI…

… thread and controller thread. Fix bug in npiet_utils.
  • Loading branch information...
1 parent a16da5e commit 9e55094efb295485ba64e42d41275268a105040b @Ramblurr committed Aug 8, 2010
Showing with 104 additions and 33 deletions.
  1. +14 −0 MainWindow.cpp
  2. +2 −0 MainWindow.h
  3. +6 −7 NPietObserver.cpp
  4. +1 −1 NPietObserver.h
  5. +55 −16 RunController.cpp
  6. +17 −0 RunController.h
  7. +3 −3 npiet/npiet.c
  8. +5 −5 npiet/npiet_utils.c
  9. +1 −1 npiet/npiet_utils.h
View
@@ -110,7 +110,10 @@ MainWindow::MainWindow( QWidget *parent ) :
connect( mRunController, SIGNAL( stepped( trace_step* ) ), mDebugWidget, SLOT( slotStepped( trace_step* ) ) );
connect( mRunController, SIGNAL( actionChanged( trace_action* ) ), mDebugWidget, SLOT( slotActionChanged( trace_action* ) ) );
connect( mRunController, SIGNAL(stopped()), this, SLOT( slotControllerStopped() ) );
+ connect( mRunController, SIGNAL(waitingForInt()), this, SLOT( slotGetInt()) );
+ connect( mRunController, SIGNAL(waitingForChar()), this, SLOT( slotGetChar() ) );
+ connect( &mRunThread, SIGNAL( started() ), mRunController, SLOT( slotThreadStarted() ) );
mRunController->moveToThread( &mRunThread );
mRunThread.start();
@@ -457,6 +460,17 @@ void MainWindow::slotControllerStopped()
emit setStopEnabled( false );
}
+void MainWindow::slotGetChar()
+{
+ qDebug() << "slotGetChar();";
+ mRunController->putChar( 'c' );
+}
+
+void MainWindow::slotGetInt()
+{
+ qDebug() << "slotGetInt();";
+ mRunController->putInt( 3 );
+}
#include "MainWindow.moc"
View
@@ -74,6 +74,8 @@ private slots:
void slotToggleOutput();
void slotToggleDebug();
void slotControllerStopped();
+ void slotGetChar();
+ void slotGetInt();
private:
void setupToolbar();
View
@@ -19,6 +19,7 @@
#include "NPietObserver.h"
#include <QDebug>
+#include <QThread>
extern "C"
{
#include "npiet/npiet_utils.h"
@@ -49,33 +50,31 @@ char NPietObserver::get_char()
int NPietObserver::get_int()
{
- qDebug() << "HAI";
- qDebug() << thread();
return mRunController->getInt();
}
void NPietObserver::call_action( void* object, trace_action* act )
{
- NPietObserver* me = (NPietObserver*) object;
+ NPietObserver* me = static_cast<NPietObserver*>( object );
me->action( act );
}
void NPietObserver::call_step( void* object, trace_step* ste )
{
- NPietObserver* me = (NPietObserver*) object;
+ NPietObserver* me = static_cast<NPietObserver*>( object );
me->step( ste );
}
char NPietObserver::call_readchar( void* object )
{
- NPietObserver* me = (NPietObserver*) object;
+ NPietObserver* me = static_cast<NPietObserver*>( object );
return me->get_char();
}
int NPietObserver::call_readint( void* object )
{
- NPietObserver* me = (NPietObserver*) object;
- return me->get_int();
+ NPietObserver* me = static_cast<NPietObserver*>( object );
+ return me->get_int();;
}
View
@@ -28,7 +28,7 @@ struct trace_action;
class NPietObserver : public QObject
{
- Q_OBJECT
+Q_OBJECT
public:
NPietObserver( RunController* controller = 0 );
View
@@ -24,7 +24,7 @@
#include <QSocketNotifier>
#include <QDebug>
#include <QTemporaryFile>
-
+#include <QThread>
#include <unistd.h>
#include <stdio.h>
@@ -44,11 +44,8 @@ extern "C"
#include "npiet/npiet_utils.h"
}
-RunController::RunController(): QObject( 0 ), mPrepared( false ), mStdOut( 0 ), mNotifier( 0 ), mObserver( new NPietObserver(this) ), mAbort( false ), mExecuting( false ), mDebugging( false )
+RunController::RunController(): QObject( 0 ), mPrepared( false ), mStdOut( 0 ), mNotifier( 0 ), mObserver( 0 ), mAbort( false ), mExecuting( false ), mDebugging( false )
{
- connect( mObserver, SIGNAL( stepped( trace_step* ) ), this, SIGNAL( stepped( trace_step* ) ) );
- connect( mObserver, SIGNAL( actionChanged( trace_action* ) ), this, SIGNAL( actionChanged( trace_action* ) ) );
- connect( &mTimer, SIGNAL( timeout() ), this, SLOT( tick() ) );
}
RunController::~RunController()
@@ -59,6 +56,15 @@ RunController::~RunController()
wait();
}
+void RunController::slotThreadStarted()
+{
+ mObserver = new NPietObserver( this );
+ connect( mObserver, SIGNAL( stepped( trace_step* ) ), this, SIGNAL( stepped( trace_step* ) ) );
+ connect( mObserver, SIGNAL( actionChanged( trace_action* ) ), this, SIGNAL( actionChanged( trace_action* ) ) );
+ connect( &mTimer, SIGNAL( timeout() ), this, SLOT( tick() ) );
+}
+
+
bool RunController::initialize( const QImage &source )
{
mSource = source;
@@ -75,19 +81,20 @@ void RunController::execute()
mExecuting = true;
if ( !mPrepared )
return;
- mTimer.start( 100 );
+ mTimer.start( 0 );
}
void RunController::tick()
{
- QMutexLocker locker( &mMutex );
+ mMutex.lock();
bool abort;
if( mAbort ) {
abort = true;
- } else if( piet_step() < 0 )
+ }
+ mMutex.unlock();
+ if( !abort && piet_step() < 0 )
abort = true;
if( abort ) {
- qDebug() << "ABORT";
mTimer.stop();
finish();
emit stopped();
@@ -193,15 +200,47 @@ void RunController::stdoutReadyRead()
void RunController::slotAction(trace_action* )
{
-// mMutex.lock();
-// if( mA
}
void RunController::slotStepped(trace_step* )
{
}
+char RunController::getChar()
+{
+ QMutexLocker locker( &mMutex );
+ emit waitingForChar();
+ mWaitCond.wait( &mMutex );
+ return mChar;
+}
+
+int RunController::getInt()
+{
+// qDebug() << "getInt()" << "getting lock";
+ QMutexLocker locker( &mMutex );
+// qDebug() << "getInt()" << "got lock";
+ emit waitingForInt();
+// qDebug() << "getInt()" << "waiting";
+ mWaitCond.wait( &mMutex );
+// qDebug() << "getInt()" << "woke up!" << mInt;
+ return mInt;
+}
+
+void RunController::putChar( char c )
+{
+ QMutexLocker locker( &mMutex );
+ mChar = c;
+ mWaitCond.wakeOne();
+}
+
+void RunController::putInt( int i )
+{
+ QMutexLocker locker( &mMutex );
+ mInt = i;
+ mWaitCond.wakeOne();
+}
+
//
// Downloaded from: http://www.ibib.waw.pl/~winnie
//
@@ -226,16 +265,16 @@ void RunController::captureStdout()
int rc = ::pipe( mPipeFd );
#endif
Q_ASSERT( rc >= 0 );
-
+
mOrigFd = STDOUT_FILENO;
-
+
mOrigFdCopy = ::dup( mOrigFd );
Q_ASSERT( mOrigFdCopy >= 0 );
-
+
rc = ::dup2( mPipeFd[1], mOrigFd );
Q_ASSERT( rc >= 0 );
::close( mPipeFd[1] );
-
+
#ifndef Q_WS_WIN
rc = ::fcntl( mPipeFd[0], F_GETFL );
Q_ASSERT( rc != -1 );
@@ -244,7 +283,7 @@ void RunController::captureStdout()
#endif
FILE * f = fdopen( mPipeFd[0], "r" );
Q_ASSERT( f != 0 );
-
+
if ( mStdOut != 0 )
delete mStdOut;
if ( mNotifier != 0 )
View
@@ -24,6 +24,7 @@
#include <QTextStream>
#include <QImage>
#include <QMutex>
+#include <QWaitCondition>
#include <QTimer>
class QSocketNotifier;
@@ -38,13 +39,24 @@ class RunController : public QObject
public:
RunController();
~RunController();
+
+ void putInt( int i );
+ void putChar( char c );
+
+ int getInt();
+ char getChar();
+
signals:
void newOutput( const QString & );
void stepped( trace_step* );
void actionChanged( trace_action* );
void stopped();
+ void waitingForInt();
+ void waitingForChar();
public slots:
+ void slotThreadStarted();
+
void debugSource( const QImage &source );
bool runSource( const QImage &source );
@@ -60,6 +72,7 @@ private slots:
void slotAction( trace_action* );
void tick();
+
private:
void captureStdout();
bool prepare();
@@ -80,10 +93,14 @@ private slots:
QImage mSource;
QMutex mMutex;
+ QWaitCondition mWaitCond;
bool mAbort;
bool mExecuting;
bool mDebugging;
QTimer mTimer;
+
+ char mChar;
+ int mInt;
};
#endif // RUNCONTROLLER_H
View
@@ -2073,10 +2073,10 @@ piet_action (int c_col, int a_col, int num_cells, char *msg)
tprintf ("action: in(number)\n");
alloc_stack_space (num_stack + 1);
- if (! quiet) {
+// if (! quiet) {
/* show a prompt: */
- printf ("? "); fflush (stdout);
- }
+// printf ("? "); fflush (stdout);
+// }
c = read_int();
// if (1 != scanf (stdin, "%d", &c)) {
// notify_msg = "cannot read int from stdin";
View
@@ -88,23 +88,23 @@ void register_action_callback( action_callback_t callable, void* obj )
int read_int()
{
- return readint_callback( readint_callback );
+ return readint_callback( readint_object );
}
char read_char()
{
- return readchar_callback( readchar_callback );
+ return readchar_callback( readchar_object );
}
-void register_readchar_callback(readchar_callback_t callable, void* obj)
+void register_readchar_callback( readchar_callback_t callable, void* obj )
{
readchar_object = obj;
readchar_callback = callable;
}
-void register_readint_callback(readint_callback_t callable, void* obj)
+void register_readint_callback( readint_callback_t callable, void* obj )
{
- readint_callback = obj;
+ readint_object = obj;
readint_callback = callable;
}
View
@@ -67,4 +67,4 @@ typedef int (*readint_callback_t)( void* object );
typedef char (*readchar_callback_t)( void* object );
void register_readint_callback( readint_callback_t callable, void* obj );
-void register_readchar_callback( readchar_callback_t callable, void* obj );
+void register_readchar_callback( readchar_callback_t callable, void* obj );

0 comments on commit 9e55094

Please sign in to comment.