From 320fdeb9d8355d3c361d5c6d60de8afc64501af9 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Wed, 30 Aug 2023 16:48:10 +1000 Subject: Use a service locator instead of passing around subsets of drivers between FSMs --- src/audio/audio_fsm.cpp | 71 +++++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 43 deletions(-) (limited to 'src/audio/audio_fsm.cpp') diff --git a/src/audio/audio_fsm.cpp b/src/audio/audio_fsm.cpp index 6cca8211..9121cb5a 100644 --- a/src/audio/audio_fsm.cpp +++ b/src/audio/audio_fsm.cpp @@ -25,6 +25,7 @@ #include "future_fetcher.hpp" #include "i2s_audio_output.hpp" #include "i2s_dac.hpp" +#include "service_locator.hpp" #include "system_events.hpp" #include "track.hpp" #include "track_queue.hpp" @@ -33,49 +34,15 @@ namespace audio { static const char kTag[] = "audio_fsm"; -drivers::IGpios* AudioState::sIGpios; -std::shared_ptr AudioState::sDac; -std::weak_ptr AudioState::sDatabase; +std::shared_ptr AudioState::sServices; std::shared_ptr AudioState::sFileSource; std::unique_ptr AudioState::sDecoder; std::shared_ptr AudioState::sSampleConverter; std::shared_ptr AudioState::sOutput; -TrackQueue* AudioState::sTrackQueue; std::optional AudioState::sCurrentTrack; -auto AudioState::Init(drivers::IGpios* gpio_expander, - std::weak_ptr database, - std::shared_ptr tag_parser, - drivers::Bluetooth* bluetooth, - TrackQueue* queue) -> bool { - sIGpios = gpio_expander; - sTrackQueue = queue; - - auto dac = drivers::I2SDac::create(gpio_expander); - if (!dac) { - return false; - } - sDac.reset(dac.value()); - sDatabase = database; - - sFileSource.reset(new FatfsAudioInput(tag_parser)); - sOutput.reset(new I2SAudioOutput(sIGpios, sDac)); - // sOutput.reset(new BluetoothAudioOutput(bluetooth)); - - sSampleConverter.reset(new SampleConverter()); - sSampleConverter->SetOutput(sOutput); - - Decoder::Start(sFileSource, sSampleConverter); - - return true; -} - -void AudioState::react(const system_fsm::StorageMounted& ev) { - sDatabase = ev.db; -} - void AudioState::react(const system_fsm::KeyUpChanged& ev) { if (ev.falling && sOutput->AdjustVolumeUp()) { ESP_LOGI(kTag, "volume up!"); @@ -100,7 +67,26 @@ void AudioState::react(const system_fsm::HasPhonesChanged& ev) { namespace states { -void Uninitialised::react(const system_fsm::BootComplete&) { +void Uninitialised::react(const system_fsm::BootComplete& ev) { + sServices = ev.services; + + auto dac = drivers::I2SDac::create(sServices->gpios()); + if (!dac) { + events::System().Dispatch(system_fsm::FatalError{}); + events::Ui().Dispatch(system_fsm::FatalError{}); + return; + } + + sFileSource.reset(new FatfsAudioInput(sServices->tag_parser())); + sOutput.reset(new I2SAudioOutput(sServices->gpios(), + std::unique_ptr{*dac})); + // sOutput.reset(new BluetoothAudioOutput(bluetooth)); + + sSampleConverter.reset(new SampleConverter()); + sSampleConverter->SetOutput(sOutput); + + Decoder::Start(sFileSource, sSampleConverter); + transit(); } @@ -117,19 +103,18 @@ void Standby::react(const internal::InputFileOpened& ev) { } void Standby::react(const QueueUpdate& ev) { - auto current_track = sTrackQueue->GetCurrent(); + auto current_track = sServices->track_queue().GetCurrent(); if (!current_track || (sCurrentTrack && *sCurrentTrack == *current_track)) { return; } sCurrentTrack = current_track; - auto db = sDatabase.lock(); + auto db = sServices->database().lock(); if (!db) { ESP_LOGW(kTag, "database not open; ignoring play request"); return; } - sFileSource->SetPath(db->GetTrackPath(*current_track)); } @@ -158,7 +143,7 @@ void Playback::react(const QueueUpdate& ev) { if (!ev.current_changed) { return; } - auto current_track = sTrackQueue->GetCurrent(); + auto current_track = sServices->track_queue().GetCurrent(); if (!current_track) { sFileSource->SetPath(); sCurrentTrack.reset(); @@ -168,7 +153,7 @@ void Playback::react(const QueueUpdate& ev) { sCurrentTrack = current_track; - auto db = sDatabase.lock(); + auto db = sServices->database().lock(); if (!db) { return; } @@ -191,8 +176,8 @@ void Playback::react(const internal::InputFileClosed& ev) {} void Playback::react(const internal::InputFileFinished& ev) { ESP_LOGI(kTag, "finished playing file"); - sTrackQueue->Next(); - if (!sTrackQueue->GetCurrent()) { + sServices->track_queue().Next(); + if (!sServices->track_queue().GetCurrent()) { transit(); } } -- cgit v1.2.3