-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow use of C++ semantics #2258
Comments
I don't understand how your suggestion with std::function can solve the class member and this arg example. |
For me, using a lambda function works fine in this example: attachInterrupt(somePin, [&]() { someMemberFunction(); }, CHANGE); But there also seems to be another solution suggested by maxgerhardt: attachInterrupt(somePin, std::bind(&MyClassName::someMemberFunction, this), CHANGE); (see https://community.platformio.org/t/how-to-assign-a-class-method-as-an-interrupt-handler/20501/2) |
The "bind" approach seems to be promising, but you need a valid "this" pointer while building the MUIF array. |
I added the MUIF array to the member variables, just like in the example. Doesn't seem like a bad thing to me. In this scope, it should have access to the |
I am currently testing the implementation of This is what i changed in #include <functional>
typedef std::function<uint8_t(mui_t* ui, uint8_t msg)> muif_cb;
// typedef uint8_t (*muif_cb)(mui_t* ui, uint8_t msg); Although my project code now accepts a lambda function with a reference to As I am compiling for an ESP32 with the PlatformIO system, it seems like the U8g2 library itself chooses that compiler. I have to investigate further to make this run and then test if my changes work on the running MCU. If |
not being able to use functional callbacks or class members is a bit frustrating :( // mui.h
typedef uint8_t (*muif_cb)(mui_t *ui, uint8_t msg, void* arg);
// then somewhere in the class
class MyClass {
uint8_t myvar;
void dosomething(uint8_t msg);
muif_t muif_main_configuration_menu_list[16] = {
// ...
MUIF_RO("HR", [](mui_t* ui, uint8_t msg, void* self){ static_cast<MyClass*>(self)->dosomething(msg); }, this),
};
fds_t mymenu[10] =
// A non-capturing lambda function
MUIF_RO("AB",
[](mui_t* ui, uint8_t msg, void* self) {
static_cast<MyClass*>(self)->myvar = 42;
return (uint8_t)0;
}),
// in case of static function this arg must be NULL'ed
MUIF_RO("HR", mui_hrule, NULL), // draw horizontal line on display
}; |
Well, yes "mui" is truly minimal. I wanted something small... I am sure there are better UI libs out there ;-) |
to my surprise most of them lack functional callbacks either :) Your one is really nice to have bundled with main u8g2 lib. |
Any solution should allow standard C compiler so handle mui code. But I am happy to included PRs if this precondition is met. |
I scratched my head for weeks trying to work-around it and somehow pass a reference to this* into MUI's callback struct so not to bring std::function dependency. But one way or the the other it has to change the structs with additional void* pointers and function arguments. So I guess it would not be a feasible option to keep backward compatibility with all the platforms u8g2 supports. MUI is pretty compact and works just fine for it's purpose. |
Background: #2252
Current Status
The U8g2 library is based around a C core library, that implements the actual functionality of U8g2 in object-oriented C.
Additionally, the library provides a thin C++ wrapper around that C core library for convenience.
Some of the C++ semantics do not work with this C++ layer though.
Consider this example, which showcases what works and what doesn't.
Ideas for solving the issue
The current implementation defines the call back with:
You suggested to use a friend function, which I think is not very elegant for a few reasons:
UIManager
, there is no quick way to do that.A modern C++ approach probably would choose the
std::function
type:A good practical example of that is Espressif's implementation of
attachInterrupt()
in their Arduino Core:https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/FunctionalInterrupt.h
The text was updated successfully, but these errors were encountered: