C++ conversions (#111)

* Remove version from artifact name
* Target C++ 20 and higher
* Use cpp string
* Better crash implementation
* String utils in cpp style
* Replace parameter methods with start() method
* MutexType to Mutex::Type
* Kernel c to cpp style
* Cleanup event flag
* More cpp conversions
* Test fixes
* Updated ideas docs
This commit is contained in:
Ken Van Hoeylandt
2024-12-07 12:24:28 +01:00
committed by GitHub
parent d52fe52d96
commit 42e843b463
66 changed files with 272 additions and 258 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.16)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (DEFINED ENV{ESP_IDF_VERSION})
+1 -1
View File
@@ -37,7 +37,7 @@ class AppInstance : public AppContext {
private:
Mutex mutex = Mutex(MutexTypeNormal);
Mutex mutex = Mutex(Mutex::TypeNormal);
const AppManifest& manifest;
State state = StateInitial;
Flags flags = { .showStatusbar = true };
+1 -1
View File
@@ -143,7 +143,7 @@ struct Loader {
std::shared_ptr<PubSub> pubsub_internal = std::make_shared<PubSub>();
std::shared_ptr<PubSub> pubsub_external = std::make_shared<PubSub>();
MessageQueue queue = MessageQueue(2, sizeof(LoaderMessage)); // 2 entries, so you can stop the current app while starting a new one without blocking
Mutex mutex = Mutex(MutexTypeRecursive);
Mutex mutex = Mutex(Mutex::TypeRecursive);
std::stack<app::AppInstance*> app_stack;
};
+3 -3
View File
@@ -155,9 +155,9 @@ void run(const Configuration& config) {
TT_LOG_I(TAG, "init starting desktop app");
service::loader::startApp(app::boot::manifest.id, true);
if (config.auto_start_app_id) {
TT_LOG_I(TAG, "init auto-starting %s", config.auto_start_app_id);
service::loader::startApp(config.auto_start_app_id, true);
if (config.autoStartAppId) {
TT_LOG_I(TAG, "init auto-starting %s", config.autoStartAppId);
service::loader::startApp(config.autoStartAppId, true);
}
TT_LOG_I(TAG, "init complete");
+1 -1
View File
@@ -12,7 +12,7 @@ typedef struct {
// List of user applications
const app::AppManifest* const apps[TT_CONFIG_APPS_LIMIT];
const service::ServiceManifest* const services[TT_CONFIG_SERVICES_LIMIT];
const char* auto_start_app_id;
const char* autoStartAppId;
} Configuration;
/**
+1 -1
View File
@@ -10,7 +10,7 @@ namespace tt::app {
typedef std::unordered_map<std::string, const AppManifest*> AppManifestMap;
static AppManifestMap app_manifest_map;
static Mutex hash_mutex(MutexTypeNormal);
static Mutex hash_mutex(Mutex::TypeNormal);
void addApp(const AppManifest* manifest) {
TT_LOG_I(TAG, "Registering manifest %s", manifest->id.c_str());
+8 -8
View File
@@ -1,13 +1,13 @@
#include <Check.h>
#include <Thread.h>
#include <Kernel.h>
#include "Assets.h"
#include "TactilityCore.h"
#include "app/AppContext.h"
#include "lvgl.h"
#include "app/display/DisplaySettings.h"
#include "hal/Display.h"
#include "service/loader/Loader.h"
#include "lvgl/Style.h"
#include "app/display/DisplaySettings.h"
#include "lvgl.h"
#ifdef ESP_PLATFORM
#include "sdkconfig.h"
@@ -26,7 +26,7 @@ struct Data {
};
static int32_t threadCallback(TT_UNUSED void* context) {
TickType_t start_time = tt::get_ticks();
TickType_t start_time = tt::kernel::getTicks();
auto* lvgl_display = lv_display_get_default();
tt_assert(lvgl_display != nullptr);
@@ -37,11 +37,11 @@ static int32_t threadCallback(TT_UNUSED void* context) {
hal_display->setBacklightDuty(backlight_duty);
}
TickType_t end_time = tt::get_ticks();
TickType_t end_time = tt::kernel::getTicks();
TickType_t ticks_passed = end_time - start_time;
TickType_t minimum_ticks = (CONFIG_TT_SPLASH_DURATION / portTICK_PERIOD_MS);
if (minimum_ticks > ticks_passed) {
tt::delay_ticks(minimum_ticks - ticks_passed);
tt::kernel::delayTicks(minimum_ticks - ticks_passed);
}
tt::service::loader::stopApp();
tt::service::loader::startApp("Desktop");
+4 -4
View File
@@ -81,7 +81,7 @@ static void onNavigateUpPressed(TT_UNUSED lv_event_t* event) {
if (strcmp(files_data->current_path, "/") != 0) {
TT_LOG_I(TAG, "Navigating upwards");
char new_absolute_path[MAX_PATH_LENGTH];
if (string_get_path_parent(files_data->current_path, new_absolute_path)) {
if (string::getPathParent(files_data->current_path, new_absolute_path)) {
data_set_entries_for_path(files_data, new_absolute_path);
}
}
@@ -102,7 +102,7 @@ static void viewFile(const char* path, const char* filename) {
// For PC we need to make the path relative to the current work directory,
// because that's how LVGL maps its 'drive letter' to the file system.
char* processed_filepath;
if (get_platform() == PlatformSimulator) {
if (kernel::getPlatform() == kernel::PlatformSimulator) {
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)) == nullptr) {
TT_LOG_E(TAG, "Failed to get current working directory");
@@ -126,7 +126,7 @@ static void viewFile(const char* path, const char* filename) {
service::loader::startApp("ImageViewer", false, bundle);
} else if (isSupportedTextFile(filename)) {
auto bundle = std::make_shared<Bundle>();
if (get_platform() == PlatformEsp) {
if (kernel::getPlatform() == kernel::PlatformEsp) {
bundle->putString(TEXT_VIEWER_FILE_ARGUMENT, processed_filepath);
} else {
// Remove forward slash, because we need a relative path
@@ -220,7 +220,7 @@ static void onShow(AppContext& app, lv_obj_t* parent) {
static void onStart(AppContext& app) {
auto data = std::make_shared<Data>();
// PC platform is bound to current work directory because of the LVGL file system mapping
if (get_platform() == PlatformSimulator) {
if (kernel::getPlatform() == kernel::PlatformSimulator) {
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)) != nullptr) {
data_set_entries_for_path(data, cwd);
+1 -1
View File
@@ -42,7 +42,7 @@ bool data_set_entries_for_path(std::shared_ptr<Data> data, const char* path) {
* ESP32 does not have a root directory, so we have to create it manually.
* We'll add the NVS Flash partitions and the binding for the sdcard.
*/
if (get_platform() == PlatformEsp && strcmp(path, "/") == 0) {
if (kernel::getPlatform() == kernel::PlatformEsp && strcmp(path, "/") == 0) {
int dir_entries_count = 3;
auto** dir_entries = static_cast<dirent**>(malloc(sizeof(struct dirent*) * 3));
+1 -1
View File
@@ -91,7 +91,7 @@ static int32_t taskMain(void* context) {
bool interrupted = false;
while (!interrupted) {
delay_ms(100);
kernel::delayMillis(100);
gpio->updatePinStates();
gpio->updatePinWidgets();
@@ -27,7 +27,7 @@ std::string getPortNamesForDropdown() {
}
port_index++;
}
return string_join(config_names, "\n");
return string::join(config_names, "\n");
}
}
+1 -1
View File
@@ -19,7 +19,7 @@ enum ScanState {
struct Data {
// Core
Mutex mutex = Mutex(MutexTypeRecursive);
Mutex mutex = Mutex(Mutex::TypeRecursive);
Thread* _Nullable scanThread = nullptr;
// State
ScanState scanState;
+2 -2
View File
@@ -41,7 +41,7 @@ static void updateUi(std::shared_ptr<Data> data) {
uint16_t charge_level_scaled = (int16_t)charge_level * 100 / 255;
int32_t current = data->power->getCurrent();
lvgl::lock(ms_to_ticks(1000));
lvgl::lock(kernel::millisToTicks(1000));
lv_obj_set_state(data->enable_switch, LV_STATE_CHECKED, charging_enabled);
lv_label_set_text_fmt(data->charge_state, "Charging: %s", charge_state);
lv_label_set_text_fmt(data->charge_level, "Charge level: %d%%", charge_level_scaled);
@@ -110,7 +110,7 @@ static void onShow(AppContext& app, lv_obj_t* parent) {
data->current = lv_label_create(wrapper);
updateUi(data);
data->update_timer->start(ms_to_ticks(1000));
data->update_timer->start(kernel::millisToTicks(1000));
}
static void onHide(TT_UNUSED AppContext& app) {
@@ -124,7 +124,7 @@ static void create_path_ui(std::shared_ptr<ScreenshotUi> ui, lv_obj_t* parent) {
lv_textarea_set_one_line(path_textarea, true);
lv_obj_set_flex_grow(path_textarea, 1);
ui->path_textarea = path_textarea;
if (get_platform() == PlatformEsp) {
if (kernel::getPlatform() == kernel::PlatformEsp) {
if (hal::sdcard::getState() == hal::sdcard::StateMounted) {
lv_textarea_set_text(path_textarea, "A:/sdcard");
} else {
@@ -16,9 +16,14 @@ namespace tt::app::selectiondialog {
#define TAG "selection_dialog"
void setItemsParameter(Bundle& bundle, const std::vector<std::string>& items) {
std::string result = string_join(items, PARAMETER_ITEM_CONCATENATION_TOKEN);
bundle.putString(PARAMETER_BUNDLE_KEY_ITEMS, result);
extern const AppManifest manifest;
void start(std::string title, const std::vector<std::string>& items) {
std::string items_joined = string::join(items, PARAMETER_ITEM_CONCATENATION_TOKEN);
auto bundle = std::make_shared<Bundle>();
bundle->putString(PARAMETER_BUNDLE_KEY_TITLE, title);
bundle->putString(PARAMETER_BUNDLE_KEY_ITEMS, items_joined);
service::loader::startApp(manifest.id, false, bundle);
}
int32_t getResultIndex(const Bundle& bundle) {
@@ -31,10 +36,6 @@ void setResultIndex(std::shared_ptr<Bundle> bundle, int32_t index) {
bundle->putInt32(RESULT_BUNDLE_KEY_INDEX, index);
}
void setTitleParameter(std::shared_ptr<Bundle> bundle, const std::string& title) {
bundle->putString(PARAMETER_BUNDLE_KEY_TITLE, title);
}
static std::string getTitleParameter(std::shared_ptr<const Bundle> bundle) {
std::string result;
if (bundle->optString(PARAMETER_BUNDLE_KEY_TITLE, result)) {
@@ -76,7 +77,7 @@ static void onShow(AppContext& app, lv_obj_t* parent) {
tt_check(parameters != nullptr, "Parameters missing");
std::string items_concatenated;
if (parameters->optString(PARAMETER_BUNDLE_KEY_ITEMS, items_concatenated)) {
std::vector<std::string> items = string_split(items_concatenated, PARAMETER_ITEM_CONCATENATION_TOKEN);
std::vector<std::string> items = string::split(items_concatenated, PARAMETER_ITEM_CONCATENATION_TOKEN);
if (items.empty() || items.front().empty()) {
TT_LOG_E(TAG, "No items provided");
app.setResult(ResultError);
@@ -14,10 +14,7 @@
*/
namespace tt::app::selectiondialog {
/** App startup parameters */
void setTitleParameter(Bundle& bundle, const std::string& title);
void setItemsParameter(Bundle& bundle, const std::vector<std::string>& items);
void start(std::string title, const std::vector<std::string>& items);
/** App result data */
+1 -1
View File
@@ -10,7 +10,7 @@ namespace tt::app::wifimanage {
*/
class State {
Mutex mutex = Mutex(MutexTypeRecursive);
Mutex mutex = Mutex(Mutex::TypeRecursive);
bool scanning;
service::wifi::WifiRadioState radioState;
std::vector<service::wifi::WifiApRecord> apRecords;
+2 -2
View File
@@ -39,7 +39,7 @@ typedef struct {
} Statusbar;
static void statusbar_init() {
statusbar_data.mutex = tt_mutex_alloc(MutexTypeRecursive);
statusbar_data.mutex = tt_mutex_alloc(Mutex::TypeRecursive);
statusbar_data.pubsub = std::make_shared<PubSub>();
for (int i = 0; i < STATUSBAR_ICON_LIMIT; i++) {
statusbar_data.icons[i].image = nullptr;
@@ -83,7 +83,7 @@ static const lv_obj_class_t statusbar_class = {
static void statusbar_pubsub_event(TT_UNUSED const void* message, void* obj) {
TT_LOG_I(TAG, "event");
auto* statusbar = static_cast<Statusbar*>(obj);
if (lock(ms_to_ticks(100))) {
if (lock(kernel::millisToTicks(100))) {
update_main(statusbar);
lv_obj_invalidate(&statusbar->obj);
unlock();
+1 -1
View File
@@ -36,7 +36,7 @@ Gui* gui_alloc() {
&gui_main,
nullptr
);
instance->mutex = tt_mutex_alloc(MutexTypeRecursive);
instance->mutex = tt_mutex_alloc(Mutex::TypeRecursive);
instance->keyboard = nullptr;
instance->loader_pubsub_subscription = tt_pubsub_subscribe(loader::getPubsub(), &loader_callback, instance);
tt_check(lvgl::lock(1000 / portTICK_PERIOD_MS));
+3 -2
View File
@@ -16,6 +16,7 @@
namespace tt::service::loader {
#define TAG "loader"
#define LOADER_EVENT_FLAG 1
typedef struct {
LoaderEventType type;
@@ -77,7 +78,7 @@ LoaderStatus startApp(const std::string& id, bool blocking, std::shared_ptr<cons
/* TODO: Check if task id is not the LVGL one,
because otherwise this fails as the apps starting logic will try to lock lvgl
to update the UI and fail. */
event_flag->wait(TT_API_LOCK_EVENT);
event_flag->wait(LOADER_EVENT_FLAG);
delete event_flag;
}
@@ -330,7 +331,7 @@ static int32_t loader_main(TT_UNUSED void* parameter) {
message.payload.start->parameters
);
if (message.api_lock != nullptr) {
message.api_lock->set(TT_API_LOCK_EVENT);
message.api_lock->set(LOADER_EVENT_FLAG);
}
message.cleanup();
break;
@@ -43,7 +43,7 @@ ScreenshotTask* alloc() {
auto* data = static_cast<ScreenshotTaskData*>(malloc(sizeof(ScreenshotTaskData)));
*data = (ScreenshotTaskData) {
.thread = nullptr,
.mutex = tt_mutex_alloc(MutexTypeRecursive),
.mutex = tt_mutex_alloc(Mutex::TypeRecursive),
.interrupted = false
};
return data;
@@ -76,7 +76,7 @@ static int32_t screenshot_task(void* context) {
if (data->work.type == TASK_WORK_TYPE_DELAY) {
// Splitting up the delays makes it easier to stop the service
for (int i = 0; i < (data->work.delay_in_seconds * 10) && !is_interrupted(data); ++i){
delay_ms(100);
kernel::delayMillis(100);
}
if (is_interrupted(data)) {
@@ -102,7 +102,7 @@ static int32_t screenshot_task(void* context) {
if (app) {
const app::AppManifest& manifest = app->getManifest();
if (manifest.id != last_app_id) {
delay_ms(100);
kernel::delayMillis(100);
last_app_id = manifest.id;
char filename[SCREENSHOT_PATH_LIMIT + 32];
@@ -116,7 +116,7 @@ static int32_t screenshot_task(void* context) {
lvgl::unlock();
}
}
delay_ms(250);
kernel::delayMillis(250);
}
}