diff --git a/Boards/LilygoTdeck/Source/Init.cpp b/Boards/LilygoTdeck/Source/Init.cpp index 45f531a7..c8c4b6df 100644 --- a/Boards/LilygoTdeck/Source/Init.cpp +++ b/Boards/LilygoTdeck/Source/Init.cpp @@ -45,17 +45,13 @@ bool tdeckInit() { return false; } - tt::kernel::systemEventAddListener(tt::kernel::SystemEvent::BootSplash, [](tt::kernel::SystemEvent event){ + tt::kernel::subscribeSystemEvent(tt::kernel::SystemEvent::BootSplash, [](tt::kernel::SystemEvent event) { auto gps_service = tt::service::gps::findGpsService(); if (gps_service != nullptr) { std::vector gps_configurations; gps_service->getGpsConfigurations(gps_configurations); if (gps_configurations.empty()) { - if (gps_service->addGpsConfiguration(tt::hal::gps::GpsConfiguration { - .uartName = "Grove", - .baudRate = 38400, - .model = tt::hal::gps::GpsModel::UBLOX10 - })) { + if (gps_service->addGpsConfiguration(tt::hal::gps::GpsConfiguration {.uartName = "Grove", .baudRate = 38400, .model = tt::hal::gps::GpsModel::UBLOX10})) { TT_LOG_I(TAG, "Configured internal GPS"); } else { TT_LOG_E(TAG, "Failed to configure internal GPS"); diff --git a/Documentation/ideas.md b/Documentation/ideas.md index f6be4a6e..a48f5bde 100644 --- a/Documentation/ideas.md +++ b/Documentation/ideas.md @@ -1,5 +1,4 @@ # TODOs -- rename kernel::systemEventAddListener() etc to subscribe/unsubscribe - Split up boot stages, so the last stage can be done from the splash screen - Start using non_null (either via MS GSL, or custom) - `hal/Configuration.h` defines C function types: Use C++ std::function instead diff --git a/Tactility/Include/Tactility/app/serialconsole/ConsoleView.h b/Tactility/Include/Tactility/app/serialconsole/ConsoleView.h index 9e4cc45f..df6dee2a 100644 --- a/Tactility/Include/Tactility/app/serialconsole/ConsoleView.h +++ b/Tactility/Include/Tactility/app/serialconsole/ConsoleView.h @@ -113,16 +113,6 @@ private: return 0; } - static int32_t viewThreadMainStatic(void* parameter) { - auto* view = (ConsoleView*)parameter; - return view->viewThreadMain(); - } - - static int32_t uartThreadMainStatic(void* parameter) { - auto* view = (ConsoleView*)parameter; - return view->uartThreadMain(); - } - static void onSendClickedCallback(lv_event_t* event) { auto* view = (ConsoleView*)lv_event_get_user_data(event); view->onSendClicked(); @@ -177,8 +167,9 @@ public: uartThread = std::make_unique( "SerConsUart", 4096, - uartThreadMainStatic, - this + [this]() { + return this->uartThreadMain(); + } ); uartThread->setPriority(tt::Thread::Priority::High); uartThread->start(); @@ -226,8 +217,9 @@ public: viewThread = std::make_unique( "SerConsView", 4096, - viewThreadMainStatic, - this + [this]() { + return this->viewThreadMain(); + } ); viewThread->setPriority(THREAD_PRIORITY_RENDER); viewThread->start(); diff --git a/Tactility/Include/Tactility/hal/gps/GpsDevice.h b/Tactility/Include/Tactility/hal/gps/GpsDevice.h index 98e1ade3..86e9373b 100644 --- a/Tactility/Include/Tactility/hal/gps/GpsDevice.h +++ b/Tactility/Include/Tactility/hal/gps/GpsDevice.h @@ -57,7 +57,6 @@ private: GpsModel model = GpsModel::Unknown; State state = State::Off; - static int32_t threadMainStatic(void* parameter); int32_t threadMain(); bool isThreadInterrupted() const; diff --git a/Tactility/Include/Tactility/kernel/SystemEvents.h b/Tactility/Include/Tactility/kernel/SystemEvents.h index dda2ab5a..d186e4c2 100644 --- a/Tactility/Include/Tactility/kernel/SystemEvents.h +++ b/Tactility/Include/Tactility/kernel/SystemEvents.h @@ -29,10 +29,10 @@ typedef uint32_t SystemEventSubscription; typedef std::function OnSystemEvent; -void systemEventPublish(SystemEvent event); +void publishSystemEvent(SystemEvent event); -SystemEventSubscription systemEventAddListener(SystemEvent event, OnSystemEvent handler); +SystemEventSubscription subscribeSystemEvent(SystemEvent event, OnSystemEvent handler); -void systemEventRemoveListener(SystemEventSubscription subscription); +void unsubscribeSystemEvent(SystemEventSubscription subscription); } \ No newline at end of file diff --git a/Tactility/Private/Tactility/service/espnow/EspNowService.h b/Tactility/Private/Tactility/service/espnow/EspNowService.h index 7ee04e17..a93d2b0c 100644 --- a/Tactility/Private/Tactility/service/espnow/EspNowService.h +++ b/Tactility/Private/Tactility/service/espnow/EspNowService.h @@ -31,10 +31,8 @@ private: bool enabled = false; // Dispatcher calls this and forwards to non-static function - static void enableFromDispatcher(std::shared_ptr context); void enableFromDispatcher(const EspNowConfig& config); - static void disableFromDispatcher(std::shared_ptr context); void disableFromDispatcher(); static void receiveCallback(const esp_now_recv_info_t* receiveInfo, const uint8_t* data, int length); diff --git a/Tactility/Source/app/boot/Boot.cpp b/Tactility/Source/app/boot/Boot.cpp index 41cbd2ef..7946437e 100644 --- a/Tactility/Source/app/boot/Boot.cpp +++ b/Tactility/Source/app/boot/Boot.cpp @@ -37,7 +37,7 @@ private: static int32_t bootThreadCallback(TT_UNUSED void* context) { TickType_t start_time = kernel::getTicks(); - kernel::systemEventPublish(kernel::SystemEvent::BootSplash); + kernel::publishSystemEvent(kernel::SystemEvent::BootSplash); auto hal_display = getHalDisplay(); assert(hal_display != nullptr); diff --git a/Tactility/Source/app/gpio/Gpio.cpp b/Tactility/Source/app/gpio/Gpio.cpp index 7acbb549..c331babf 100644 --- a/Tactility/Source/app/gpio/Gpio.cpp +++ b/Tactility/Source/app/gpio/Gpio.cpp @@ -21,7 +21,7 @@ private: Mutex mutex; static lv_obj_t* createGpioRowWrapper(lv_obj_t* parent); - static void onTimer(TT_UNUSED std::shared_ptr context); + void onTimer(); public: @@ -49,9 +49,9 @@ void GpioApp::updatePinStates() { } void GpioApp::updatePinWidgets() { - auto scoped_lvgl_lock = lvgl::getSyncLock()->scoped(); + auto scoped_lvgl_lock = lvgl::getSyncLock()->asScopedLock(); auto scoped_gpio_lock = mutex.asScopedLock(); - if (scoped_gpio_lock.lock() && scoped_lvgl_lock->lock(100)) { + if (scoped_gpio_lock.lock() && scoped_lvgl_lock.lock(lvgl::defaultLockTime)) { for (int j = 0; j < GPIO_NUM_MAX; ++j) { int level = pinStates[j]; lv_obj_t* label = lvPins[j]; @@ -79,24 +79,17 @@ lv_obj_t* GpioApp::createGpioRowWrapper(lv_obj_t* parent) { // region Task -void GpioApp::onTimer(TT_UNUSED std::shared_ptr context) { - auto appContext = getCurrentAppContext(); - if (appContext->getManifest().id == manifest.id) { - auto app = std::static_pointer_cast(appContext->getApp()); - if (app != nullptr) { - app->updatePinStates(); - app->updatePinWidgets(); - } - } +void GpioApp::onTimer() { + updatePinStates(); + updatePinWidgets(); } void GpioApp::startTask() { mutex.lock(); assert(timer == nullptr); - timer = std::make_unique( - Timer::Type::Periodic, - &onTimer - ); + timer = std::make_unique(Timer::Type::Periodic, [this]() { + onTimer(); + }); timer->start(100 / portTICK_PERIOD_MS); mutex.unlock(); } diff --git a/Tactility/Source/app/gpssettings/GpsSettings.cpp b/Tactility/Source/app/gpssettings/GpsSettings.cpp index f53b5bd3..3c1f3e8d 100644 --- a/Tactility/Source/app/gpssettings/GpsSettings.cpp +++ b/Tactility/Source/app/gpssettings/GpsSettings.cpp @@ -39,12 +39,6 @@ private: PubSub::SubscriptionHandle serviceStateSubscription = nullptr; std::shared_ptr service; - static void onUpdateCallback(TT_UNUSED std::shared_ptr context) { - auto appPtr = std::static_pointer_cast(context); - auto app = *appPtr; - app->updateViews(); - } - static void onServiceStateChangedCallback(const void* data, void* context) { auto* app = (GpsSettingsApp*)context; app->onServiceStateChanged(); @@ -266,13 +260,13 @@ private: if (wants_on != is_on) { // start/stop are potentially blocking calls, so we use a dispatcher to not block the UI if (wants_on) { - getMainDispatcher().dispatch([](auto service) { - std::static_pointer_cast(service)->startReceiving(); - }, service); + getMainDispatcher().dispatch([this]() { + service->startReceiving(); + }); } else { - getMainDispatcher().dispatch([](auto service) { - std::static_pointer_cast(service)->stopReceiving(); - }, service); + getMainDispatcher().dispatch([this]() { + service->stopReceiving(); + }); } } } @@ -280,7 +274,9 @@ private: public: GpsSettingsApp() { - timer = std::make_unique(Timer::Type::Periodic, onUpdateCallback, appReference); + timer = std::make_unique(Timer::Type::Periodic, [this]() { + updateViews(); + }); service = service::gps::findGpsService(); } diff --git a/Tactility/Source/app/i2cscanner/I2cScanner.cpp b/Tactility/Source/app/i2cscanner/I2cScanner.cpp index 943b9282..f5f6a38e 100644 --- a/Tactility/Source/app/i2cscanner/I2cScanner.cpp +++ b/Tactility/Source/app/i2cscanner/I2cScanner.cpp @@ -45,7 +45,7 @@ private: static void onSelectBusCallback(lv_event_t* event); static void onPressScanCallback(lv_event_t* event); - static void onScanTimerCallback(std::shared_ptr context); + static void onScanTimerCallback(); void onSelectBus(lv_event_t* event); void onPressScan(lv_event_t* event); @@ -180,7 +180,7 @@ void I2cScannerApp::onPressScanCallback(lv_event_t* event) { } } -void I2cScannerApp::onScanTimerCallback(TT_UNUSED std::shared_ptr context) { +void I2cScannerApp::onScanTimerCallback() { auto app = optApp(); if (app != nullptr) { app->onScanTimer(); @@ -284,10 +284,9 @@ void I2cScannerApp::startScanning() { lv_obj_clean(scanListWidget); scanState = ScanStateScanning; - scanTimer = std::make_unique( - Timer::Type::Once, - onScanTimerCallback - ); + scanTimer = std::make_unique(Timer::Type::Once, [](){ + onScanTimerCallback(); + }); scanTimer->start(10); mutex.unlock(); } else { diff --git a/Tactility/Source/app/power/Power.cpp b/Tactility/Source/app/power/Power.cpp index b5d69663..d40933dd 100644 --- a/Tactility/Source/app/power/Power.cpp +++ b/Tactility/Source/app/power/Power.cpp @@ -33,7 +33,7 @@ class PowerApp : public App { private: - Timer update_timer = Timer(Timer::Type::Periodic, &onTimer, nullptr); + Timer update_timer = Timer(Timer::Type::Periodic, []() { onTimer(); }); std::shared_ptr power; @@ -44,7 +44,7 @@ private: lv_obj_t* chargeLevelLabel = nullptr; lv_obj_t* currentLabel = nullptr; - static void onTimer(TT_UNUSED std::shared_ptr context) { + static void onTimer() { auto app = optApp(); if (app != nullptr) { app->updateUi(); diff --git a/Tactility/Source/app/screenshot/Screenshot.cpp b/Tactility/Source/app/screenshot/Screenshot.cpp index e05407bb..226c2d69 100644 --- a/Tactility/Source/app/screenshot/Screenshot.cpp +++ b/Tactility/Source/app/screenshot/Screenshot.cpp @@ -72,15 +72,10 @@ static void onModeSetCallback(TT_UNUSED lv_event_t* event) { } } -static void onTimerCallback(TT_UNUSED std::shared_ptr context) { - auto app = optApp(); - if (app != nullptr) { - app->onTimerTick(); - } -} - ScreenshotApp::ScreenshotApp() { - updateTimer = std::make_unique(Timer::Type::Periodic, onTimerCallback, nullptr); + updateTimer = std::make_unique(Timer::Type::Periodic, [this]() { + onTimerTick(); + }); } ScreenshotApp::~ScreenshotApp() { @@ -90,8 +85,8 @@ ScreenshotApp::~ScreenshotApp() { } void ScreenshotApp::onTimerTick() { - auto lvgl_lock = lvgl::getSyncLock()->scoped(); - if (lvgl_lock->lock(50 / portTICK_PERIOD_MS)) { + auto lock = lvgl::getSyncLock()->asScopedLock(); + if (lock.lock(lvgl::defaultLockTime)) { updateScreenshotMode(); } } diff --git a/Tactility/Source/app/timezone/TimeZone.cpp b/Tactility/Source/app/timezone/TimeZone.cpp index efc19ce3..f95326f7 100644 --- a/Tactility/Source/app/timezone/TimeZone.cpp +++ b/Tactility/Source/app/timezone/TimeZone.cpp @@ -117,7 +117,7 @@ private: lv_obj_add_event_cb(btn, &onListItemSelectedCallback, LV_EVENT_SHORT_CLICKED, (void*)index); } - static void updateTimerCallback(std::shared_ptr context) { + static void updateTimerCallback() { auto appContext = getCurrentAppContext(); if (appContext != nullptr && appContext->getManifest().id == manifest.id) { auto app = std::static_pointer_cast(appContext->getApp()); @@ -231,7 +231,7 @@ public: } void onCreate(AppContext& app) override { - updateTimer = std::make_unique(Timer::Type::Once, updateTimerCallback, nullptr); + updateTimer = std::make_unique(Timer::Type::Once, []() { updateTimerCallback(); }); } }; diff --git a/Tactility/Source/app/wifimanage/View.cpp b/Tactility/Source/app/wifimanage/View.cpp index b4a1d39d..67d83e8e 100644 --- a/Tactility/Source/app/wifimanage/View.cpp +++ b/Tactility/Source/app/wifimanage/View.cpp @@ -69,7 +69,13 @@ static void connect(lv_event_t* event) { if (ssid != nullptr) { TT_LOG_I(TAG, "Clicked AP: %s", ssid); auto* bindings = (Bindings*)lv_event_get_user_data(event); - bindings->onConnectSsid(ssid); + + std::string connection_target = service::wifi::getConnectionTarget(); + if (connection_target == ssid) { + bindings->onDisconnect(); + } else { + bindings->onConnectSsid(ssid); + } } } diff --git a/Tactility/Source/hal/Hal.cpp b/Tactility/Source/hal/Hal.cpp index b3868b9d..3a7dee72 100644 --- a/Tactility/Source/hal/Hal.cpp +++ b/Tactility/Source/hal/Hal.cpp @@ -15,19 +15,19 @@ namespace tt::hal { void init(const Configuration& configuration) { - kernel::systemEventPublish(kernel::SystemEvent::BootInitHalBegin); + kernel::publishSystemEvent(kernel::SystemEvent::BootInitHalBegin); - kernel::systemEventPublish(kernel::SystemEvent::BootInitI2cBegin); + kernel::publishSystemEvent(kernel::SystemEvent::BootInitI2cBegin); tt_check(i2c::init(configuration.i2c), "I2C init failed"); - kernel::systemEventPublish(kernel::SystemEvent::BootInitI2cEnd); + kernel::publishSystemEvent(kernel::SystemEvent::BootInitI2cEnd); - kernel::systemEventPublish(kernel::SystemEvent::BootInitSpiBegin); + kernel::publishSystemEvent(kernel::SystemEvent::BootInitSpiBegin); tt_check(spi::init(configuration.spi), "SPI init failed"); - kernel::systemEventPublish(kernel::SystemEvent::BootInitSpiEnd); + kernel::publishSystemEvent(kernel::SystemEvent::BootInitSpiEnd); - kernel::systemEventPublish(kernel::SystemEvent::BootInitUartBegin); + kernel::publishSystemEvent(kernel::SystemEvent::BootInitUartBegin); tt_check(uart::init(configuration.uart), "UART init failed"); - kernel::systemEventPublish(kernel::SystemEvent::BootInitUartEnd); + kernel::publishSystemEvent(kernel::SystemEvent::BootInitUartEnd); if (configuration.initBoot != nullptr) { TT_LOG_I(TAG, "Init power"); @@ -47,7 +47,7 @@ void init(const Configuration& configuration) { hal::registerDevice(power); } - kernel::systemEventPublish(kernel::SystemEvent::BootInitHalEnd); + kernel::publishSystemEvent(kernel::SystemEvent::BootInitHalEnd); } } // namespace diff --git a/Tactility/Source/hal/gps/GpsDevice.cpp b/Tactility/Source/hal/gps/GpsDevice.cpp index d2159f8d..e6818cfc 100644 --- a/Tactility/Source/hal/gps/GpsDevice.cpp +++ b/Tactility/Source/hal/gps/GpsDevice.cpp @@ -10,11 +10,6 @@ namespace tt::hal::gps { constexpr uint32_t GPS_UART_BUFFER_SIZE = 256; constexpr const char* TAG = "GpsDevice"; -int32_t GpsDevice::threadMainStatic(void* parameter) { - auto* gps_device = (GpsDevice*)parameter; - return gps_device->threadMain(); -} - int32_t GpsDevice::threadMain() { uint8_t buffer[GPS_UART_BUFFER_SIZE]; @@ -125,8 +120,9 @@ bool GpsDevice::start() { thread = std::make_unique( "gps", 4096, - threadMainStatic, - this + [this]() { + return this->threadMain(); + } ); thread->setPriority(tt::Thread::Priority::High); thread->start(); diff --git a/Tactility/Source/kernel/SystemEvents.cpp b/Tactility/Source/kernel/SystemEvents.cpp index dd8d59fa..95d222d2 100644 --- a/Tactility/Source/kernel/SystemEvents.cpp +++ b/Tactility/Source/kernel/SystemEvents.cpp @@ -55,7 +55,7 @@ static const char* getEventName(SystemEvent event) { tt_crash(); // Missing case above } -void systemEventPublish(SystemEvent event) { +void publishSystemEvent(SystemEvent event) { TT_LOG_I(TAG, "%s", getEventName(event)); if (mutex.lock(portMAX_DELAY)) { @@ -69,7 +69,7 @@ void systemEventPublish(SystemEvent event) { } } -SystemEventSubscription systemEventAddListener(SystemEvent event, std::function handler) { +SystemEventSubscription subscribeSystemEvent(SystemEvent event, OnSystemEvent handler) { if (mutex.lock(portMAX_DELAY)) { auto id = ++subscriptionCounter; @@ -86,7 +86,7 @@ SystemEventSubscription systemEventAddListener(SystemEvent event, std::function< } } -void systemEventRemoveListener(SystemEventSubscription subscription) { +void unsubscribeSystemEvent(SystemEventSubscription subscription) { if (mutex.lock(portMAX_DELAY)) { std::erase_if(subscriptions, [subscription](auto& item) { return (item.id == subscription); diff --git a/Tactility/Source/lvgl/Init.cpp b/Tactility/Source/lvgl/Init.cpp index 39ffe624..2b181455 100644 --- a/Tactility/Source/lvgl/Init.cpp +++ b/Tactility/Source/lvgl/Init.cpp @@ -84,7 +84,7 @@ static bool initKeyboard(const std::shared_ptr& dis void init(const hal::Configuration& config) { TT_LOG_I(TAG, "Starting"); - kernel::systemEventPublish(kernel::SystemEvent::BootInitLvglBegin); + kernel::publishSystemEvent(kernel::SystemEvent::BootInitLvglBegin); #ifdef ESP_PLATFORM if (config.lvglInit == hal::LvglInit::Default && !initEspLvglPort()) { @@ -114,7 +114,7 @@ void init(const hal::Configuration& config) { TT_LOG_I(TAG, "Finished"); - kernel::systemEventPublish(kernel::SystemEvent::BootInitLvglEnd); + kernel::publishSystemEvent(kernel::SystemEvent::BootInitLvglEnd); } } // namespace diff --git a/Tactility/Source/lvgl/Statusbar.cpp b/Tactility/Source/lvgl/Statusbar.cpp index a9f28109..b485025f 100644 --- a/Tactility/Source/lvgl/Statusbar.cpp +++ b/Tactility/Source/lvgl/Statusbar.cpp @@ -18,7 +18,7 @@ namespace tt::lvgl { #define TAG "statusbar" -static void onUpdateTime(TT_UNUSED std::shared_ptr context); +static void onUpdateTime(); struct StatusbarIcon { std::string image; @@ -30,7 +30,7 @@ struct StatusbarData { Mutex mutex = Mutex(Mutex::Type::Recursive); std::shared_ptr pubsub = std::make_shared(); StatusbarIcon icons[STATUSBAR_ICON_LIMIT] = {}; - Timer* time_update_timer = new Timer(Timer::Type::Once, onUpdateTime, nullptr); + Timer* time_update_timer = new Timer(Timer::Type::Once, []() { onUpdateTime(); }); uint8_t time_hours = 0; uint8_t time_minutes = 0; bool time_set = false; @@ -70,7 +70,7 @@ static TickType_t getNextUpdateTime() { return pdMS_TO_TICKS(seconds_to_wait * 1000U); } -static void onUpdateTime(TT_UNUSED std::shared_ptr context) { +static void onUpdateTime() { time_t now = ::time(nullptr); struct tm* tm_struct = localtime(&now); @@ -137,7 +137,7 @@ static void statusbar_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj) if (!statusbar_data.time_update_timer->isRunning()) { statusbar_data.time_update_timer->start(50 / portTICK_PERIOD_MS); - statusbar_data.systemEventSubscription = kernel::systemEventAddListener( + statusbar_data.systemEventSubscription = kernel::subscribeSystemEvent( kernel::SystemEvent::Time, onNetworkConnected ); diff --git a/Tactility/Source/network/Ntp.cpp b/Tactility/Source/network/Ntp.cpp index 3ee252a7..4c6fb107 100644 --- a/Tactility/Source/network/Ntp.cpp +++ b/Tactility/Source/network/Ntp.cpp @@ -15,7 +15,7 @@ namespace tt::network::ntp { static void onTimeSynced(struct timeval* tv) { TT_LOG_I(TAG, "Time synced (%llu)", tv->tv_sec); - kernel::systemEventPublish(kernel::SystemEvent::Time); + kernel::publishSystemEvent(kernel::SystemEvent::Time); } void init() { diff --git a/Tactility/Source/service/espnow/EspNowService.cpp b/Tactility/Source/service/espnow/EspNowService.cpp index 7fc988b4..d643a5ef 100644 --- a/Tactility/Source/service/espnow/EspNowService.cpp +++ b/Tactility/Source/service/espnow/EspNowService.cpp @@ -38,20 +38,9 @@ void EspNowService::onStop(ServiceContext& service) { // region Enable void EspNowService::enable(const EspNowConfig& config) { - auto enable_context = std::make_shared(config); - getMainDispatcher().dispatch(enableFromDispatcher, enable_context); -} - -void EspNowService::enableFromDispatcher(std::shared_ptr context) { - auto service = findService(); - if (service == nullptr) { - TT_LOG_E(TAG, "Service not running"); - return; - } - - auto config = std::static_pointer_cast(context); - - service->enableFromDispatcher(*config); + getMainDispatcher().dispatch([this, config]() { + enableFromDispatcher(config); + }); } void EspNowService::enableFromDispatcher(const EspNowConfig& config) { @@ -101,17 +90,9 @@ void EspNowService::enableFromDispatcher(const EspNowConfig& config) { // region Disable void EspNowService::disable() { - getMainDispatcher().dispatch(disableFromDispatcher, nullptr); -} - -void EspNowService::disableFromDispatcher(TT_UNUSED std::shared_ptr context) { - auto service = findService(); - if (service == nullptr) { - TT_LOG_E(TAG, "Service not running"); - return; - } - - service->disableFromDispatcher(); + getMainDispatcher().dispatch([this]() { + disableFromDispatcher(); + }); } void EspNowService::disableFromDispatcher() { diff --git a/Tactility/Source/service/loader/Loader.cpp b/Tactility/Source/service/loader/Loader.cpp index 88421938..7d691628 100644 --- a/Tactility/Source/service/loader/Loader.cpp +++ b/Tactility/Source/service/loader/Loader.cpp @@ -1,6 +1,5 @@ #include "Tactility/app/AppManifest.h" #include "Tactility/app/ManifestRegistry.h" -#include "Tactility/service/gui/Gui.h" #include "Tactility/service/loader/Loader_i.h" #include @@ -54,9 +53,6 @@ private: */ std::unique_ptr dispatcherThread = std::make_unique("loader_dispatcher", 6144); // Files app requires ~5k - static void onStartAppMessageCallback(std::shared_ptr message); - static void onStopAppMessageCallback(std::shared_ptr message); - void onStartAppMessage(const std::string& id, std::shared_ptr parameters); void onStopAppMessage(const std::string& id); @@ -86,14 +82,6 @@ std::shared_ptr _Nullable optScreenshotService() { return service::findServiceById(manifest.id); } -void LoaderService::onStartAppMessageCallback(std::shared_ptr message) { - auto start_message = std::reinterpret_pointer_cast(message); - auto& id = start_message->id; - auto& parameters = start_message->parameters; - - optScreenshotService()->onStartAppMessage(id, parameters); -} - void LoaderService::onStartAppMessage(const std::string& id, std::shared_ptr parameters) { TT_LOG_I(TAG, "Start by id %s", id.c_str()); @@ -130,12 +118,6 @@ void LoaderService::onStartAppMessage(const std::string& id, std::shared_ptrpublish(&event_external); } -void LoaderService::onStopAppMessageCallback(std::shared_ptr message) { - TT_LOG_I(TAG, "OnStopAppMessageCallback"); - auto stop_message = std::reinterpret_pointer_cast(message); - optScreenshotService()->onStopAppMessage(stop_message->id); -} - void LoaderService::onStopAppMessage(const std::string& id) { auto lock = mutex.asScopedLock(); @@ -271,14 +253,17 @@ void LoaderService::transitionAppToState(const std::shared_ptr void LoaderService::startApp(const std::string& id, std::shared_ptr parameters) { auto message = std::make_shared(id, std::move(parameters)); - dispatcherThread->dispatch(onStartAppMessageCallback, message); + dispatcherThread->dispatch([this, id, parameters]() { + onStartAppMessage(id, parameters); + }); } void LoaderService::stopApp() { TT_LOG_I(TAG, "stopApp()"); auto id = getCurrentAppContext()->getManifest().id; - auto message = std::make_shared(id); - dispatcherThread->dispatch(onStopAppMessageCallback, message); + dispatcherThread->dispatch([this, id]() { + onStopAppMessage(id); + }); TT_LOG_I(TAG, "dispatched"); } diff --git a/Tactility/Source/service/sdcard/Sdcard.cpp b/Tactility/Source/service/sdcard/Sdcard.cpp index 80452316..c6412d6b 100644 --- a/Tactility/Source/service/sdcard/Sdcard.cpp +++ b/Tactility/Source/service/sdcard/Sdcard.cpp @@ -49,17 +49,14 @@ private: } } - static void onUpdate(std::shared_ptr context) { - auto service = std::static_pointer_cast(context); - service->update(); - } - public: void onStart(ServiceContext& serviceContext) final { if (hal::getConfiguration()->sdcard != nullptr) { - auto service = findServiceById(manifest.id); - updateTimer = std::make_unique(Timer::Type::Periodic, onUpdate, service); + auto service = findServiceById(manifest.id); + updateTimer = std::make_unique(Timer::Type::Periodic, [service]() { + service->update(); + }); // We want to try and scan more often in case of startup or scan lock failure updateTimer->start(1000); } else { diff --git a/Tactility/Source/service/statusbar/Statusbar.cpp b/Tactility/Source/service/statusbar/Statusbar.cpp index e06a049a..d7b1ae8f 100644 --- a/Tactility/Source/service/statusbar/Statusbar.cpp +++ b/Tactility/Source/service/statusbar/Statusbar.cpp @@ -223,8 +223,7 @@ private: updatePowerStatusIcon(); } - static void onUpdate(std::shared_ptr parameter) { - auto service = std::static_pointer_cast(parameter); + static void onUpdate(const std::shared_ptr& service) { service->update(); } @@ -242,11 +241,14 @@ public: // TODO: Make thread-safe for LVGL lvgl::statusbar_icon_set_visibility(wifi_icon_id, true); - auto service = findServiceById(manifest.id); + auto service = findServiceById(manifest.id); assert(service); onUpdate(service); - updateTimer = std::make_unique(Timer::Type::Periodic, onUpdate, service); + updateTimer = std::make_unique(Timer::Type::Periodic, [service]() { + onUpdate(service); + }); + // We want to try and scan more often in case of startup or scan lock failure updateTimer->start(1000); } diff --git a/Tactility/Source/service/wifi/WifiEsp.cpp b/Tactility/Source/service/wifi/WifiEsp.cpp index 40728b60..6b58ec64 100644 --- a/Tactility/Source/service/wifi/WifiEsp.cpp +++ b/Tactility/Source/service/wifi/WifiEsp.cpp @@ -25,12 +25,12 @@ namespace tt::service::wifi { class Wifi; static void scan_list_free_safely(std::shared_ptr wifi); // Methods for main thread dispatcher -static void dispatchAutoConnect(std::shared_ptr context); -static void dispatchEnable(std::shared_ptr context); -static void dispatchDisable(std::shared_ptr context); -static void dispatchScan(std::shared_ptr context); -static void dispatchConnect(std::shared_ptr context); -static void dispatchDisconnectButKeepActive(std::shared_ptr context); +static void dispatchAutoConnect(std::shared_ptr wifi); +static void dispatchEnable(std::shared_ptr wifi); +static void dispatchDisable(std::shared_ptr wifi); +static void dispatchScan(std::shared_ptr wifi); +static void dispatchConnect(std::shared_ptr wifi); +static void dispatchDisconnectButKeepActive(std::shared_ptr wifi); class Wifi { @@ -172,7 +172,7 @@ void scan() { return; } - getMainDispatcher().dispatch(dispatchScan, wifi); + getMainDispatcher().dispatch([wifi]() { dispatchScan(wifi); }); } bool isScanning() { @@ -202,10 +202,10 @@ void connect(const settings::WifiApSettings* ap, bool remember) { wifi->connection_target_remember = remember; if (wifi->getRadioState() == RadioState::Off) { - getMainDispatcher().dispatch(dispatchEnable, wifi); + getMainDispatcher().dispatch([wifi]() { dispatchEnable(wifi); }); } - getMainDispatcher().dispatch(dispatchConnect, wifi); + getMainDispatcher().dispatch([wifi]() { dispatchConnect(wifi); }); } void disconnect() { @@ -227,7 +227,7 @@ void disconnect() { }; // Manual disconnect (e.g. via app) should stop auto-connecting until a new connection is established wifi->pause_auto_connect = true; - getMainDispatcher().dispatch(dispatchDisconnectButKeepActive, wifi); + getMainDispatcher().dispatch([wifi]() { dispatchDisconnectButKeepActive(wifi); }); } void setScanRecords(uint16_t records) { @@ -291,10 +291,11 @@ void setEnabled(bool enabled) { } if (enabled) { - getMainDispatcher().dispatch(dispatchEnable, wifi); + getMainDispatcher().dispatch([wifi]() { dispatchEnable(wifi); }); } else { - getMainDispatcher().dispatch(dispatchDisable, wifi); + getMainDispatcher().dispatch([wifi]() { dispatchDisable(wifi); }); } + wifi->pause_auto_connect = false; wifi->last_scan_time = 0; } @@ -405,8 +406,7 @@ static bool copy_scan_list(std::shared_ptr wifi) { } } -static bool find_auto_connect_ap(std::shared_ptr context, settings::WifiApSettings& settings) { - auto wifi = std::static_pointer_cast(context); +static bool find_auto_connect_ap(std::shared_ptr wifi, settings::WifiApSettings& settings) { auto lock = wifi->dataMutex.asScopedLock(); if (lock.lock(10 / portTICK_PERIOD_MS)) { @@ -430,14 +430,16 @@ static bool find_auto_connect_ap(std::shared_ptr context, settings::WifiAp return false; } -static void dispatchAutoConnect(std::shared_ptr context) { +static void dispatchAutoConnect(std::shared_ptr wifi) { TT_LOG_I(TAG, "dispatchAutoConnect()"); - auto wifi = std::static_pointer_cast(context); settings::WifiApSettings settings; - if (find_auto_connect_ap(context, settings)) { + if (find_auto_connect_ap(wifi, settings)) { TT_LOG_I(TAG, "Auto-connecting to %s", settings.ssid); connect(&settings, false); + // TODO: We currently have to manually reset it because connect() sets it. + // connect() assumes it's only being called by the user and not internally, so it disables auto-connect + wifi->pause_auto_connect = false; } } @@ -461,8 +463,16 @@ static void eventHandler(TT_UNUSED void* arg, esp_event_base_t event_base, int32 } } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { TT_LOG_I(TAG, "eventHandler: disconnected"); - if (wifi->getRadioState() == RadioState::ConnectionPending) { - wifi->connection_wait_flags.set(WIFI_FAIL_BIT); + switch (wifi->getRadioState()) { + case RadioState::ConnectionPending: + wifi->connection_wait_flags.set(WIFI_FAIL_BIT); + break; + case RadioState::On: + // Ensure we can reconnect again + wifi->pause_auto_connect = false; + break; + default: + break; } wifi->setRadioState(RadioState::On); publish_event_simple(wifi, EventType::Disconnected); @@ -493,14 +503,13 @@ static void eventHandler(TT_UNUSED void* arg, esp_event_base_t event_base, int32 TT_LOG_I(TAG, "eventHandler: Finished scan"); if (copied_list && wifi_singleton->getRadioState() == RadioState::On && !wifi->pause_auto_connect) { - getMainDispatcher().dispatch(dispatchAutoConnect, wifi); + getMainDispatcher().dispatch([wifi]() { dispatchAutoConnect(wifi); }); } } } -static void dispatchEnable(std::shared_ptr context) { +static void dispatchEnable(std::shared_ptr wifi) { TT_LOG_I(TAG, "dispatchEnable()"); - auto wifi = std::static_pointer_cast(context); RadioState state = wifi->getRadioState(); if ( @@ -580,15 +589,17 @@ static void dispatchEnable(std::shared_ptr context) { wifi->setRadioState(RadioState::On); publish_event_simple(wifi, EventType::RadioStateOn); + + wifi->pause_auto_connect = false; + TT_LOG_I(TAG, "Enabled"); } else { TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED); } } -static void dispatchDisable(std::shared_ptr context) { +static void dispatchDisable(std::shared_ptr wifi) { TT_LOG_I(TAG, "dispatchDisable()"); - auto wifi = std::static_pointer_cast(context); auto lock = wifi->radioMutex.asScopedLock(); if (!lock.lock(50 / portTICK_PERIOD_MS)) { @@ -653,9 +664,8 @@ static void dispatchDisable(std::shared_ptr context) { TT_LOG_I(TAG, "Disabled"); } -static void dispatchScan(std::shared_ptr context) { +static void dispatchScan(std::shared_ptr wifi) { TT_LOG_I(TAG, "dispatchScan()"); - auto wifi = std::static_pointer_cast(context); auto lock = wifi->radioMutex.asScopedLock(); if (!lock.lock(10 / portTICK_PERIOD_MS)) { @@ -687,9 +697,8 @@ static void dispatchScan(std::shared_ptr context) { publish_event_simple(wifi, EventType::ScanStarted); } -static void dispatchConnect(std::shared_ptr context) { +static void dispatchConnect(std::shared_ptr wifi) { TT_LOG_I(TAG, "dispatchConnect()"); - auto wifi = std::static_pointer_cast(context); auto lock = wifi->radioMutex.asScopedLock(); if (!lock.lock(50 / portTICK_PERIOD_MS)) { @@ -786,9 +795,8 @@ static void dispatchConnect(std::shared_ptr context) { wifi_singleton->connection_wait_flags.clear(WIFI_FAIL_BIT | WIFI_CONNECTED_BIT); } -static void dispatchDisconnectButKeepActive(std::shared_ptr context) { +static void dispatchDisconnectButKeepActive(std::shared_ptr wifi) { TT_LOG_I(TAG, "dispatchDisconnectButKeepActive()"); - auto wifi = std::static_pointer_cast(context); auto lock = wifi->radioMutex.asScopedLock(); if (!lock.lock(50 / portTICK_PERIOD_MS)) { @@ -836,6 +844,7 @@ static void dispatchDisconnectButKeepActive(std::shared_ptr context) { static bool shouldScanForAutoConnect(std::shared_ptr wifi) { auto lock = wifi->dataMutex.asScopedLock(); if (!lock.lock(100)) { + TT_LOG_W(TAG, "Auto-connect can't lock"); return false; } @@ -844,6 +853,7 @@ static bool shouldScanForAutoConnect(std::shared_ptr wifi) { !wifi->pause_auto_connect; if (!is_radio_in_scannable_state) { + TT_LOG_W(TAG, "Auto-connect: radio state not ok (%d, %d, %d)", (int)wifi->getRadioState(), wifi->isScanActive(), wifi->pause_auto_connect); return false; } @@ -851,15 +861,19 @@ static bool shouldScanForAutoConnect(std::shared_ptr wifi) { bool scan_time_has_looped = (current_time < wifi->last_scan_time); bool no_recent_scan = (current_time - wifi->last_scan_time) > (AUTO_SCAN_INTERVAL / portTICK_PERIOD_MS); + if (!scan_time_has_looped && !no_recent_scan) { + TT_LOG_W(TAG, "Auto-connect: scan time looped = %d, no recent scan = %d", scan_time_has_looped, no_recent_scan); + } + return scan_time_has_looped || no_recent_scan; } -void onAutoConnectTimer(std::shared_ptr context) { +void onAutoConnectTimer() { auto wifi = std::static_pointer_cast(wifi_singleton); // Automatic scanning is done so we can automatically connect to access points bool should_auto_scan = shouldScanForAutoConnect(wifi); if (should_auto_scan) { - getMainDispatcher().dispatch(dispatchScan, wifi); + getMainDispatcher().dispatch([wifi]() { dispatchScan(wifi); }); } } @@ -871,13 +885,13 @@ public: assert(wifi_singleton == nullptr); wifi_singleton = std::make_shared(); - wifi_singleton->autoConnectTimer = std::make_unique(Timer::Type::Periodic, onAutoConnectTimer, wifi_singleton); + wifi_singleton->autoConnectTimer = std::make_unique(Timer::Type::Periodic, []() { onAutoConnectTimer(); }); // We want to try and scan more often in case of startup or scan lock failure wifi_singleton->autoConnectTimer->start(std::min(2000, AUTO_SCAN_INTERVAL)); if (settings::shouldEnableOnBoot()) { TT_LOG_I(TAG, "Auto-enabling due to setting"); - getMainDispatcher().dispatch(dispatchEnable, wifi_singleton); + getMainDispatcher().dispatch([]() { dispatchEnable(wifi_singleton); }); } } diff --git a/Tactility/Source/time/Time.cpp b/Tactility/Source/time/Time.cpp index 978a323c..99d97f12 100644 --- a/Tactility/Source/time/Time.cpp +++ b/Tactility/Source/time/Time.cpp @@ -32,7 +32,7 @@ void setTimeZone(const std::string& name, const std::string& code) { setenv("TZ", code.c_str(), 1); tzset(); - kernel::systemEventPublish(kernel::SystemEvent::Time); + kernel::publishSystemEvent(kernel::SystemEvent::Time); } std::string getTimeZoneName() { @@ -65,7 +65,7 @@ bool isTimeFormat24Hour() { void setTimeFormat24Hour(bool show24Hour) { Preferences preferences(TIME_SETTINGS_NAMESPACE); preferences.putBool(TIMEZONE_PREFERENCES_KEY_TIME24, show24Hour); - kernel::systemEventPublish(kernel::SystemEvent::Time); + kernel::publishSystemEvent(kernel::SystemEvent::Time); } #else @@ -79,7 +79,7 @@ void init() {} void setTimeZone(const std::string& name, const std::string& code) { timeZoneName = name; timeZoneCode = code; - kernel::systemEventPublish(kernel::SystemEvent::Time); + kernel::publishSystemEvent(kernel::SystemEvent::Time); } std::string getTimeZoneName() { @@ -96,7 +96,7 @@ bool isTimeFormat24Hour() { void setTimeFormat24Hour(bool enabled) { show24Hour = enabled; - kernel::systemEventPublish(kernel::SystemEvent::Time); + kernel::publishSystemEvent(kernel::SystemEvent::Time); } #endif diff --git a/TactilityC/Source/tt_timer.cpp b/TactilityC/Source/tt_timer.cpp index 3e6f31e1..62ad2bbb 100644 --- a/TactilityC/Source/tt_timer.cpp +++ b/TactilityC/Source/tt_timer.cpp @@ -3,23 +3,14 @@ struct TimerWrapper { std::unique_ptr timer; - TimerCallback callback; - void* _Nullable callbackContext; }; extern "C" { -static void callbackWrapper(std::shared_ptr wrapper) { - auto timer_wrapper = (TimerWrapper*)wrapper.get(); - timer_wrapper->callback(timer_wrapper->callbackContext); -} - TimerHandle tt_timer_alloc(TimerType type, TimerCallback callback, void* callbackContext) { auto wrapper = std::make_shared(); - wrapper->callback = callback; - wrapper->callbackContext = callbackContext; - wrapper->timer = std::make_unique((tt::Timer::Type)type, callbackWrapper, wrapper); + wrapper->timer = std::make_unique((tt::Timer::Type)type, [callback, callbackContext](){ callback(callbackContext); }); return wrapper.get(); } diff --git a/TactilityCore/Include/Tactility/Dispatcher.h b/TactilityCore/Include/Tactility/Dispatcher.h index 362f2a68..f8462aed 100644 --- a/TactilityCore/Include/Tactility/Dispatcher.h +++ b/TactilityCore/Include/Tactility/Dispatcher.h @@ -22,23 +22,12 @@ namespace tt { class Dispatcher { public: - typedef void (*Function)(std::shared_ptr data); + typedef std::function Function; private: - struct DispatcherMessage { - Function function; - std::shared_ptr context; // Can't use unique_ptr with void, so we use shared_ptr - - DispatcherMessage(Function function, std::shared_ptr context) : - function(function), - context(std::move(context)) - {} - - ~DispatcherMessage() = default; - }; Mutex mutex; - std::queue> queue = {}; + std::queue queue = {}; EventFlag eventFlag; public: @@ -49,9 +38,8 @@ public: /** * Queue a function to be consumed elsewhere. * @param[in] function the function to execute elsewhere - * @param[in] context the data to pass onto the function */ - void dispatch(Function function, std::shared_ptr context, TickType_t timeout = portMAX_DELAY); + void dispatch(Function function, TickType_t timeout = portMAX_DELAY); /** * Consume 1 or more dispatched function (if any) until the queue is empty. diff --git a/TactilityCore/Include/Tactility/DispatcherThread.h b/TactilityCore/Include/Tactility/DispatcherThread.h index 64221b77..7683aab7 100644 --- a/TactilityCore/Include/Tactility/DispatcherThread.h +++ b/TactilityCore/Include/Tactility/DispatcherThread.h @@ -11,6 +11,8 @@ class DispatcherThread { std::unique_ptr thread; bool interruptThread = false; + int32_t threadMain(); + public: explicit DispatcherThread(const std::string& threadName, size_t threadStackSize = 4096); @@ -19,16 +21,13 @@ public: /** * Dispatch a message. */ - void dispatch(Dispatcher::Function function, std::shared_ptr context, TickType_t timeout = portMAX_DELAY); + void dispatch(Dispatcher::Function function, TickType_t timeout = portMAX_DELAY); /** Start the thread (blocking). */ void start(); /** Stop the thread (blocking). */ void stop(); - - /** Internal method */ - void _threadMain(); }; } \ No newline at end of file diff --git a/TactilityCore/Include/Tactility/Thread.h b/TactilityCore/Include/Tactility/Thread.h index 5473614c..97c05114 100644 --- a/TactilityCore/Include/Tactility/Thread.h +++ b/TactilityCore/Include/Tactility/Thread.h @@ -1,12 +1,12 @@ #pragma once #include "CoreDefines.h" - -#include -#include - #include "RtosCompatTask.h" +#include +#include +#include + namespace tt { typedef TaskHandle_t ThreadId; @@ -38,6 +38,7 @@ public: * @warning never use osThreadExit in Thread */ typedef int32_t (*Callback)(void* context); + typedef std::function MainFunction; /** Write to stdout callback * @param[in] data pointer to data @@ -57,8 +58,7 @@ private: TaskHandle_t taskHandle = nullptr; State state = State::Stopped; - Callback callback = nullptr; - void* callbackContext = nullptr; + MainFunction mainFunction; int32_t callbackResult = 0; StateCallback stateCallback = nullptr; void* stateCallbackContext = nullptr; @@ -80,6 +80,7 @@ public: * @param[in] callbackContext * @param[in] affinity Which CPU core to pin this task to, -1 means unpinned (only works on ESP32) */ + [[deprecated("Use constructor variant with std::function")]] Thread( std::string name, configSTACK_DEPTH_TYPE stackSize, @@ -88,6 +89,19 @@ public: portBASE_TYPE affinity = -1 ); + /** Allocate Thread, shortcut version + * @param[in] name the name of the thread + * @param[in] stackSize in bytes + * @param[in] function + * @param[in] affinity Which CPU core to pin this task to, -1 means unpinned (only works on ESP32) + */ + Thread( + std::string name, + configSTACK_DEPTH_TYPE stackSize, + MainFunction function, + portBASE_TYPE affinity = -1 + ); + ~Thread(); /** Set Thread name @@ -104,8 +118,14 @@ public: * @param[in] callback ThreadCallback, called upon thread run * @param[in] callbackContext what to pass to the callback */ + [[deprecated("use setMainFunction()")]] void setCallback(Callback callback, _Nullable void* callbackContext = nullptr); + /** Set Thread callback + * @param[in] function called upon thread run + */ + void setMainFunction(MainFunction function); + /** Set Thread priority * @param[in] priority ThreadPriority value */ diff --git a/TactilityCore/Include/Tactility/Timer.h b/TactilityCore/Include/Tactility/Timer.h index fddd1866..445e23e1 100644 --- a/TactilityCore/Include/Tactility/Timer.h +++ b/TactilityCore/Include/Tactility/Timer.h @@ -2,7 +2,9 @@ #include "RtosCompatTimers.h" #include "Thread.h" + #include +#include namespace tt { @@ -10,7 +12,8 @@ class Timer { public: - typedef void (*Callback)(std::shared_ptr context); + typedef std::function Callback; +// typedef std::function PendingCallback; typedef void (*PendingCallback)(void* context, uint32_t arg); private: @@ -22,7 +25,6 @@ private: }; Callback callback; - std::shared_ptr callbackContext; std::unique_ptr, TimerHandleDeleter> handle; static void onCallback(TimerHandle_t hTimer); @@ -42,9 +44,8 @@ public: /** * @param[in] type The timer type * @param[in] callback The callback function - * @param callbackContext The callback context */ - Timer(Type type, Callback callback, std::shared_ptr callbackContext = nullptr); + Timer(Type type, Callback callback); ~Timer(); diff --git a/TactilityCore/Source/Dispatcher.cpp b/TactilityCore/Source/Dispatcher.cpp index 0fa41cee..756e7d1f 100644 --- a/TactilityCore/Source/Dispatcher.cpp +++ b/TactilityCore/Source/Dispatcher.cpp @@ -15,11 +15,10 @@ Dispatcher::~Dispatcher() { mutex.unlock(); } -void Dispatcher::dispatch(Function function, std::shared_ptr context, TickType_t timeout) { - auto message = std::make_shared(function, std::move(context)); +void Dispatcher::dispatch(Function function, TickType_t timeout) { // Mutate if (mutex.lock(timeout)) { - queue.push(std::move(message)); + queue.push(std::move(function)); if (queue.size() == BACKPRESSURE_WARNING_COUNT) { TT_LOG_W(TAG, "Backpressure: You're not consuming fast enough (100 queued)"); } @@ -46,13 +45,13 @@ uint32_t Dispatcher::consume(TickType_t timeout) { do { if (mutex.lock(10)) { if (!queue.empty()) { - auto item = queue.front(); + auto function = queue.front(); queue.pop(); consumed++; processing = !queue.empty(); // Don't keep lock as callback might be slow mutex.unlock(); - item->function(item->context); + function(); } else { processing = false; mutex.unlock(); diff --git a/TactilityCore/Source/DispatcherThread.cpp b/TactilityCore/Source/DispatcherThread.cpp index 7410b533..f065bdf3 100644 --- a/TactilityCore/Source/DispatcherThread.cpp +++ b/TactilityCore/Source/DispatcherThread.cpp @@ -2,18 +2,13 @@ namespace tt { -int32_t dispatcherThreadMain(void* context) { - auto* dispatcherThread = (DispatcherThread*)context; - dispatcherThread->_threadMain(); - return 0; -} - DispatcherThread::DispatcherThread(const std::string& threadName, size_t threadStackSize) { thread = std::make_unique( threadName, threadStackSize, - dispatcherThreadMain, - this + [this]() { + return threadMain(); + } ); } @@ -23,7 +18,7 @@ DispatcherThread::~DispatcherThread() { } } -void DispatcherThread::_threadMain() { +int32_t DispatcherThread::threadMain() { do { /** * If this value is too high (e.g. 1 second) then the dispatcher destroys too slowly when the simulator exits. @@ -31,10 +26,12 @@ void DispatcherThread::_threadMain() { */ dispatcher.consume(100 / portTICK_PERIOD_MS); } while (!interruptThread); + + return 0; } -void DispatcherThread::dispatch(Dispatcher::Function function, std::shared_ptr context, TickType_t timeout) { - dispatcher.dispatch(function, std::move(context), timeout); +void DispatcherThread::dispatch(Dispatcher::Function function, TickType_t timeout) { + dispatcher.dispatch(function, timeout); } void DispatcherThread::start() { diff --git a/TactilityCore/Source/Thread.cpp b/TactilityCore/Source/Thread.cpp index 3bff0ede..15be24b2 100644 --- a/TactilityCore/Source/Thread.cpp +++ b/TactilityCore/Source/Thread.cpp @@ -53,7 +53,7 @@ void Thread::mainBody(void* context) { TT_LOG_I(TAG, "Starting %s", thread->name.c_str()); assert(thread->state == Thread::State::Starting); thread->setState(Thread::State::Running); - thread->callbackResult = thread->callback(thread->callbackContext); + thread->callbackResult = thread->mainFunction(); assert(thread->state == Thread::State::Running); thread->setState(Thread::State::Stopped); @@ -73,8 +73,21 @@ Thread::Thread( _Nullable void* callbackContext, portBASE_TYPE affinity ) : - callback(callback), - callbackContext(callbackContext), + mainFunction([callback, callbackContext]() { + return callback(callbackContext); + }), + name(std::move(name)), + stackSize(stackSize), + affinity(affinity) +{} + +Thread::Thread( + std::string name, + configSTACK_DEPTH_TYPE stackSize, + MainFunction function, + portBASE_TYPE affinity +) : + mainFunction(function), name(std::move(name)), stackSize(stackSize), affinity(affinity) @@ -97,12 +110,17 @@ void Thread::setStackSize(size_t newStackSize) { stackSize = newStackSize; } -void Thread::setCallback(Callback newCallback, _Nullable void* newCallbackContext) { +void Thread::setCallback(Callback callback, _Nullable void* callbackContext) { assert(state == State::Stopped); - callback = newCallback; - callbackContext = newCallbackContext; + mainFunction = [callback, callbackContext]() { + return callback(callbackContext); + }; } +void Thread::setMainFunction(MainFunction function) { + assert(state == State::Stopped); + mainFunction = function; +} void Thread::setPriority(Priority newPriority) { assert(state == State::Stopped); @@ -121,7 +139,7 @@ Thread::State Thread::getState() const { } void Thread::start() { - assert(callback); + assert(mainFunction); assert(state == State::Stopped); assert(stackSize > 0U && stackSize < (UINT16_MAX * sizeof(StackType_t))); diff --git a/TactilityCore/Source/Timer.cpp b/TactilityCore/Source/Timer.cpp index f9bde67f..1ce15502 100644 --- a/TactilityCore/Source/Timer.cpp +++ b/TactilityCore/Source/Timer.cpp @@ -4,15 +4,12 @@ #include "Tactility/RtosCompat.h" #include "Tactility/kernel/Kernel.h" -#include - namespace tt { void Timer::onCallback(TimerHandle_t hTimer) { auto* timer = static_cast(pvTimerGetTimerID(hTimer)); - if (timer != nullptr) { - timer->callback(timer->callbackContext); + timer->callback(); } } @@ -30,9 +27,8 @@ static inline TimerHandle_t createTimer(Timer::Type type, void* timerId, TimerCa return xTimerCreate(nullptr, portMAX_DELAY, (BaseType_t)reload, timerId, callback); } -Timer::Timer(Type type, Callback callback, std::shared_ptr callbackContext) : +Timer::Timer(Type type, Callback callback) : callback(callback), - callbackContext(std::move(callbackContext)), handle(createTimer(type, this, onCallback)) { assert(!kernel::isIsr()); diff --git a/Tests/TactilityCore/DispatcherTest.cpp b/Tests/TactilityCore/DispatcherTest.cpp index ad5711a9..8f34e5fa 100644 --- a/Tests/TactilityCore/DispatcherTest.cpp +++ b/Tests/TactilityCore/DispatcherTest.cpp @@ -4,26 +4,10 @@ using namespace tt; -static uint32_t counter = 0; -static const uint32_t value_chacker_expected = 123; - -void increment_callback(TT_UNUSED std::shared_ptr context) { - counter++; -} - -void value_checker(std::shared_ptr context) { - auto value = std::static_pointer_cast(context); - if (*value != value_chacker_expected) { - tt_crash("Test error"); - } -} - TEST_CASE("dispatcher should not call callback if consume isn't called") { - counter = 0; + int counter = 0; Dispatcher dispatcher; - - auto context = std::make_shared(); - dispatcher.dispatch(&increment_callback, std::move(context)); + dispatcher.dispatch([&counter]() { counter++; }); kernel::delayTicks(10); CHECK_EQ(counter, 0); @@ -32,24 +16,23 @@ TEST_CASE("dispatcher should not call callback if consume isn't called") { TEST_CASE("dispatcher should be able to dealloc when message is not consumed") { auto* dispatcher = new Dispatcher(); auto context = std::make_shared(); - dispatcher->dispatch(increment_callback, std::move(context)); + dispatcher->dispatch([]() { /* NO-OP */ }); delete dispatcher; } TEST_CASE("dispatcher should call callback when consume is called") { - counter = 0; + int counter = 0; Dispatcher dispatcher; - auto context = std::make_shared(); - dispatcher.dispatch(increment_callback, std::move(context)); + dispatcher.dispatch([&counter]() { counter++; }); dispatcher.consume(100); + CHECK_EQ(counter, 1); } TEST_CASE("message should be passed on correctly") { Dispatcher dispatcher; - auto context = std::make_shared(value_chacker_expected); - dispatcher.dispatch(value_checker, std::move(context)); + dispatcher.dispatch([]() { /* NO-OP */ }); dispatcher.consume(100); } diff --git a/Tests/TactilityCore/TimerTest.cpp b/Tests/TactilityCore/TimerTest.cpp index 44ee3f47..1fc50dbf 100644 --- a/Tests/TactilityCore/TimerTest.cpp +++ b/Tests/TactilityCore/TimerTest.cpp @@ -2,34 +2,11 @@ #include #include -#include - using namespace tt; -std::shared_ptr timer_callback_context = NULL; -static void timer_callback_with_context(std::shared_ptr context) { - timer_callback_context = std::move(context); -} - -static void timer_callback_with_counter(std::shared_ptr context) { - auto int_ptr = std::static_pointer_cast(context); - (*int_ptr)++; -} - -TEST_CASE("a timer passes the context correctly") { - auto foo = std::make_shared(1); - auto* timer = new Timer(Timer::Type::Once, &timer_callback_with_context, foo); - timer->start(1); - kernel::delayTicks(10); - timer->stop(); - delete timer; - - CHECK_EQ(*std::static_pointer_cast(timer_callback_context), *foo); -} - TEST_CASE("TimerType::Periodic timers can be stopped and restarted") { - auto counter = std::make_shared(0); - auto* timer = new Timer(Timer::Type::Periodic, &timer_callback_with_counter, counter); + int counter = 0; + auto* timer = new Timer(Timer::Type::Periodic, [&counter]() { counter++; }); timer->start(1); kernel::delayTicks(10); timer->stop(); @@ -38,24 +15,24 @@ TEST_CASE("TimerType::Periodic timers can be stopped and restarted") { timer->stop(); delete timer; - CHECK_GE(*counter, 2); + CHECK_GE(counter, 2); } TEST_CASE("TimerType::Periodic calls the callback periodically") { - auto counter = std::make_shared(0); int ticks_to_run = 10; - auto* timer = new Timer(Timer::Type::Periodic, &timer_callback_with_counter, counter); + int counter = 0; + auto* timer = new Timer(Timer::Type::Periodic, [&counter]() { counter++; }); timer->start(1); kernel::delayTicks(ticks_to_run); timer->stop(); delete timer; - CHECK_EQ(*counter, ticks_to_run); + CHECK_EQ(counter, ticks_to_run); } TEST_CASE("restarting TimerType::Once timers calls the callback again") { - auto counter = std::make_shared(0); - auto* timer = new Timer(Timer::Type::Once, &timer_callback_with_counter, counter); + int counter = 0; + auto* timer = new Timer(Timer::Type::Once, [&counter]() { counter++; }); timer->start(1); kernel::delayTicks(10); timer->stop(); @@ -64,5 +41,5 @@ TEST_CASE("restarting TimerType::Once timers calls the callback again") { timer->stop(); delete timer; - CHECK_EQ(*counter, 2); + CHECK_EQ(counter, 2); }