FLTK logo

[fltk/fltk] Using Fl_Callback_Interface with Fl_Timeout (Fl::add_timeout(), Fl::repeat_timeout()) (PR #1600)

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

[fltk/fltk] Using Fl_Callback_Interface with Fl_Timeout (Fl::add_timeout(), Fl::repeat_timeout()) (PR #1600) Matthias Melcher 06:35 Sep 04  
 

This PR is less for merging and more to show how Fl_Callback_Interface would work with Fl_Timeout.

I am pretty sure this will be rejected - at least in this extreme - because it does add the "templatefication" that we do not want. It's a readability issue though. On the functional side, this is quite awesome.

So what are we doing here. Fl::add_timeout() calls static Fl_Timeout::add_timeout() which manages a list of pending and unused Fl_Timeout instances. The only supported callback is void()(void*). Making Fl_Callback_Interface a base class of Fl_Timeout adds all the other callback convenience that is now in Fl_Widget, plus being back compatible for creating timeouts.

Well, what are the drawbacks?

1

First of all, we have an API for removing timeouts that does not work with lambdas. Fl::remove_timeout(callback, user_data) can't work, because std::function does not ever return a unique address of anything.

Well, this is solvable if Fl::add_timeout() returns a pointer to Fl_Timeout, right? No, because when a timer expires, Fl_Timeout becomes invalid after the callback. Calling Fl::remove_timeout(Fl_Timout* t) after a certain time would be undefined.

The solution would be to return an ever increasing Fl_Timeout_ID, and add Fl::remove_timeout(Fl_Timeout_ID) which would only remove a timer if it was still pending. SO that is solvable, but adds a new (and improved) API.

2

The second feature is completely optional, and the issue with it is scary and amazing at the same time. In the code for Fl_Timeout, I implemented static Fl_Timeout::add_timeout() with a template:

  template<typename... Args>
  static void Fl_Timeout::add_timeout(double time, Args&&... args) { 
    ...
    new_timeout->callback((std::forward<Args>(args)...));
    ...
  }

What this odes is amazing: for every FL_Callback_Interface::callback(...) function, the compiler creates a corresponding Fl_Timeout::add_timeout(double, ...) function, if required. So with just four lines of code, we get 11 new Fl::add_timeout() functions. Wow!

Since all the template features of C++ are only available in header files, Fl_Timeout would need to be public in the FL header directory.

new APIs

To illustrate, if implemented all the way, we get the following APIs and even more, and they only generate code if they are actually used:

// lambdas:
Fl::add_timeout( 3.0, [something]() { something->run(); } )
// and we can serve these callbacks:
void ()(void*);
void ()(long);
void ()(Fl_Timeout*);
void ()(Fl_Timeout*, void*);
// etc.

Example

// A set-and-forget timer, classic style, with allocated data
void timer_cb(void *u) {
  // do something with 'u'
}

void free_cb(void* u) {
  ::free(u);
}

void* important_data = malloc(3, 1024);
Fl::add_timeout(5.0, timer_cb, important_data, free_cb);
// important_data will be free'd by FLTK after the timer callback returns

You can view, comment on, or merge this pull request online at:

  https://github.com/fltk/fltk/pull/1600

Commit Summary

  • 66a7242 Extract Fl_Widget::callback into an Interface
  • e263c97 Fix generalizd do_callback,
  • 6bbef5b Phase 2: Use Callback Interface with Fl_File_Chooser
  • 14e724b Phase 3a: store user data destructor
  • dc41f38 Phase 3b: allow an arbitray destructor for Fl_Cllback_User_Data
  • 154f2b4 Phase 3c: custom user_data free callback for void*
  • 40f640c Phase 4: add std::function callbacks
  • 0b673b3 Making gcc happy.
  • 9187387 Making Windows happy as well
  • 7d352f0 Fixed std::function creation and destruction
  • 1804a40 Phase 5: avoid casting function pointers, cleanup, documentation
  • 462b9d3 Fl_Timeout with Fl_Callback_Interface. Read the Text with the PR.

File Changes

(10 files)

Patch Links:

—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.Message ID: <fltk/fltk/pull/1600@github.com>

[ Direct Link to Message ]
 
     
[ Previous Message ] [ New Message | Reply ] [ Next Message ]
 
 

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