[rtttl] Gate on_finished_playback callback storage behind define

Wrap the on_finished_playback CallbackManager storage, registration
method and call site behind USE_RTTTL_FINISHED_PLAYBACK_CALLBACK so
configs without an on_finished_playback automation pay zero RAM and
zero flash for it.

Keeps CallbackManager rather than switching to StaticCallbackManager
because rtttl is MULTI_CONF — a per-class compile-time N would force
every instance to reserve max(callbacks_per_instance) slots.
This commit is contained in:
J. Nick Koston
2026-04-25 14:26:23 -05:00
parent b5ccd55f4e
commit 12f744bbbe
5 changed files with 17 additions and 1 deletions
+3 -1
View File
@@ -93,7 +93,9 @@ async def to_code(config):
cg.add(var.set_gain(config[CONF_GAIN]))
await automation.build_callback_automations(var, config, _CALLBACK_AUTOMATIONS)
if config.get(CONF_ON_FINISHED_PLAYBACK):
cg.add_define("USE_RTTTL_FINISHED_PLAYBACK_CALLBACK")
await automation.build_callback_automations(var, config, _CALLBACK_AUTOMATIONS)
@automation.register_action(
+2
View File
@@ -424,7 +424,9 @@ void Rtttl::set_state_(State state) {
// Clear loop_done when transitioning from `State::STOPPED` to any other state
if (state == State::STOPPED) {
this->disable_loop();
#ifdef USE_RTTTL_FINISHED_PLAYBACK_CALLBACK
this->on_finished_playback_callback_.call();
#endif
ESP_LOGD(TAG, "Playback finished");
} else if (old_state == State::STOPPED) {
this->enable_loop();
+6
View File
@@ -2,6 +2,8 @@
#include "esphome/core/automation.h"
#include "esphome/core/component.h"
#include "esphome/core/defines.h"
#include "esphome/core/helpers.h"
#ifdef USE_OUTPUT
#include "esphome/components/output/float_output.h"
@@ -45,9 +47,11 @@ class Rtttl : public Component {
bool is_playing() { return this->state_ != State::STOPPED; }
#ifdef USE_RTTTL_FINISHED_PLAYBACK_CALLBACK
template<typename F> void add_on_finished_playback_callback(F &&callback) {
this->on_finished_playback_callback_.add(std::forward<F>(callback));
}
#endif
protected:
inline uint16_t get_integer_() {
@@ -106,8 +110,10 @@ class Rtttl : public Component {
uint32_t samples_gap_{0};
#endif // USE_SPEAKER
#ifdef USE_RTTTL_FINISHED_PLAYBACK_CALLBACK
/// The callback to call when playback is finished.
CallbackManager<void()> on_finished_playback_callback_;
#endif
};
template<typename... Ts> class PlayAction : public Action<Ts...> {
+1
View File
@@ -185,6 +185,7 @@
#define USE_MQTT
#define USE_MQTT_COVER_JSON
#define USE_NETWORK
#define USE_RTTTL_FINISHED_PLAYBACK_CALLBACK
#define USE_RUNTIME_IMAGE_BMP
#define USE_RUNTIME_IMAGE_PNG
#define USE_RUNTIME_IMAGE_JPEG
+5
View File
@@ -29,3 +29,8 @@ output:
rtttl:
output: rtttl_output
on_finished_playback:
- then:
- logger.log: "Playback finished 1"
- then:
- logger.log: "Playback finished 2"