Skip to content
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

Regression: NetworkEvents::onEvent() can't register function calbacks via lambda expressions #10365

Open
1 task done
vortigont opened this issue Sep 22, 2024 · 0 comments · May be fixed by #10376
Open
1 task done

Regression: NetworkEvents::onEvent() can't register function calbacks via lambda expressions #10365

vortigont opened this issue Sep 22, 2024 · 0 comments · May be fixed by #10376
Labels
Status: Awaiting triage Issue is waiting for triage

Comments

@vortigont
Copy link
Contributor

Board

ESP32 Dev module

Device Description

plain module

Hardware Configuration

plain module

Version

latest master (checkout manually)

IDE Name

PlatformIO

Operating System

Ubuntu Linux

Flash frequency

defajult

PSRAM enabled

no

Upload speed

115200

Description

Network lib has a regression when updated from 3.0.4 to 3.0.5

The method NetworkEvents::onEvent
can no longer register two or more functional callbacks for Network event handling when those are lambda expressions.

In 2f89026 additional code was added that tries to check if an attempt is made to register a duplicate callback function based on determined address of a callback

if (findEvent(cbEvent, event) < cbEventList.size()) {

This template code does not work properly for lambdas and returns 0 (nullptr) always.

template<typename T, typename... U> static size_t getStdFunctionAddress(std::function<T(U...)> f) {
typedef T(fnType)(U...);
fnType **fnPointer = f.template target<fnType *>();
if (fnPointer != nullptr) {
return (size_t)*fnPointer;
}
return (size_t)fnPointer;
}

Do we really need that duplicate callbacks check? It's up to user to register callback, even if those are called twice there is no big deal in that. While that address-pointer comparison magic is tend to errors.

Sketch

#include "Arduino.h"
#include "WiFi.h"

#define MY_SSID    "My_SSID"
#define MY_PASS    "MY_PASSwd"

class MyWiFi{
private:
    wifi_event_id_t eid{999};
    wifi_event_id_t eid2{999};

    // member function for event handling 
    void _onWiFiEvent(arduino_event_id_t event, arduino_event_info_t info){
        Serial.printf( "event tracker1: %d - %s\n", event, Network.eventName(event));
    }

public:
    void reg_events(){
        // use capturing lambda for member function handler
        eid = WiFi.onEvent( [&](WiFiEvent_t event, WiFiEventInfo_t info){ _onWiFiEvent(event, info); } );
        if (eid)
            Serial.printf( "registered hndlr 1 with id:%u\n", eid);
        else
            Serial.println( "Err registering hndlr 1");

        // non-capturing lambda
        eid2 = WiFi.onEvent( [](WiFiEvent_t event, WiFiEventInfo_t info){ Serial.printf( "event tracker2: %d - %s\n", event, Network.eventName(event)); } );
        if (eid2)
            Serial.printf( "registered hndlr 2 with id:%u\n", eid2);
        else
            Serial.println( "Err registering hndlr 2");
    }

};

MyWiFi mywifi;

void setup(){
    Serial.begin(115200);

    mywifi.reg_events();
    WiFi.begin(MY_SSID, MY_PASS);
}


void loop() {}

Debug Message

Log messages with some additional debugging added

[   253][V][NetworkEvents.cpp:227] onEvent(): Check Event dupes, 0 out of 0
registered hndlr 1 with id:1
[   260][V][NetworkEvents.cpp:173] findEvent(): Compare: 0 vs 0
[   268][V][NetworkEvents.cpp:227] onEvent(): Check Event dupes, 0 out of 1
[   275][W][NetworkEvents.cpp:230] onEvent(): Attempt to add duplicate event handler!
Err registering hndlr 2

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@vortigont vortigont added the Status: Awaiting triage Issue is waiting for triage label Sep 22, 2024
@vortigont vortigont changed the title Regression: NetworkEvents::onEvent() can't register function calbacks via labda expressions Regression: NetworkEvents::onEvent() can't register function calbacks via lambda expressions Sep 22, 2024
vortigont added a commit to vortigont/arduino-esp32 that referenced this issue Sep 26, 2024
…llbacks

removing event callback via std::function pointer does not work as expected for lambdas (issue espressif#10365)
here mark NetworkEvents::removeEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX)
as deprecated in favor of removing by callback's id

for NetworkEvents::onEvent remove checking for dublicate event handler, this does not work for lambdas too

remove NetworkEvents::find methods as unnecessary

move cbEventList container inside the class

declare NetworkEventCbList_t as a cpp struct with constructor, allows using std::vector.emplace() when adding new items to container

optimize NetworkEvents::remove() calls to use erase-remove idiom for std::vector
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting triage Issue is waiting for triage
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant