From 2f85b367b0e55316bc12004aeba383c4ddb8054d Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 16 May 2026 16:17:10 +0200 Subject: [PATCH] replace std:function with lambda --- src/core/emsdevice.cpp | 4 ++-- src/core/emsdevice.h | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/core/emsdevice.cpp b/src/core/emsdevice.cpp index df8d47830..f80e9a343 100644 --- a/src/core/emsdevice.cpp +++ b/src/core/emsdevice.cpp @@ -2252,7 +2252,7 @@ bool EMSdevice::handle_telegram(const std::shared_ptr & telegram if (tf.telegram_type_id_ == telegram->type_id) { // for telegram destination only read telegram if (telegram->dest == device_id_ && telegram->message_length > 0) { - tf.process_function_(telegram); + tf.process_function_(this, telegram); return true; } // if the data block is empty and we have not received data before, assume that this telegram @@ -2270,7 +2270,7 @@ bool EMSdevice::handle_telegram(const std::shared_ptr & telegram } if (telegram->message_length > 0) { tf.received_ = true; - tf.process_function_(telegram); + tf.process_function_(this, telegram); } return true; diff --git a/src/core/emsdevice.h b/src/core/emsdevice.h index 0f10a9f06..43011b078 100644 --- a/src/core/emsdevice.h +++ b/src/core/emsdevice.h @@ -34,7 +34,15 @@ class EMSdevice { public: virtual ~EMSdevice() = default; // destructor of base class must always be virtual because it's a polymorphic class - using process_function_p = std::function &)>; + // Raw function pointer + EMSdevice* context, instead of std::function. + // Each std::function typically heap-allocates its capture (a few + // bytes for the [&] closure) on libstdc++ ESP32 builds. With hundreds of + // registered telegram handlers across devices, that's tens of KB of + // long-lived heap. The MAKE_PF_CB macro produces a non-capturing trampoline + // that decays to this raw pointer (zero heap, zero indirection beyond the + // call itself). The first parameter receives `this` of the dispatching + // EMSdevice instance; the trampoline downcasts to the actual derived type. + using process_function_p = void (*)(EMSdevice * dev, const std::shared_ptr & t); // device_type defines which derived class to use, e.g. BOILER, THERMOSTAT etc.. EMSdevice(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * default_name, uint8_t flags, uint8_t brand)