Latest 1.4 with W11 and VS2019

21 views
Skip to first unread message

pvr...@btinternet.com

unread,
Mar 2, 2022, 6:07:22 AM3/2/22
to fltk.general
I have moved this to a separate thread.

I am migrating from a version of 1.4 downloaded 2020/3/22 to one downoaded 2022/2/28.

I experienced some issues with not having compatible include directives, but thta's not a problem with the package.

I am now expriencing the following...

My app never gets to the call of fl::run() as it launches a server that listens for receipts of UDP datagrams from another application first. It then loops listening for these.

Previously the FLTK scheduler would still respond to events from FLTK buttons before I call fl::run(). Now it does not. I have a note in the code to implement the UDP server as a separate thread, but this will require me to understand multi-threading first. Is there a light-weight mechanism in FLTK that I can launch the UDP server and procede to the call of fl::run()?

Thanks in advance
Phil.

Albrecht Schlosser

unread,
Mar 2, 2022, 8:12:19 AM3/2/22
to fltkg...@googlegroups.com
On 3/2/22 12:07 'pvr...@btinternet.com' via fltk.general wrote:
I am migrating from a version of 1.4 downloaded 2020/3/22 to one downoaded 2022/2/28.

I am now expriencing the following...

My app never gets to the call of fl::run() as it launches a server that listens for receipts of UDP datagrams from another application first. It then loops listening for these.

Previously the FLTK scheduler would still respond to events from FLTK buttons before I call fl::run(). Now it does not.

This described "previous" behavior is technically not possible - unless you used Fl::wait() or something like this that dispatches FLTK events. Fl::run() does this for you in a loop as long as there are open windows.


I have a note in the code to implement the UDP server as a separate thread, but this will require me to understand multi-threading first. Is there a light-weight mechanism in FLTK that I can launch the UDP server and procede to the call of fl::run()?

Calling Fl::wait() inside your polling loop will do what you want because this is what Fl::run() would do. You can't use blocking read's though on your UDP server (socket), of course, because this would obviously block calling Fl::wait() as well. Untested pseudo code follows:

int connected = 0;
while (!connected) {
  Fl::wait(0.05); // wait 1/20 of a second
  if ( poll_udp_socket() ) { // must be unblocking!
    // do something
    connected = 1;
  }
}

return Fl::run();


Another way would be to use Fl::add_idle() and run your polling in the idle loop but this is another issue and not as simple as it may sound, maybe.


pvr...@btinternet.com

unread,
Mar 2, 2022, 9:42:09 AM3/2/22
to fltk.general
Thanks Albrecht. I am now happy with the latest 1.4 version (well Monday's at least)

On Wednesday, March 2, 2022 at 1:12:19 PM UTC Albrecht Schlosser wrote:
On 3/2/22 12:07 'pvr...@btinternet.com' via fltk.general wrote:
I am migrating from a version of 1.4 downloaded 2020/3/22 to one downoaded 2022/2/28.

I am now expriencing the following...

My app never gets to the call of fl::run() as it launches a server that listens for receipts of UDP datagrams from another application first. It then loops listening for these.

Previously the FLTK scheduler would still respond to events from FLTK buttons before I call fl::run(). Now it does not.

This described "previous" behavior is technically not possible - unless you used Fl::wait() or something like this that dispatches FLTK events. Fl::run() does this for you in a loop as long as there are open windows.

I knpw I played around with using Fl::wait() to get certain stuff to draw. I don't recall changing this as part of the migration.


I have a note in the code to implement the UDP server as a separate thread, but this will require me to understand multi-threading first. Is there a light-weight mechanism in FLTK that I can launch the UDP server and procede to the call of fl::run()?

Calling Fl::wait() inside your polling loop will do what you want because this is what Fl::run() would do. You can't use blocking read's though on your UDP server (socket), of course, because this would obviously block calling Fl::wait() as well. Untested pseudo code follows:

int connected = 0;
while (!connected) {
  Fl::wait(0.05); // wait 1/20 of a second
  if ( poll_udp_socket() ) { // must be unblocking!
    // do something
    connected = 1;
  }
}

return Fl::run();

I've now added Fl::wait() if the non-blocking poll returns no data. If it returns data I want it to process it. This now does what I want, and I have also managed it to control the display of my load progress bar at the speed I want using redraw() of the appropriate widget and use of Fl::wait().
o

Another way would be to use Fl::add_idle() and run your polling in the idle loop but this is another issue and not as simple as it may sound, maybe.



Regards Phil.

pvr...@btinternet.com

unread,
Mar 2, 2022, 9:50:06 AM3/2/22
to fltk.general
On Wednesday, March 2, 2022 at 2:42:09 PM UTC pvr...@btinternet.com wrote:
Thanks Albrecht. I am now happy with the latest 1.4 version (well Monday's at least)

On Wednesday, March 2, 2022 at 1:12:19 PM UTC Albrecht Schlosser wrote:
On 3/2/22 12:07 'pvr...@btinternet.com' via fltk.general wrote:
Previously the FLTK scheduler would still respond to events from FLTK buttons before I call fl::run(). Now it does not.

This described "previous" behavior is technically not possible - unless you used Fl::wait() or something like this that dispatches FLTK events. Fl::run() does this for you in a loop as long as there are open windows.

I knpw I played around with using Fl::wait() to get certain stuff to draw. I don't recall changing this as part of the migration.

Looking at my code again, I set a timeout after pulling a UDP packet to pull the next one. Has the behaviour of this changed?

Phil.

Albrecht Schlosser

unread,
Mar 2, 2022, 10:47:29 AM3/2/22
to fltkg...@googlegroups.com
Short answer: yes and no...

Long answer: According to the title of this thread you're on Windows. The previous versions of Fl::add_timeout() and Fl::repeat_timeout() used system timers on Windows and macOS whereas Unix/Linux/X11 used its own timeout mechanism synchronized by the event loop.

The old FLTK code was not cross-platform compatible and some implementation details differed significantly. This has been unified recently so it is now 100% cross-platform using the Unix/X11 internal timeout mechanism.

This means that FLTK timers can only work when the FLTK event loop is running, i.e. either by calling Fl::run() once or Fl::wait() repeatedly.

The old version of your program would have worked on Windows (as you wrote) and likely on macOS but not on Linux/Unix (X11/Wayland) nor on the Android port (beta, currently not supported) and any other future platform (Wayland etc.).

You have two options:
(1) as you did already, using Fl::wait() inside your polling loop before Fl::run()
(2) use Fl::add_timeout() and Fl::repeat_timeout() while polling but run Fl::run() anyway.

Pseudo code for option (2):

void poll_udp(void *) {
  // ... poll udp socket ...
  if (!connected)
    Fl::repeat_timeout(0.1, poll_udp);
}

int main() {
  // ... init ...
  Fl::add_timeout(0.1, poll_udp);
  Fl::run();
}



Sorry for the inconveniencies and thank you very much for the heads-up. This is indeed a behavioral change on some platforms but it's an intended change and will not be reverted. I'll document this to make it clear.

Ian MacArthur

unread,
Mar 2, 2022, 11:03:45 AM3/2/22
to fltk.general
And, somewhat related, if you want to "listen" to your UDP socket, then I'd be taking a good look at fl:;add_fd() for that, as that works on sockets OK, even on Win32 (which is otherwise a bit rubbish at handling listening to an fd of any other type!)


Reply all
Reply to author
Forward
0 new messages