Skip to content

Commit ad63077

Browse files
committed
Successful two-way move between Gtk+ and rest of code
1 parent 2631b35 commit ad63077

19 files changed

+150
-61
lines changed

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
source = ahab.cpp es.cpp mpegheader.cpp bitreader.cpp startfinder.cpp sequence.cpp extensions.cpp exceptions.cpp picture.cpp slice.cpp file.cpp ogl.cpp slicedecode.cpp idct_mmx.cpp motion_comp_mmx.cpp framebuffer.cpp opq.cpp displayop.cpp controller.cpp displayopq.cpp decoder.cpp decoderop.cpp decoderopq.cpp xeventloop.cpp slicerow.cpp benchmark.cpp decodeengine.cpp readythreadq.cpp decoderjobq.cpp framequeue.cpp
2-
objects = es.o mpegheader.o bitreader.o startfinder.o sequence.o extensions.o exceptions.o picture.o slice.o file.o ogl.o slicedecode.o idct_mmx.o motion_comp_mmx.o framebuffer.o opq.o displayop.o controller.o displayopq.o decoder.o decoderop.o decoderopq.o xeventloop.o slicerow.o decodeengine.o readythreadq.o decoderjobq.o framequeue.o
1+
source = ahab.cpp benchmark.cpp bitreader.cpp controller.cpp decodeengine.cpp decoder.cpp decoderop.cpp displayop.cpp es.cpp exceptions.cpp extensions.cpp file.cpp framebuffer.cpp idct_mmx.cpp motion_comp_mmx.cpp mpegheader.cpp ogl.cpp opq.cpp picture.cpp queue_templates.cpp sequence.cpp slice.cpp slicedecode.cpp slicerow.cpp startfinder.cpp xeventloop.cpp controllerop.cpp
2+
objects = bitreader.o controller.o decodeengine.o decoder.o decoderop.o displayop.o es.o exceptions.o extensions.o file.o framebuffer.o idct_mmx.o motion_comp_mmx.o mpegheader.o ogl.o opq.o picture.o queue_templates.o sequence.o slice.o slicedecode.o slicerow.o startfinder.o xeventloop.o controllerop.o
33
executables = ahab benchmark
44

55
CPP = g++

ahab.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
#include "file.hpp"
1010
#include "es.hpp"
1111
#include "ogl.hpp"
12-
#include "framebuffer.hpp"
13-
#include "colorimetry.hpp"
1412
#include "decoder.hpp"
1513
#include "xeventloop.hpp"
1614

@@ -72,6 +70,8 @@ int main( int argc, char *argv[] )
7270
xevents->get_key_queue()->hookup( decoder->get_queue() );
7371
xevents->get_repaint_queue()->hookup( display->get_queue() );
7472

73+
decoder->get_output_queue()->hookup( controller->get_input_queue() );
74+
7575
try {
7676
decoder->wait_shutdown();
7777
} catch ( UnixAssertError *e ) {

controller.cpp

+43-13
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "exceptions.hpp"
33
#include "decoderop.hpp"
44
#include "mutexobj.hpp"
5+
#include "controllerop.hpp"
56

67
#include <stdio.h>
78

@@ -16,12 +17,36 @@ static void *thread_helper( void *controller )
1617
Controller::Controller( uint s_num_frames )
1718
: quit_signal( NULL ),
1819
opq( 0 ),
20+
inputq( 0 ),
1921
num_frames( s_num_frames )
2022
{
2123
unixassert( pthread_mutex_init( &mutex, NULL ) );
2224
pthread_create( &thread_handle, NULL, thread_helper, this );
2325
}
2426

27+
void Controller::move( void ) {
28+
ControllerOperation *op = inputq.dequeue( false );
29+
if ( op ) {
30+
op->execute( state );
31+
delete op;
32+
}
33+
}
34+
35+
void tick_move_slider_helper( void *obj )
36+
{
37+
Controller *me = static_cast<Controller *>( obj );
38+
ahabassert( me );
39+
me->tick_move_slider();
40+
}
41+
42+
void Controller::tick_move_slider( void )
43+
{
44+
MutexLock x( &mutex );
45+
if ( state.move_slider ) {
46+
(*state.move_slider)();
47+
}
48+
}
49+
2550
void Controller::loop( void )
2651
{
2752
main = new Gtk::Main( 0, NULL );
@@ -30,24 +55,28 @@ void Controller::loop( void )
3055
{
3156
MutexLock x( &mutex );
3257
quit_signal = new Glib::Dispatcher;
33-
}
58+
state.move_slider = new Glib::Dispatcher;
3459

35-
window->set_default_size( 600, 50 );
36-
window->set_title( "Ahab Controller" );
60+
window->set_default_size( 600, 50 );
61+
window->set_title( "Ahab Controller" );
3762

38-
scale = new Gtk::HScale( 0, num_frames, 1 );
39-
window->add( *scale );
63+
state.scale = new Gtk::HScale( 0, num_frames, 1 );
64+
window->add( *state.scale );
4065

41-
scale->set_update_policy( Gtk::UPDATE_CONTINUOUS );
42-
scale->set_digits( 0 );
43-
scale->set_value_pos( Gtk::POS_TOP );
44-
scale->set_draw_value();
66+
state.scale->set_update_policy( Gtk::UPDATE_CONTINUOUS );
67+
state.scale->set_digits( 0 );
68+
state.scale->set_value_pos( Gtk::POS_TOP );
69+
state.scale->set_draw_value();
4570

46-
scale->signal_change_value().connect( sigc::mem_fun( this, &Controller::on_changed_value ) );
71+
state.scale->signal_change_value().connect( sigc::mem_fun( this, &Controller::on_changed_value ) );
4772

48-
quit_signal->connect( sigc::mem_fun( this, &Controller::shutdown ) );
73+
quit_signal->connect( sigc::mem_fun( this, &Controller::shutdown ) );
74+
state.move_slider->connect( sigc::mem_fun( this, &Controller::move ) );
4975

50-
scale->show();
76+
inputq.set_enqueue_callback( tick_move_slider_helper, this );
77+
78+
state.scale->show();
79+
}
5180

5281
main->run( *window );
5382

@@ -63,7 +92,7 @@ void Controller::loop( void )
6392
opq.enqueue( op );
6493
} catch ( UnixAssertError *e ) {}
6594

66-
delete scale;
95+
delete state.scale;
6796
delete window;
6897
delete main;
6998
}
@@ -90,6 +119,7 @@ Controller::~Controller()
90119
(*quit_signal)();
91120
}
92121
}
122+
93123
unixassert( pthread_join( thread_handle, NULL ) );
94124
unixassert( pthread_mutex_destroy( &mutex ) );
95125
}

controller.hpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,31 @@
55
#include <pthread.h>
66

77
#include "decoderop.hpp"
8+
#include "controllerop.hpp"
9+
10+
class ControllerState {
11+
public:
12+
Glib::Dispatcher *move_slider;
13+
Gtk::HScale *scale;
14+
};
815

916
class Controller {
1017
private:
1118
Gtk::Main *main;
1219
Gtk::Window *window;
13-
Gtk::HScale *scale;
1420

1521
pthread_mutex_t mutex;
1622
pthread_t thread_handle;
1723

1824
bool on_changed_value( Gtk::ScrollType scroll, double new_value );
1925
void shutdown( void ) { main->quit(); }
26+
void move( void );
2027

2128
Glib::Dispatcher *quit_signal;
29+
ControllerState state;
2230

2331
Queue<DecoderOperation> opq;
32+
Queue<ControllerOperation> inputq;
2433

2534
int num_frames;
2635

@@ -30,6 +39,9 @@ class Controller {
3039

3140
void loop( void );
3241
Queue<DecoderOperation> *get_queue() { return &opq; }
42+
Queue<ControllerOperation> *get_input_queue() { return &inputq; }
43+
44+
void tick_move_slider( void );
3345
};
3446

3547
#endif

controllerop.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include "controller.hpp"
2+
#include "controllerop.hpp"
3+
4+
void MoveSlider::execute( ControllerState &state )
5+
{
6+
state.scale->set_value( picture_number );
7+
8+
/* Gtk+ doesn't redraw the number (value) unless the position
9+
of the slider changes or it gets exposed! This looks like
10+
a bug since we can even get partial numerals! */
11+
12+
state.scale->hide();
13+
state.scale->show();
14+
}

controllerop.hpp

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#ifndef CONTROLLEROP_HPP
2+
#define CONTROLLEROP_HPP
3+
4+
#include <pthread.h>
5+
6+
class ControllerState;
7+
8+
class ControllerOperation {
9+
public:
10+
virtual void execute( ControllerState &state ) = 0;
11+
virtual ~ControllerOperation() {}
12+
};
13+
14+
class MoveSlider : public ControllerOperation {
15+
private:
16+
int picture_number;
17+
18+
public:
19+
MoveSlider( int s_picture_number ) : picture_number( s_picture_number ) {}
20+
~MoveSlider() {}
21+
void execute( ControllerState &state );
22+
};
23+
24+
#endif

decoder.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class DisplayOperation;
1111

1212
#include "opq.hpp"
1313
#include "decodeengine.hpp"
14+
#include "controllerop.hpp"
1415

1516
class DecoderState {
1617
public:
@@ -19,6 +20,7 @@ class DecoderState {
1920
bool live;
2021
OpenGLDisplay *display;
2122
Queue<DisplayOperation> *oglq;
23+
Queue<ControllerOperation> outputq;
2224
};
2325

2426
class Decoder {
@@ -38,6 +40,7 @@ class Decoder {
3840

3941
void loop();
4042
Queue<DecoderOperation> *get_queue() { return &opq; }
43+
Queue<ControllerOperation> *get_output_queue() { return &state.outputq; }
4144
void wait_shutdown( void );
4245
};
4346

decoderjobq.cpp

-3
This file was deleted.

decoderjobq.hpp

-9
This file was deleted.

decoderop.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@ void XKey::execute( DecoderState &state )
1818
break;
1919
case XK_Left:
2020
state.current_picture--;
21+
state.outputq.flush();
22+
state.outputq.enqueue( new MoveSlider( state.current_picture ) );
2123
break;
2224
case XK_Right:
2325
state.current_picture++;
26+
state.outputq.flush();
27+
state.outputq.enqueue( new MoveSlider( state.current_picture ) );
2428
break;
2529
default:
2630
fprintf( stderr, "key %d hit\n", key );

decoderopq.cpp

-3
This file was deleted.

decoderopq.hpp

-9
This file was deleted.

displayopq.cpp

-3
This file was deleted.

framequeue.cpp

-3
This file was deleted.

opq.cpp

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#ifndef OPQ_CPP
2+
#define OPQ_CPP
3+
14
#include <pthread.h>
25

36
#include "opq.hpp"
@@ -13,13 +16,23 @@ Queue<T>::Queue( int s_max_size )
1316
max_size( s_max_size ),
1417
head( NULL ),
1518
tail( NULL ),
16-
output( NULL )
19+
output( NULL ),
20+
enqueue_callback( NULL )
1721
{
1822
unixassert( pthread_mutex_init( &mutex, NULL ) );
1923
unixassert( pthread_cond_init( &write_activity, NULL ) );
2024
unixassert( pthread_cond_init( &read_activity, NULL ) );
2125
}
2226

27+
template <class T>
28+
void Queue<T>::set_enqueue_callback( void (*s_enqueue_callback)(void *obj),
29+
void *s_obj)
30+
{
31+
MutexLock x( &mutex );
32+
enqueue_callback = s_enqueue_callback;
33+
obj = s_obj;
34+
}
35+
2336
template <class T>
2437
Queue<T>::~Queue()
2538
{
@@ -73,6 +86,10 @@ QueueElement<T> *Queue<T>::enqueue( T *h )
7386

7487
unixassert( pthread_cond_signal( &write_activity ) );
7588

89+
if ( enqueue_callback ) {
90+
(*enqueue_callback)(obj);
91+
}
92+
7693
return op;
7794
}
7895

@@ -118,6 +135,10 @@ QueueElement<T> *Queue<T>::leapfrog_enqueue( T *h,
118135

119136
unixassert( pthread_cond_signal( &write_activity ) );
120137

138+
if ( enqueue_callback ) {
139+
(*enqueue_callback)(obj);
140+
}
141+
121142
return op;
122143
}
123144

@@ -273,3 +294,5 @@ void Queue<T>::hookup( Queue<T> *s_output )
273294
head = tail = NULL;
274295
count = 0;
275296
}
297+
298+
#endif

opq.hpp

+8
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,14 @@ class Queue
3131

3232
Queue<T> *output;
3333

34+
void (*enqueue_callback)(void *obj);
35+
void *obj;
36+
3437
public:
3538
Queue( int s_max_size );
39+
Queue() { Queue( 0 ); }
3640
~Queue();
41+
3742
QueueElement<T> *enqueue( T *h );
3843
QueueElement<T> *leapfrog_enqueue( T *h, T *leapfrog_type );
3944
void remove_specific( QueueElement<T> *op );
@@ -46,6 +51,9 @@ class Queue
4651
int get_count( void ) { MutexLock x( &mutex ); return count; }
4752

4853
void hookup( Queue<T> *s_output );
54+
55+
void set_enqueue_callback( void (*s_enqueue_callback)(void *obj),
56+
void *s_obj );
4957
};
5058

5159
#endif

queue_templates.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "decoderjob.hpp"
2+
#include "decoderop.hpp"
3+
#include "displayop.hpp"
4+
#include "framebuffer.hpp"
5+
#include "decodeengine.hpp"
6+
#include "controllerop.hpp"
7+
8+
template class Queue<DecoderJob>;
9+
template class Queue<DecoderOperation>;
10+
template class Queue<DisplayOperation>;
11+
template class Queue<Frame>;
12+
template class Queue<ReadyThread>;
13+
template class Queue<ControllerOperation>;

readythreadq.cpp

-3
This file was deleted.

readythreadq.hpp

-9
This file was deleted.

0 commit comments

Comments
 (0)