summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-08-30 16:48:10 +1000
committerjacqueline <me@jacqueline.id.au>2023-08-30 16:48:10 +1000
commit320fdeb9d8355d3c361d5c6d60de8afc64501af9 (patch)
treef0d5a2ab82199c78ad6768c6b18ba1239a0b7ee4 /src/ui
parent4247c9fe7d25c921fbfc73fc50e849c8780e7ad6 (diff)
downloadtangara-fw-320fdeb9d8355d3c361d5c6d60de8afc64501af9.tar.gz
Use a service locator instead of passing around subsets of drivers between FSMs
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/include/lvgl_task.hpp27
-rw-r--r--src/ui/include/screen_playing.hpp4
-rw-r--r--src/ui/include/screen_settings.hpp6
-rw-r--r--src/ui/include/ui_fsm.hpp25
-rw-r--r--src/ui/include/wheel_encoder.hpp4
-rw-r--r--src/ui/lvgl_task.cpp79
-rw-r--r--src/ui/screen_playing.cpp6
-rw-r--r--src/ui/screen_settings.cpp8
-rw-r--r--src/ui/ui_fsm.cpp101
-rw-r--r--src/ui/wheel_encoder.cpp15
10 files changed, 148 insertions, 127 deletions
diff --git a/src/ui/include/lvgl_task.hpp b/src/ui/include/lvgl_task.hpp
index 7e60c4b4..6b7e446e 100644
--- a/src/ui/include/lvgl_task.hpp
+++ b/src/ui/include/lvgl_task.hpp
@@ -12,15 +12,38 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
+#include "freertos/timers.h"
#include "display.hpp"
#include "relative_wheel.hpp"
+#include "screen.hpp"
#include "themes.hpp"
#include "touchwheel.hpp"
+#include "wheel_encoder.hpp"
namespace ui {
-auto StartLvgl(std::weak_ptr<drivers::RelativeWheel> touch_wheel,
- std::weak_ptr<drivers::Display> display) -> void;
+class UiTask {
+ public:
+ static auto Start() -> UiTask*;
+
+ ~UiTask();
+
+ // FIXME: Once we have more input devices, this function should accept a more
+ // generic interface.
+ auto SetInputDevice(std::shared_ptr<TouchWheelEncoder> dev) -> void;
+
+ private:
+ UiTask();
+
+ auto Main() -> void;
+
+ std::shared_ptr<TouchWheelEncoder> input_device_;
+ std::shared_ptr<Screen> current_screen_;
+
+ std::atomic<bool> quit_;
+ SemaphoreHandle_t frame_semaphore_;
+ TimerHandle_t frame_timer_;
+};
} // namespace ui
diff --git a/src/ui/include/screen_playing.hpp b/src/ui/include/screen_playing.hpp
index c684ddff..f2998c88 100644
--- a/src/ui/include/screen_playing.hpp
+++ b/src/ui/include/screen_playing.hpp
@@ -29,7 +29,7 @@ namespace screens {
class Playing : public Screen {
public:
explicit Playing(std::weak_ptr<database::Database> db,
- audio::TrackQueue* queue);
+ audio::TrackQueue& queue);
~Playing();
auto Tick() -> void override;
@@ -51,7 +51,7 @@ class Playing : public Screen {
auto ApplyNextUp(const std::vector<database::Track>& tracks) -> void;
std::weak_ptr<database::Database> db_;
- audio::TrackQueue* queue_;
+ audio::TrackQueue& queue_;
std::optional<database::Track> track_;
std::vector<database::Track> next_tracks_;
diff --git a/src/ui/include/screen_settings.hpp b/src/ui/include/screen_settings.hpp
index 61375fa9..0ec96d26 100644
--- a/src/ui/include/screen_settings.hpp
+++ b/src/ui/include/screen_settings.hpp
@@ -37,14 +37,14 @@ class Headphones : public MenuScreen {
class Appearance : public MenuScreen {
public:
- Appearance(drivers::NvsStorage* nvs, drivers::Display* display);
+ Appearance(drivers::NvsStorage& nvs, drivers::Display& display);
auto ChangeBrightness(uint_fast8_t) -> void;
auto CommitBrightness() -> void;
private:
- drivers::NvsStorage* nvs_;
- drivers::Display* display_;
+ drivers::NvsStorage& nvs_;
+ drivers::Display& display_;
lv_obj_t* current_brightness_label_;
uint_fast8_t current_brightness_;
diff --git a/src/ui/include/ui_fsm.hpp b/src/ui/include/ui_fsm.hpp
index 1fa6bf26..12fe5c69 100644
--- a/src/ui/include/ui_fsm.hpp
+++ b/src/ui/include/ui_fsm.hpp
@@ -11,9 +11,12 @@
#include "audio_events.hpp"
#include "battery.hpp"
+#include "gpios.hpp"
+#include "lvgl_task.hpp"
#include "nvs.hpp"
#include "relative_wheel.hpp"
#include "screen_playing.hpp"
+#include "service_locator.hpp"
#include "tinyfsm.hpp"
#include "display.hpp"
@@ -24,15 +27,13 @@
#include "touchwheel.hpp"
#include "track_queue.hpp"
#include "ui_events.hpp"
+#include "wheel_encoder.hpp"
namespace ui {
class UiState : public tinyfsm::Fsm<UiState> {
public:
- static auto Init(drivers::IGpios*,
- std::shared_ptr<drivers::NvsStorage>,
- audio::TrackQueue*,
- std::shared_ptr<battery::Battery>) -> bool;
+ static auto InitBootSplash(drivers::IGpios&) -> bool;
virtual ~UiState() {}
@@ -46,7 +47,7 @@ class UiState : public tinyfsm::Fsm<UiState> {
/* Fallback event handler. Does nothing. */
void react(const tinyfsm::Event& ev) {}
- void react(const system_fsm::BatteryStateChanged&);
+ virtual void react(const system_fsm::BatteryStateChanged&);
virtual void react(const audio::PlaybackStarted&) {}
virtual void react(const audio::PlaybackUpdate&) {}
@@ -76,15 +77,10 @@ class UiState : public tinyfsm::Fsm<UiState> {
void PopScreen();
void UpdateTopBar();
- static drivers::IGpios* sIGpios;
- static audio::TrackQueue* sQueue;
-
- static std::shared_ptr<drivers::TouchWheel> sTouchWheel;
- static std::shared_ptr<drivers::RelativeWheel> sRelativeWheel;
- static std::shared_ptr<drivers::Display> sDisplay;
- static std::shared_ptr<battery::Battery> sBattery;
- static std::shared_ptr<drivers::NvsStorage> sNvs;
- static std::weak_ptr<database::Database> sDb;
+ static std::unique_ptr<UiTask> sTask;
+ static std::shared_ptr<system_fsm::ServiceLocator> sServices;
+ static std::unique_ptr<drivers::Display> sDisplay;
+ static std::shared_ptr<TouchWheelEncoder> sEncoder;
static std::stack<std::shared_ptr<Screen>> sScreens;
static std::shared_ptr<Screen> sCurrentScreen;
@@ -97,6 +93,7 @@ class Splash : public UiState {
public:
void exit() override;
void react(const system_fsm::BootComplete&) override;
+ void react(const system_fsm::BatteryStateChanged&) override{};
using UiState::react;
};
diff --git a/src/ui/include/wheel_encoder.hpp b/src/ui/include/wheel_encoder.hpp
index c49e5929..fcac5edd 100644
--- a/src/ui/include/wheel_encoder.hpp
+++ b/src/ui/include/wheel_encoder.hpp
@@ -17,7 +17,7 @@ namespace ui {
class TouchWheelEncoder {
public:
- explicit TouchWheelEncoder(std::weak_ptr<drivers::RelativeWheel> wheel);
+ explicit TouchWheelEncoder(std::unique_ptr<drivers::RelativeWheel> wheel);
auto Read(lv_indev_data_t* data) -> void;
auto registration() -> lv_indev_t* { return registration_; }
@@ -27,7 +27,7 @@ class TouchWheelEncoder {
lv_indev_t* registration_;
lv_key_t last_key_;
- std::weak_ptr<drivers::RelativeWheel> wheel_;
+ std::unique_ptr<drivers::RelativeWheel> wheel_;
};
} // namespace ui
diff --git a/src/ui/lvgl_task.cpp b/src/ui/lvgl_task.cpp
index 9952d0bb..a0f14f7d 100644
--- a/src/ui/lvgl_task.cpp
+++ b/src/ui/lvgl_task.cpp
@@ -48,67 +48,74 @@
namespace ui {
-static const char* kTag = "lv_task";
+static const char* kTag = "ui_task";
static const TickType_t kMaxFrameRate = pdMS_TO_TICKS(100);
-static int sTimerId;
-static SemaphoreHandle_t sFrameSemaphore;
-
-auto next_frame(TimerHandle_t) {
- xSemaphoreGive(sFrameSemaphore);
+static auto next_frame(TimerHandle_t t) {
+ SemaphoreHandle_t sem =
+ reinterpret_cast<SemaphoreHandle_t>(pvTimerGetTimerID(t));
+ xSemaphoreGive(sem);
}
-void LvglMain(std::weak_ptr<drivers::RelativeWheel> weak_touch_wheel,
- std::weak_ptr<drivers::Display> weak_display) {
- ESP_LOGI(kTag, "init lvgl");
- lv_init();
-
- sFrameSemaphore = xSemaphoreCreateBinary();
- auto timer =
- xTimerCreate("lvgl_frame", kMaxFrameRate, pdTRUE, &sTimerId, next_frame);
- xTimerStart(timer, portMAX_DELAY);
-
- lv_theme_t* base_theme = lv_theme_basic_init(NULL);
- lv_disp_set_theme(NULL, base_theme);
- themes::Theme::instance()->Apply();
+UiTask::UiTask()
+ : quit_(false),
+ frame_semaphore_(xSemaphoreCreateBinary()),
+ frame_timer_(xTimerCreate("ui_frame",
+ kMaxFrameRate,
+ pdTRUE,
+ frame_semaphore_,
+ next_frame)) {
+ xTimerStart(frame_timer_, portMAX_DELAY);
+}
- TouchWheelEncoder encoder(weak_touch_wheel);
+UiTask::~UiTask() {
+ assert(false);
+}
- std::shared_ptr<Screen> current_screen;
+auto UiTask::Main() -> void {
+ ESP_LOGI(kTag, "start ui task");
lv_group_t* current_group = nullptr;
auto* events = events::queues::Ui();
- while (1) {
+ while (true) {
while (events->Service(0)) {
}
std::shared_ptr<Screen> screen = UiState::current_screen();
- if (screen != current_screen && screen != nullptr) {
- // TODO(jacqueline): animate this sometimes
+ if (screen != current_screen_ && screen != nullptr) {
lv_scr_load(screen->root());
- lv_indev_set_group(encoder.registration(), screen->group());
- current_screen = screen;
+ if (input_device_) {
+ lv_indev_set_group(input_device_->registration(), screen->group());
+ }
+ current_screen_ = screen;
}
- if (current_screen->group() != current_group) {
- current_group = current_screen->group();
- lv_indev_set_group(encoder.registration(), current_group);
+ if (input_device_ && current_screen_->group() != current_group) {
+ current_group = current_screen_->group();
+ lv_indev_set_group(input_device_->registration(), current_group);
}
- if (current_screen) {
- current_screen->Tick();
+ if (current_screen_) {
+ current_screen_->Tick();
}
lv_task_handler();
// Wait for the signal to loop again.
- xSemaphoreTake(sFrameSemaphore, portMAX_DELAY);
+ xSemaphoreTake(frame_semaphore_, portMAX_DELAY);
+ }
+}
+
+auto UiTask::SetInputDevice(std::shared_ptr<TouchWheelEncoder> dev) -> void {
+ input_device_ = std::move(dev);
+ if (current_screen_ && input_device_) {
+ lv_indev_set_group(input_device_->registration(), current_screen_->group());
}
}
-auto StartLvgl(std::weak_ptr<drivers::RelativeWheel> touch_wheel,
- std::weak_ptr<drivers::Display> display) -> void {
- tasks::StartPersistent<tasks::Type::kUi>(
- 0, [=]() { LvglMain(touch_wheel, display); });
+auto UiTask::Start() -> UiTask* {
+ UiTask* ret = new UiTask();
+ tasks::StartPersistent<tasks::Type::kUi>(0, [=]() { ret->Main(); });
+ return ret;
}
} // namespace ui
diff --git a/src/ui/screen_playing.cpp b/src/ui/screen_playing.cpp
index 7538d093..2eb4e09e 100644
--- a/src/ui/screen_playing.cpp
+++ b/src/ui/screen_playing.cpp
@@ -104,7 +104,7 @@ auto Playing::next_up_label(lv_obj_t* parent, const std::string& text)
return button;
}
-Playing::Playing(std::weak_ptr<database::Database> db, audio::TrackQueue* queue)
+Playing::Playing(std::weak_ptr<database::Database> db, audio::TrackQueue& queue)
: db_(db),
queue_(queue),
track_(),
@@ -204,7 +204,7 @@ Playing::Playing(std::weak_ptr<database::Database> db, audio::TrackQueue* queue)
Playing::~Playing() {}
auto Playing::OnTrackUpdate() -> void {
- auto current = queue_->GetCurrent();
+ auto current = queue_.GetCurrent();
if (!current) {
return;
}
@@ -230,7 +230,7 @@ auto Playing::OnPlaybackUpdate(uint32_t pos_seconds, uint32_t new_duration)
auto Playing::OnQueueUpdate() -> void {
OnTrackUpdate();
- auto current = queue_->GetUpcoming(kMaxUpcoming);
+ auto current = queue_.GetUpcoming(kMaxUpcoming);
auto db = db_.lock();
if (!db) {
return;
diff --git a/src/ui/screen_settings.cpp b/src/ui/screen_settings.cpp
index 6bafb9a8..01f40cb5 100644
--- a/src/ui/screen_settings.cpp
+++ b/src/ui/screen_settings.cpp
@@ -161,7 +161,7 @@ static auto brightness_str(uint_fast8_t percent) -> std::string {
return std::to_string(percent) + "%";
}
-Appearance::Appearance(drivers::NvsStorage* nvs, drivers::Display* display)
+Appearance::Appearance(drivers::NvsStorage& nvs, drivers::Display& display)
: MenuScreen("Appearance"), nvs_(nvs), display_(display) {
lv_obj_t* toggle_container = settings_container(content_);
lv_obj_t* toggle_label = lv_label_create(toggle_container);
@@ -170,7 +170,7 @@ Appearance::Appearance(drivers::NvsStorage* nvs, drivers::Display* display)
lv_obj_t* toggle = lv_switch_create(toggle_container);
lv_group_add_obj(group_, toggle);
- uint_fast8_t initial_brightness = nvs_->ScreenBrightness().get();
+ uint_fast8_t initial_brightness = nvs_.ScreenBrightness().get();
lv_obj_t* brightness_label = lv_label_create(content_);
lv_label_set_text(brightness_label, "Brightness");
@@ -192,13 +192,13 @@ Appearance::Appearance(drivers::NvsStorage* nvs, drivers::Display* display)
auto Appearance::ChangeBrightness(uint_fast8_t new_level) -> void {
current_brightness_ = new_level;
- display_->SetBrightness(new_level);
+ display_.SetBrightness(new_level);
lv_label_set_text(current_brightness_label_,
brightness_str(new_level).c_str());
}
auto Appearance::CommitBrightness() -> void {
- nvs_->ScreenBrightness(current_brightness_);
+ nvs_.ScreenBrightness(current_brightness_);
}
InputMethod::InputMethod() : MenuScreen("Input Method") {
diff --git a/src/ui/ui_fsm.cpp b/src/ui/ui_fsm.cpp
index 1febd1c7..0054db23 100644
--- a/src/ui/ui_fsm.cpp
+++ b/src/ui/ui_fsm.cpp
@@ -32,6 +32,7 @@
#include "touchwheel.hpp"
#include "track_queue.hpp"
#include "ui_events.hpp"
+#include "wheel_encoder.hpp"
#include "widget_top_bar.hpp"
namespace ui {
@@ -40,51 +41,25 @@ static constexpr char kTag[] = "ui_fsm";
static const std::size_t kRecordsPerPage = 15;
-drivers::IGpios* UiState::sIGpios;
-audio::TrackQueue* UiState::sQueue;
-
-std::shared_ptr<drivers::TouchWheel> UiState::sTouchWheel;
-std::shared_ptr<drivers::RelativeWheel> UiState::sRelativeWheel;
-std::shared_ptr<drivers::Display> UiState::sDisplay;
-std::shared_ptr<battery::Battery> UiState::sBattery;
-std::shared_ptr<drivers::NvsStorage> UiState::sNvs;
-std::weak_ptr<database::Database> UiState::sDb;
+std::unique_ptr<UiTask> UiState::sTask;
+std::shared_ptr<system_fsm::ServiceLocator> UiState::sServices;
+std::unique_ptr<drivers::Display> UiState::sDisplay;
+std::shared_ptr<TouchWheelEncoder> UiState::sEncoder;
std::stack<std::shared_ptr<Screen>> UiState::sScreens;
std::shared_ptr<Screen> UiState::sCurrentScreen;
std::shared_ptr<Modal> UiState::sCurrentModal;
-auto UiState::Init(drivers::IGpios* gpio_expander,
- std::shared_ptr<drivers::NvsStorage> nvs,
- audio::TrackQueue* queue,
- std::shared_ptr<battery::Battery> battery) -> bool {
- sIGpios = gpio_expander;
- sNvs = nvs;
- sQueue = queue;
- sBattery = battery;
-
+auto UiState::InitBootSplash(drivers::IGpios& gpios) -> bool {
+ // Init LVGL first, since the display driver registers itself with LVGL.
lv_init();
- sDisplay.reset(
- drivers::Display::Create(gpio_expander, drivers::displays::kST7735R));
+ sDisplay.reset(drivers::Display::Create(gpios, drivers::displays::kST7735R));
if (sDisplay == nullptr) {
return false;
}
- sDisplay->SetBrightness(nvs->ScreenBrightness().get());
-
- sTouchWheel.reset(drivers::TouchWheel::Create());
- if (sTouchWheel != nullptr) {
- sRelativeWheel.reset(new drivers::RelativeWheel(sTouchWheel.get()));
- }
sCurrentScreen.reset(new screens::Splash());
-
- // Start the UI task even if init ultimately failed, so that we can show some
- // kind of error screen to the user.
- StartLvgl(sRelativeWheel, sDisplay);
-
- if (sTouchWheel == nullptr) {
- return false;
- }
+ sTask.reset(UiTask::Start());
return true;
}
@@ -107,7 +82,8 @@ void UiState::PopScreen() {
void UiState::react(const system_fsm::KeyLockChanged& ev) {
sDisplay->SetDisplayOn(ev.falling);
- sRelativeWheel->SetEnabled(ev.falling);
+ sTask->SetInputDevice(ev.falling ? sEncoder
+ : std::shared_ptr<TouchWheelEncoder>());
}
void UiState::react(const system_fsm::BatteryStateChanged&) {
@@ -115,8 +91,8 @@ void UiState::react(const system_fsm::BatteryStateChanged&) {
}
void UiState::UpdateTopBar() {
- auto battery_state = sBattery->State();
- bool has_queue = sQueue->GetCurrent().has_value();
+ auto battery_state = sServices->battery().State();
+ bool has_queue = sServices->track_queue().GetCurrent().has_value();
bool is_playing = audio::AudioState::is_in_state<audio::states::Playback>();
widgets::TopBar::State state{
@@ -140,19 +116,40 @@ namespace states {
void Splash::exit() {
if (sDisplay != nullptr) {
- sDisplay->SetDisplayOn(sIGpios->Get(drivers::IGpios::Pin::kKeyLock));
+ sDisplay->SetDisplayOn(
+ sServices->gpios().Get(drivers::IGpios::Pin::kKeyLock));
}
}
void Splash::react(const system_fsm::BootComplete& ev) {
+ sServices = ev.services;
+
+ // The system has finished booting! We now need to prepare to show real UI.
+ // This basically just involves reading and applying the user's preferences.
+
+ lv_theme_t* base_theme = lv_theme_basic_init(NULL);
+ lv_disp_set_theme(NULL, base_theme);
+ themes::Theme::instance()->Apply();
+
+ sDisplay->SetBrightness(sServices->nvs().ScreenBrightness().get());
+
+ auto touchwheel = sServices->touchwheel();
+ if (touchwheel) {
+ auto relative_wheel =
+ std::make_unique<drivers::RelativeWheel>(**touchwheel);
+ sEncoder = std::make_shared<TouchWheelEncoder>(std::move(relative_wheel));
+ sTask->SetInputDevice(sEncoder);
+ } else {
+ ESP_LOGE(kTag, "no input devices initialised!");
+ }
+
transit<Browse>();
}
void Browse::entry() {}
void Browse::react(const system_fsm::StorageMounted& ev) {
- sDb = ev.db;
- auto db = ev.db.lock();
+ auto db = sServices->database().lock();
if (!db) {
// TODO(jacqueline): Hmm.
return;
@@ -177,7 +174,7 @@ void Browse::react(const internal::ShowSettingsPage& ev) {
screen.reset(new screens::Headphones());
break;
case internal::ShowSettingsPage::Page::kAppearance:
- screen.reset(new screens::Appearance(sNvs.get(), sDisplay.get()));
+ screen.reset(new screens::Appearance(sServices->nvs(), *sDisplay));
break;
case internal::ShowSettingsPage::Page::kInput:
screen.reset(new screens::InputMethod());
@@ -198,7 +195,7 @@ void Browse::react(const internal::ShowSettingsPage& ev) {
}
void Browse::react(const internal::RecordSelected& ev) {
- auto db = sDb.lock();
+ auto db = sServices->database().lock();
if (!db) {
return;
}
@@ -206,9 +203,10 @@ void Browse::react(const internal::RecordSelected& ev) {
auto record = ev.page->values().at(ev.record);
if (record.track()) {
ESP_LOGI(kTag, "selected track '%s'", record.text()->c_str());
- sQueue->Clear();
- sQueue->IncludeLast(std::make_shared<playlist::IndexRecordSource>(
- sDb, ev.initial_page, 0, ev.page, ev.record));
+ auto& queue = sServices->track_queue();
+ queue.Clear();
+ queue.IncludeLast(std::make_shared<playlist::IndexRecordSource>(
+ sServices->database(), ev.initial_page, 0, ev.page, ev.record));
transit<Playing>();
} else {
ESP_LOGI(kTag, "selected record '%s'", record.text()->c_str());
@@ -218,21 +216,21 @@ void Browse::react(const internal::RecordSelected& ev) {
}
auto query = db->GetPage(&cont.value());
std::string title = record.text().value_or("TODO");
- PushScreen(
- std::make_shared<screens::TrackBrowser>(sDb, title, std::move(query)));
+ PushScreen(std::make_shared<screens::TrackBrowser>(
+ sServices->database(), title, std::move(query)));
}
}
void Browse::react(const internal::IndexSelected& ev) {
- auto db = sDb.lock();
+ auto db = sServices->database().lock();
if (!db) {
return;
}
ESP_LOGI(kTag, "selected index %s", ev.index.name.c_str());
auto query = db->GetTracksByIndex(ev.index, kRecordsPerPage);
- PushScreen(std::make_shared<screens::TrackBrowser>(sDb, ev.index.name,
- std::move(query)));
+ PushScreen(std::make_shared<screens::TrackBrowser>(
+ sServices->database(), ev.index.name, std::move(query)));
}
void Browse::react(const internal::BackPressed& ev) {
@@ -242,7 +240,8 @@ void Browse::react(const internal::BackPressed& ev) {
static std::shared_ptr<screens::Playing> sPlayingScreen;
void Playing::entry() {
- sPlayingScreen.reset(new screens::Playing(sDb, sQueue));
+ sPlayingScreen.reset(
+ new screens::Playing(sServices->database(), sServices->track_queue()));
PushScreen(sPlayingScreen);
}
diff --git a/src/ui/wheel_encoder.cpp b/src/ui/wheel_encoder.cpp
index a0e12b7f..2f2e7f68 100644
--- a/src/ui/wheel_encoder.cpp
+++ b/src/ui/wheel_encoder.cpp
@@ -22,8 +22,8 @@ void encoder_feedback(lv_indev_drv_t* drv, uint8_t event_code) {
}
TouchWheelEncoder::TouchWheelEncoder(
- std::weak_ptr<drivers::RelativeWheel> wheel)
- : last_key_(0), wheel_(wheel) {
+ std::unique_ptr<drivers::RelativeWheel> wheel)
+ : last_key_(0), wheel_(std::move(wheel)) {
lv_indev_drv_init(&driver_);
driver_.type = LV_INDEV_TYPE_ENCODER;
driver_.read_cb = encoder_read;
@@ -34,16 +34,11 @@ TouchWheelEncoder::TouchWheelEncoder(
}
auto TouchWheelEncoder::Read(lv_indev_data_t* data) -> void {
- auto lock = wheel_.lock();
- if (lock == nullptr) {
- return;
- }
+ wheel_->Update();
- lock->Update();
-
- data->enc_diff = lock->ticks();
+ data->enc_diff = wheel_->ticks();
data->state =
- lock->is_clicking() ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
+ wheel_->is_clicking() ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
}
} // namespace ui