FLTK logo

Re: [fltk.general] Re: Window is frozen

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.general  ]
 
Previous Message ]New Message | Reply ]Next Message ]

Re: Re: Window is frozen supsm17 Nov 29, 2021  
  Thanks for all the help. I usually don't use pointers frequently so I apologize for the dumb mistake.

On Monday, November 29, 2021 at 3:11:59 AM UTC-8 Ian MacArthur wrote:
Coffee break: Here's a worked example based on the OP code - though note that I had to "de-C++ify" it to make it work with the somewhat ancient compiler on this particular machine!

fltk-config --compile test.cxx

-------------------


#include <memory>
#include <string>

#include "FL/Fl.H"
#include "FL/Fl_Double_Window.H"
#include "FL/Fl_Browser.H"
#include "FL/Fl_Button.H"
#include "FL/Fl_Toggle_Button.H"

#ifdef _WIN32
# include <process.h>

typedef unsigned long Fl_Thread;
extern "C" {
    typedef void * (__cdecl Fl_Thread_Func) (void *);
}

static int fl_create_thread (Fl_Thread &t, Fl_Thread_Func *f, void *p)
{
    return t = (Fl_Thread)_beginthread ((void (__cdecl *) (void *))f, 0, p);
}

#define DELAY(XX) Sleep(XX)
#else
# include <pthread.h>

typedef pthread_t Fl_Thread;
extern "C" {
    typedef void * (Fl_Thread_Func) (void *);
}

static int fl_create_thread (Fl_Thread &t, Fl_Thread_Func *f, void *p)
{
    return pthread_create ((pthread_t *)&t, 0, f, p);
}

#define DELAY(XX) usleep(XX * 1000)
#endif

static Fl_Thread t = (Fl_Thread)0;
static volatile bool thread_alive = false;
static bool keep_alive = false;

static void run_once (Fl_Button *, void *);
static void run_many (Fl_Button *, void *);

class UI
{
public:
    Fl_Double_Window *window;
    Fl_Browser *output;
    UI()
    {
        {
            window = new Fl_Double_Window (660, 420, "Thread Test");
            window->begin();

            Fl_Button *bt = new Fl_Button (445, 370, 190, 30, "Run Once");
            bt->labelfont (1);
            bt->labelsize (16);
            bt->callback ((Fl_Callback *)run_once);

            bt = new Fl_Toggle_Button (445, 330, 190, 30, "Run Many");
            bt->labelfont (1);
            bt->labelsize (16);
            bt->callback ((Fl_Callback *)run_many);

            output = new Fl_Browser (25, 40, 395, 275);
            output->box (FL_BORDER_BOX);
            output->textfont (4);
        }
    }
};

static std::unique_ptr<UI> ui;

static volatile bool in_use = false;
static char text_buffer [128];

static void awake (void *)
{
    if (in_use)
    {
        ui->output->add (text_buffer);
        int ln = ui->output->size();
        ui->output->bottomline (ln);
        in_use = false;
    }
}

static void output (const char *pc)
{
    if (!in_use)
    {
        snprintf (text_buffer, 128, "@S14@C92@.%s", pc);
        in_use = true;
        puts (text_buffer);
        Fl::awake (awake, NULL);
    }
}

static void output (std::string s)
{
    output (s.c_str());
}

static void *thread (void *)
{
    while (thread_alive)
    {
        output ("a");

        DELAY (1000);

        output ("b");

        unsigned temp = 1;
        for (int i = 1; i < 1000000000; i++)
        {
            temp += i;
        }

        output (std::to_string (temp));

        if (!keep_alive)
        {
            thread_alive = false;
        }
        else
        {
            // busy wait for awake to flush the previous message
            while (in_use);
        }
    }

    // busy wait for awake to flush the message
    while (in_use);
    output ("Worker Thread Exit");
    t = (Fl_Thread)0;
    return NULL;
}

static void run_once (Fl_Button *, void *)
{
    if (!t)
    {
        thread_alive = true;
        fl_create_thread (t, thread, NULL);
    }
}

static void run_many (Fl_Button *, void *)
{
    if (!t)
    {
        thread_alive = true;
        keep_alive = true;
        fl_create_thread (t, thread, NULL);
    }
    else
    {
        keep_alive = false;
    }
}

int main (int argc, char *argv[])
{
    ui = std::make_unique<UI>();

    Fl::lock();
    ui->window->show (argc, argv);

    // Only the first of these strings will appear, since the
    // worker thread is
    for (int i = 0; i < 20; i++)
    {
        char buf [32];
        snprintf (buf, 32, "%d", i);
        ui->output->add (buf);
        int ln = ui->output->size();
        ui->output->bottomline (ln);
    }
    Fl::run();

    // Tell the worker to expire - if it is still alive!
    keep_alive = false;
    thread_alive = false;

    return 0;
}

// end of file


 

--
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkgeneral/820dc052-d141-4f1a-bd7f-4ee7bfbd70d9n%40googlegroups.com.
Direct Link to Message ]
 
     
Previous Message ]New Message | Reply ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.