I'm trying to create my first threaded application with fltk. I have two threads: one that produces stuff and the gui thread. For simplicity, the producer thread just generates random rectangles and tells the gui thread to draw them via Fl::awake(). See code below.
The problem is I have to put the producer thread to sleep() for a few seconds right at the beginning of the thread function, to allow for everything else to get going. See makeRectangles() below. I imagine this is not the proper way to make sure all threads have started, so what's the right way? Also, the threads.cxx example from fltk-1.1 locks/unlocks in the "producer" thread, but that's because it adds rows to the browsers. I'm not accessing any fltk widgets, so I don't have to lock, is that correct? Finally, there seems to be another way of drawing from a non-gui thread in the gui thread, using Fl::add_fd(), as explained here: http://www.angelfire.com/linux/tzptech/fltk/fltk-mt.pdf Is this what Fl::awake() does behind the scenes? Thanks. // // g++ -g -Wall -o randRectangle randRectangle.C `fltk-config --ldflags` - lpthread // #include <FL/Fl.H> #include <FL/Fl_Widget.H> #include <FL/fl_draw.H> #include <FL/Fl_Window.H> #include <FL/fl_ask.H> #include <iostream> #include <pthread.h> using namespace std; typedef pthread_t Fl_Thread; static int fl_create_thread(Fl_Thread& t, void *(*f) (void *), void* p) { return pthread_create((pthread_t*)&t, 0, f, p); } struct Color { int red, green, blue; Color(int r=0,int g=0,int b=0) : red(r), green(g), blue(b) {}; }; struct Rectangle { Color clr; int x,y,w,h; }; class Canvas : public Fl_Widget { public: Canvas(int x, int y, int w, int h) : Fl_Widget(x,y,w,h) {} void draw() { fl_push_clip(x(), y(), w(), h()); fl_rectf(0,0,w(),h(),255,255,255); fl_pop_clip(); } int handle(int event) { switch(event){ case FL_FOCUS: return 1; case FL_KEYDOWN: cerr << Fl::event_key() << endl; if(Fl::event_key()=='q') exit(0); break; default: return Fl_Widget::handle(event); } draw(); // Draw on each event received. return 1; }; }; // Callback for Fl::awake() void drawRectangle(void * data) { Rectangle * X=(Rectangle*) data; fl_rectf(X->x,X->y,X->w,X->h, X->clr.red,X->clr.green,X->clr.blue); } // Worker thread function: generate rectangles at random positions. void * makeRectangles(void * p) { Canvas * theCanvas=(Canvas*) p; Rectangle X; X.w=5; X.h=5; X.clr.red=0; X.clr.green=0; X.clr.blue=255; size_t nSleep=2; cerr << "Waiting " << nSleep << " seconds" << endl; sleep(nSleep); for(size_t i=0; i<1000000; i++){ cout << i << endl; // Choose x,y randomly: X.x=rand()%theCanvas->w(); X.y=rand()%theCanvas->h(); // and tell gui thread to draw. Fl::awake(drawRectangle, &X); // usleep(100000); } return 0; } int main() { Fl_Window window(400, 400, 0); Canvas theCanvas(0,0,400,400); window.end(); window.show(); Fl_Thread producerThread; Fl::lock(); fl_create_thread(producerThread, makeRectangles, &theCanvas); Fl::run(); } _______________________________________________ fltk mailing list [email protected] http://lists.easysw.com/mailman/listinfo/fltk

