-
Notifications
You must be signed in to change notification settings - Fork 1
/
controller.cpp
125 lines (99 loc) · 2.69 KB
/
controller.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "controller.hpp"
#include "exceptions.hpp"
#include "decoderop.hpp"
#include "mutexobj.hpp"
#include "controllerop.hpp"
#include <stdio.h>
static void *thread_helper( void *controller )
{
Controller *me = static_cast<Controller *>( controller );
ahabassert( me );
me->loop();
return NULL;
}
Controller::Controller( uint s_num_frames )
: quit_signal( NULL ),
opq( 0 ),
inputq( 0 ),
num_frames( s_num_frames )
{
unixassert( pthread_mutex_init( &mutex, NULL ) );
pthread_create( &thread_handle, NULL, thread_helper, this );
}
void Controller::move( void ) {
ControllerOperation *op = inputq.dequeue( false );
if ( op ) {
op->execute( state );
delete op;
}
}
void tick_move_slider_helper( void *obj )
{
Controller *me = static_cast<Controller *>( obj );
ahabassert( me );
me->tick_move_slider();
}
void Controller::tick_move_slider( void )
{
MutexLock x( &mutex );
if ( state.move_slider ) {
(*state.move_slider)();
}
}
void Controller::loop( void )
{
main = new Gtk::Main( 0, NULL );
window = new Gtk::Window;
{
MutexLock x( &mutex );
quit_signal = new Glib::Dispatcher;
state.move_slider = new Glib::Dispatcher;
window->set_default_size( 600, 50 );
window->set_title( "Ahab Controller" );
state.scale = new Gtk::HScale( 0, num_frames, 1 );
window->add( *state.scale );
state.scale->set_update_policy( Gtk::UPDATE_CONTINUOUS );
state.scale->set_digits( 0 );
state.scale->set_value_pos( Gtk::POS_TOP );
state.scale->set_draw_value();
state.scale->signal_change_value().connect( sigc::mem_fun( this, &Controller::on_changed_value ) );
quit_signal->connect( sigc::mem_fun( this, &Controller::shutdown ) );
state.move_slider->connect( sigc::mem_fun( this, &Controller::move ) );
inputq.set_enqueue_callback( tick_move_slider_helper, this );
state.scale->show();
}
main->run( *window );
{
MutexLock x( &mutex );
delete quit_signal;
quit_signal = NULL;
}
DecoderShutDown *op = new DecoderShutDown();
try {
opq.enqueue( op );
} catch ( UnixAssertError *e ) {}
delete state.scale;
delete window;
delete main;
}
bool Controller::on_changed_value( Gtk::ScrollType, double new_value )
{
int cur_frame = lround( new_value );
if ( cur_frame < 0 ) cur_frame = 0;
if ( cur_frame >= num_frames ) cur_frame = num_frames - 1;
SetPictureNumber *op = new SetPictureNumber( cur_frame );
opq.flush_type( op );
opq.enqueue( op );
return true;
}
Controller::~Controller()
{
{
MutexLock x( &mutex );
if ( quit_signal ) {
(*quit_signal)();
}
}
unixassert( pthread_join( thread_handle, NULL ) );
unixassert( pthread_mutex_destroy( &mutex ) );
}