Various services improved (#110)

This commit is contained in:
Ken Van Hoeylandt
2024-12-06 23:16:29 +01:00
committed by GitHub
parent 36bb25deba
commit d52fe52d96
32 changed files with 771 additions and 636 deletions
+7 -1
View File
@@ -1,3 +1,4 @@
#include <Dispatcher.h>
#include "Tactility.h"
#include "app/ManifestRegistry.h"
@@ -127,7 +128,7 @@ static void register_and_start_user_services(const service::ServiceManifest* con
}
}
void init(const Configuration& config) {
void run(const Configuration& config) {
TT_LOG_I(TAG, "init started");
tt_assert(config.hardware);
@@ -160,6 +161,11 @@ void init(const Configuration& config) {
}
TT_LOG_I(TAG, "init complete");
TT_LOG_I(TAG, "Processing main dispatcher");
while (true) {
getMainDispatcher().consume(TtWaitForever);
}
}
const Configuration* _Nullable getConfiguration() {
+1 -1
View File
@@ -19,7 +19,7 @@ typedef struct {
* Attempts to initialize Tactility and all configured hardware.
* @param config
*/
void init(const Configuration& config);
void run(const Configuration& config);
/**
* While technically nullable, this instance is always set if tt_init() succeeds.
+1 -1
View File
@@ -13,7 +13,7 @@ namespace tt::app::power {
#define TAG "power"
extern const AppManifest manifest;
static void on_timer(TT_UNUSED void* context);
static void on_timer(TT_UNUSED std::shared_ptr<void> context);
struct Data {
std::unique_ptr<Timer> update_timer = std::unique_ptr<Timer>(new Timer(Timer::TypePeriodic, &on_timer, nullptr));
@@ -54,7 +54,7 @@ static void onConnect(const service::wifi::settings::WifiApSettings* ap_settings
}
WifiConnect::WifiConnect() {
PubSub* wifi_pubsub = service::wifi::getPubsub();
auto wifi_pubsub = service::wifi::getPubsub();
wifiSubscription = tt_pubsub_subscribe(wifi_pubsub, &eventCallback, this);
bindings = (Bindings) {
.onConnectSsid = onConnect,
@@ -63,7 +63,7 @@ WifiConnect::WifiConnect() {
}
WifiConnect::~WifiConnect() {
PubSub* pubsub = service::wifi::getPubsub();
auto pubsub = service::wifi::getPubsub();
tt_pubsub_unsubscribe(pubsub, wifiSubscription);
}
@@ -108,7 +108,7 @@ static void wifiManageEventCallback(const void* message, void* context) {
}
void WifiManage::onShow(AppContext& app, lv_obj_t* parent) {
PubSub* wifi_pubsub = service::wifi::getPubsub();
auto wifi_pubsub = service::wifi::getPubsub();
wifiSubscription = tt_pubsub_subscribe(wifi_pubsub, &wifiManageEventCallback, this);
// State update (it has its own locking)
@@ -128,6 +128,7 @@ void WifiManage::onShow(AppContext& app, lv_obj_t* parent) {
bool can_scan = radio_state == service::wifi::WIFI_RADIO_ON ||
radio_state == service::wifi::WIFI_RADIO_CONNECTION_PENDING ||
radio_state == service::wifi::WIFI_RADIO_CONNECTION_ACTIVE;
TT_LOG_I(TAG, "%d %d", radio_state, service::wifi::isScanning());
if (can_scan && !service::wifi::isScanning()) {
service::wifi::scan();
}
@@ -135,7 +136,7 @@ void WifiManage::onShow(AppContext& app, lv_obj_t* parent) {
void WifiManage::onHide(TT_UNUSED AppContext& app) {
lock();
PubSub* wifi_pubsub = service::wifi::getPubsub();
auto wifi_pubsub = service::wifi::getPubsub();
tt_pubsub_unsubscribe(wifi_pubsub, wifiSubscription);
wifiSubscription = nullptr;
isViewEnabled = false;
+2 -2
View File
@@ -22,7 +22,7 @@ typedef struct {
typedef struct {
Mutex* mutex;
PubSub* pubsub;
std::shared_ptr<PubSub> pubsub;
StatusbarIcon icons[STATUSBAR_ICON_LIMIT];
} StatusbarData;
@@ -40,7 +40,7 @@ typedef struct {
static void statusbar_init() {
statusbar_data.mutex = tt_mutex_alloc(MutexTypeRecursive);
statusbar_data.pubsub = tt_pubsub_alloc();
statusbar_data.pubsub = std::make_shared<PubSub>();
for (int i = 0; i < STATUSBAR_ICON_LIMIT; i++) {
statusbar_data.icons[i].image = nullptr;
statusbar_data.icons[i].visible = false;
+3 -11
View File
@@ -29,38 +29,30 @@ static Loader* loader_singleton = nullptr;
static Loader* loader_alloc() {
assert(loader_singleton == nullptr);
loader_singleton = new Loader();
loader_singleton->pubsub_internal = tt_pubsub_alloc();
loader_singleton->pubsub_external = tt_pubsub_alloc();
loader_singleton->thread = new Thread(
"loader",
4096, // Last known minimum was 2400 for starting Hello World app
&loader_main,
nullptr
);
loader_singleton->mutex = tt_mutex_alloc(MutexTypeRecursive);
return loader_singleton;
}
static void loader_free() {
tt_assert(loader_singleton != nullptr);
delete loader_singleton->thread;
tt_pubsub_free(loader_singleton->pubsub_internal);
tt_pubsub_free(loader_singleton->pubsub_external);
tt_mutex_free(loader_singleton->mutex);
delete loader_singleton;
loader_singleton = nullptr;
}
static void loader_lock() {
tt_assert(loader_singleton);
tt_assert(loader_singleton->mutex);
tt_check(tt_mutex_acquire(loader_singleton->mutex, TtWaitForever) == TtStatusOk);
tt_check(loader_singleton->mutex.acquire(TtWaitForever) == TtStatusOk);
}
static void loader_unlock() {
tt_assert(loader_singleton);
tt_assert(loader_singleton->mutex);
tt_check(tt_mutex_release(loader_singleton->mutex) == TtStatusOk);
tt_check(loader_singleton->mutex.release() == TtStatusOk);
}
LoaderStatus startApp(const std::string& id, bool blocking, std::shared_ptr<const Bundle> parameters) {
@@ -107,7 +99,7 @@ app::AppContext* _Nullable getCurrentApp() {
return dynamic_cast<app::AppContext*>(app);
}
PubSub* getPubsub() {
std::shared_ptr<PubSub> getPubsub() {
tt_assert(loader_singleton);
// it's safe to return pubsub without locking
// because it's never freed and loader is never exited
+1 -1
View File
@@ -37,6 +37,6 @@ app::AppContext* _Nullable getCurrentApp();
/**
* @brief PubSub for LoaderEvent
*/
PubSub* getPubsub();
std::shared_ptr<PubSub> getPubsub();
} // namespace
@@ -1,11 +1,13 @@
#include "Assets.h"
#include "Mutex.h"
#include "Timer.h"
#include "Tactility.h"
#include "hal/Power.h"
#include "hal/sdcard/Sdcard.h"
#include "Mutex.h"
#include "lvgl/Statusbar.h"
#include "service/ServiceContext.h"
#include "service/wifi/Wifi.h"
#include "Tactility.h"
#include "lvgl/Statusbar.h"
#include "service/ServiceRegistry.h"
namespace tt::service::statusbar {
@@ -16,8 +18,7 @@ extern const ServiceManifest manifest;
struct ServiceData {
Mutex mutex;
Thread thread;
bool service_interrupted = false;
std::unique_ptr<Timer> updateTimer;
int8_t wifi_icon_id = lvgl::statusbar_icon_add(nullptr);
const char* wifi_last_icon = nullptr;
int8_t sdcard_icon_id = lvgl::statusbar_icon_add(nullptr);
@@ -153,51 +154,35 @@ static void service_data_free(ServiceData* data) {
free(data);
}
int32_t serviceMain(TT_UNUSED void* parameter) {
TT_LOG_I(TAG, "Started main loop");
delay_ms(20); // TODO: Make service instance findable earlier on (but expose "starting" state?)
auto context = tt::service::findServiceById(manifest.id);
if (context == nullptr) {
TT_LOG_E(TAG, "Service not found");
return -1;
}
auto data = std::static_pointer_cast<ServiceData>(context->getData());
while (!data->service_interrupted) {
update_wifi_icon(data);
update_sdcard_icon(data);
update_power_icon(data);
delay_ms(1000);
}
return 0;
static void onUpdate(std::shared_ptr<void> parameter) {
auto data = std::static_pointer_cast<ServiceData>(parameter);
// TODO: Make thread-safe for LVGL
update_wifi_icon(data);
update_sdcard_icon(data);
update_power_icon(data);
}
static void onStart(ServiceContext& service) {
auto data = std::make_shared<ServiceData>();
service.setData(data);
// TODO: Make thread-safe for LVGL
lvgl::statusbar_icon_set_visibility(data->wifi_icon_id, true);
update_wifi_icon(data);
update_sdcard_icon(data); // also updates visibility
update_power_icon(data);
data->thread.setCallback(serviceMain, nullptr);
data->thread.setPriority(Thread::PriorityLow);
data->thread.setStackSize(3000);
data->thread.setName("statusbar");
data->thread.start();
data->updateTimer = std::make_unique<Timer>(Timer::TypePeriodic, onUpdate, data);
// We want to try and scan more often in case of startup or scan lock failure
data->updateTimer->start(1000);
}
static void onStop(ServiceContext& service) {
auto data = std::static_pointer_cast<ServiceData>(service.getData());
// Stop thread
data->lock();
data->service_interrupted = true;
data->unlock();
data->thread.join();
data->updateTimer->stop();
data->updateTimer = nullptr;
}
extern const ServiceManifest manifest = {