Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

bcrepeater.C

Go to the documentation of this file.
00001 #include "bcrepeater.h"
00002 #include "bcsignals.h"
00003 #include "bcwindow.h"
00004 #include "condition.h"
00005 
00006 #include <unistd.h>
00007 
00008 BC_Repeater::BC_Repeater(BC_WindowBase *top_level, long delay)
00009  : Thread()
00010 {
00011         set_synchronous(1);
00012         pause_lock = new Condition(0, "BC_Repeater::pause_lock");
00013         startup_lock = new Condition(0, "BC_Repeater::startup_lock");
00014         repeat_lock = new Condition(1, "BC_Repeater::repeat_lock");
00015         repeating = 0;
00016         interrupted = 0;
00017         this->delay = delay;
00018         this->top_level = top_level;
00019 
00020 }
00021 
00022 BC_Repeater::~BC_Repeater()
00023 {
00024         interrupted = 1;
00025         pause_lock->unlock();
00026         repeat_lock->unlock();
00027 
00028         Thread::end();
00029         Thread::join();
00030 
00031         delete pause_lock;
00032         delete startup_lock;
00033         delete repeat_lock;
00034 }
00035 
00036 void BC_Repeater::initialize()
00037 {
00038         start();
00039 // This is important.  It doesn't unblock until the thread is running.
00040         startup_lock->lock("BC_Repeater::initialize");
00041 }
00042 
00043 int BC_Repeater::start_repeating()
00044 {
00045 //printf("BC_Repeater::start_repeating 1 %d\n", delay);
00046         repeating++;
00047         if(repeating == 1)
00048         {
00049 // Resume the loop
00050                 pause_lock->unlock();
00051         }
00052         return 0;
00053 }
00054 
00055 int BC_Repeater::stop_repeating()
00056 {
00057 // Recursive calling happens when mouse wheel is used.
00058         if(repeating > 0)
00059         {
00060                 repeating--;
00061 // Pause the loop
00062                 if(repeating == 0) pause_lock->lock("BC_Repeater::stop_repeating");
00063         }
00064         return 0;
00065 }
00066 
00067 void BC_Repeater::run()
00068 {
00069 //printf("BC_Repeater::run 1 %d\n", getpid());
00070         next_delay = delay;
00071         Thread::disable_cancel();
00072         startup_lock->unlock();
00073 
00074         while(!interrupted)
00075         {
00076                 Thread::enable_cancel();
00077                 timer.delay(next_delay);
00078                 Thread::disable_cancel();
00079 //if(next_delay <= 0) printf("BC_Repeater::run delay=%d next_delay=%d\n", delay, next_delay);
00080 
00081 // Test exit conditions
00082                 if(interrupted) return;
00083 // Busy wait here
00084 //              if(repeating <= 0) continue;
00085 
00086 // Test for pause
00087                 pause_lock->lock("BC_Repeater::run");
00088                 pause_lock->unlock();
00089                 timer.update();
00090 
00091 // Test exit conditions
00092                 if(interrupted) return;
00093                 if(repeating <= 0) continue;
00094 
00095 // Wait for existing signal to be processed before sending a new one
00096                 repeat_lock->lock("BC_Repeater::run");
00097 
00098 // Test exit conditions
00099                 if(interrupted)
00100                 {
00101                         repeat_lock->unlock();
00102                         return;
00103                 }
00104                 if(repeating <= 0)
00105                 {
00106                         repeat_lock->unlock();
00107                         continue;
00108                 }
00109 
00110 // Wait for window to become available.
00111                 top_level->lock_window("BC_Repeater::run");
00112 
00113 // Test exit conditions
00114                 if(interrupted)
00115                 {
00116                         repeat_lock->unlock();
00117                         top_level->unlock_window();
00118                         return;
00119                 }
00120                 if(repeating <= 0)
00121                 {
00122                         repeat_lock->unlock();
00123                         top_level->unlock_window();
00124                         continue;
00125                 }
00126 
00127 // Stick event into queue
00128                 top_level->arm_repeat(delay);
00129                 top_level->unlock_window();
00130                 next_delay = delay - timer.get_difference();
00131                 if(next_delay <= 0) next_delay = 0;
00132 
00133 // Test exit conditions
00134                 if(interrupted) 
00135                 {
00136                         repeat_lock->unlock();
00137                         return;
00138                 }
00139                 if(repeating <= 0)
00140                 {
00141                         repeat_lock->unlock();
00142                         continue;
00143                 }
00144         }
00145 }

Generated on Sun Jan 8 13:26:32 2006 for Guicast-svn by  doxygen 1.4.4