fire-eggs / YAIV

"Yet Another Image Viewer"
MIT License
3 stars 0 forks source link

src/XBox.cpp:26:22: error: ‘chrono_literals’ is not a namespace-name #128

Open rageworx opened 1 year ago

rageworx commented 1 year ago

Dear Kevin, I'm working on merging your latest version of YAIV to mine, and fixing compilation errors for some other platform - Embedded Linux Kernel 4.4.179 - with 6.3.0, and occurs some unsupported issue on XBox.cpp with chrono_literals. Looks std::chrono_literals is supported since c++14, and most modern compilers may should support this features, but some compilers are still not.

Is there some reason to used chron_literals to used durations or calculating elapse time period ? Please let me know to support old compilers :).

fire-eggs commented 1 year ago

Hi, raph - The code doesn't seem to actually need that using statement. (At least in KDevelop...) I think I've got KDevelop building as C++11 and is OK if I delete that using.

The purpose is to wait a specified time and produce a message if the wait runs out. The time is specified via std::chrono::milliseconds which I think is C++11 ?

This is the chunk of code in question:

        std::future<Fl_Image *> future = std::async(std::launch::async, loadFile, (char*)fullpath, this);
        std::future_status status = future.wait_for(std::chrono::milliseconds(750));
        if (status != std::future_status::ready)
        {
            showUserMessage("Loading...");
        }

It could be replaced with the previous commit:

Fl_Image *img = loadFile((char *)fullpath, this);
rageworx commented 1 year ago

As decision of std::chrono_literals is part of C++14, so I asked is it really used or not - and tested it is OK to build as well as commented.

And I'm not sure why you need std::async() before read file to wait 750ms. Is it something related to "not flushed image file" from somewhere ? Or something issue on cached from memory to do not read actually changed image file ? Just let me know to something you have reason why :)

fire-eggs commented 1 year ago

And I'm not sure why you need std::async() before read file to wait 750ms.

The intent is to display the message if the load time takes longer than 750ms. This requires two activities: a timer and the file-load. One or the other has to run in a separate thread.

Here's some pseudo-code suggesting how it might be done by running the timer in a separate thread. (I don't know off-hand how run_timer_in_separate_thread might be implemented.)

bool load_finished;

void timer_callback()
{
    if (!load_finished)
        show_message("Loading...");
}
...
    load_finished = false;
    run_timer_in_separate_thread(750ms, timer_callback);
    Fl_Image *img = loadFile(fullpath, this);
    load_finished = true;
    clear_message();
rageworx commented 1 year ago

I have some similar solution to display something current FLTK window to be displayed by timer as this video.

https://user-images.githubusercontent.com/6948225/223291080-6192a47a-2dd7-408d-bc4b-56bd859c9ca3.mp4

A pthread is looping to grab images, and changes something to be displayed, but FLTK update always slow and even macOS cannot display update non-main thread. So I'm using FLTK timer to display status like above video with timer flag as like this,

Part of timer flags

#define TAF_SEARCH_DEVICE       0x0000000000000004
#define TAF_OLGRAPH_LOOP        0x0000000000000100
#define TAF_STOP_POLL           0x0000000000001000

Calling timer anywhere in thread

                timerActFlag |= TAF_STOP_POLL;
                if ( Fl::has_timeout( fl_timer_cb, this ) > 0 )
                    Fl::repeat_timeout( TIMER_DELAYED_TIMEF, fl_timer_cb, this );
                else
                    Fl::add_timeout( TIMER_DELAYED_TIMEF, fl_timer_cb, this );
                return;

Process timer callback with flag bits

void wMain::TimerCB()
{
    if ( timerActFlag > 0 )
    {
        if ( ( timerActFlag & TAF_STOP_POLL) > 0 )
        {
            // let click btnPoll ...
            if ( btnPoll->active_r() > 0 )
            {
                btnPoll->do_callback();
            }

            timerActFlag &= ~TAF_STOP_POLL;
            timerrefcnt--;
            return;
        }
}

Doing like this, as an asynchronous update by timer. Is this method is similar ? This method is suitable for all platforms - macOS and Windows even Linux X11.

fire-eggs commented 1 year ago

Doing like this, as an asynchronous update by timer. Is this method is similar ?

Yes, we're both on the same page with this. The similar situation in YAIV is the "file scan" pthread in fileScanThread.cpp: instead of a timer to update the GUI, I use Fl::awake() to periodically send a FLTK event.

The std::async version seems to me to be a cleaner and easier implementation compared to the equivalent pthread/timer version. loadFile is a one-shot task: std::async nicely invokes it in a separate thread, and std::future provides a convenient timeout check. There's no timer callback function, no global "file load done" flag, and no FLTK wait loop (to allow the timer to actually run).

I'd do it differently if this was an involved background process with expensive impact on the GUI.

fire-eggs commented 1 year ago

In case I've misunderstood something : is using std::async or std::future a problem for platforms other than Linux?

rageworx commented 1 year ago

In case I've misunderstood something : is using std::async or std::future a problem for platforms other than Linux?

Nope ! Not a problem, That's all right :)