Refactor app loading and window management (#609)

This commit is contained in:
Ken Van Hoeylandt
2026-08-11 23:40:59 +02:00
committed by GitHub
parent dc3f6104b8
commit 37c507544b
243 changed files with 16034 additions and 10865 deletions
-133
View File
@@ -1,133 +0,0 @@
#include "tt_app.h"
#include <Tactility/app/App.h>
#include <Tactility/app/AppPaths.h>
#include <Tactility/app/AppContext.h>
#include <Tactility/app/ElfApp.h>
#include <tactility/log.h>
#include <cstring>
constexpr auto* TAG = "tt_app";
extern "C" {
#define HANDLE_AS_APP_CONTEXT(handle) ((tt::app::AppContext*)(handle))
void tt_app_register(
const AppRegistration appRegistration
) {
#ifdef ESP_PLATFORM
assert((appRegistration.createData == nullptr) == (appRegistration.destroyData == nullptr));
tt::app::setElfAppParameters(
appRegistration.createData,
appRegistration.destroyData,
appRegistration.onCreate,
appRegistration.onDestroy,
appRegistration.onShow,
appRegistration.onHide,
reinterpret_cast<tt::app::OnResult>(appRegistration.onResult)
);
#else
check(false, "TactilityC is not intended for PC/Simulator");
#endif
}
BundleHandle tt_app_get_parameters(AppHandle handle) {
return (BundleHandle)HANDLE_AS_APP_CONTEXT(handle)->getParameters().get();
}
void tt_app_set_result(AppHandle handle, AppResult result, BundleHandle bundle) {
auto shared_bundle = std::unique_ptr<tt::Bundle>(static_cast<tt::Bundle*>(bundle));
HANDLE_AS_APP_CONTEXT(handle)->getApp()->setResult(static_cast<tt::app::Result>(result), std::move(shared_bundle));
}
bool tt_app_has_result(AppHandle handle) {
return HANDLE_AS_APP_CONTEXT(handle)->getApp()->hasResult();
}
void tt_app_start(const char* appId) {
tt::app::start(appId);
}
void tt_app_start_with_bundle(const char* appId, BundleHandle parameters) {
tt::app::start(appId, std::shared_ptr<tt::Bundle>(static_cast<tt::Bundle*>(parameters)));
}
void tt_app_stop() {
tt::app::stop();
}
void tt_app_get_user_data_path(AppHandle handle, char* buffer, size_t* size) {
assert(buffer != nullptr);
assert(size != nullptr);
assert(*size > 0);
const auto paths = HANDLE_AS_APP_CONTEXT(handle)->getPaths();
const auto data_path = paths->getUserDataPath();
const auto expected_length = data_path.length() + 1;
if (*size < expected_length) {
LOG_E(TAG, "Path buffer not large enough (%u < %u)", (unsigned)*size, (unsigned)expected_length);
*size = 0;
buffer[0] = 0;
return;
}
strcpy(buffer, data_path.c_str());
*size = data_path.length();
}
void tt_app_get_user_data_child_path(AppHandle handle, const char* childPath, char* buffer, size_t* size) {
assert(buffer != nullptr);
assert(size != nullptr);
assert(*size > 0);
const auto paths = HANDLE_AS_APP_CONTEXT(handle)->getPaths();
const auto resolved_path = paths->getUserDataPath(childPath);
const auto resolved_path_length = resolved_path.length();
if (*size < (resolved_path_length + 1)) {
LOG_E(TAG, "Path buffer not large enough (%u < %u)", (unsigned)*size, (unsigned)(resolved_path_length + 1));
*size = 0;
buffer[0] = 0;
return;
}
strcpy(buffer, resolved_path.c_str());
*size = resolved_path_length;
}
void tt_app_get_assets_path(AppHandle handle, char* buffer, size_t* size) {
assert(buffer != nullptr);
assert(size != nullptr);
assert(*size > 0);
const auto paths = HANDLE_AS_APP_CONTEXT(handle)->getPaths();
const auto assets_path = paths->getAssetsPath();
const auto expected_length = assets_path.length() + 1;
if (*size < expected_length) {
LOG_E(TAG, "Path buffer not large enough (%u < %u)", (unsigned)*size, (unsigned)expected_length);
*size = 0;
buffer[0] = 0;
return;
}
strcpy(buffer, assets_path.c_str());
*size = assets_path.length();
}
void tt_app_get_assets_child_path(AppHandle handle, const char* childPath, char* buffer, size_t* size) {
assert(buffer != nullptr);
assert(size != nullptr);
assert(*size > 0);
const auto paths = HANDLE_AS_APP_CONTEXT(handle)->getPaths();
const auto resolved_path = paths->getAssetsPath(childPath);
const auto resolved_path_length = resolved_path.length();
if (*size < (resolved_path_length + 1)) {
LOG_E(TAG, "Path buffer not large enough (%u < %u)", (unsigned)*size, (unsigned)(resolved_path_length + 1));
*size = 0;
buffer[0] = 0;
return;
}
strcpy(buffer, resolved_path.c_str());
*size = resolved_path_length;
}
}
+4 -6
View File
@@ -1,18 +1,16 @@
#include "tt_app_alertdialog.h"
#include <Tactility/app/alertdialog/AlertDialog.h>
extern "C" {
AppLaunchId tt_app_alertdialog_start(const char* title, const char* message, const char* buttonLabels[], uint32_t buttonLabelCount) {
AppInstanceId tt_app_alertdialog_start(AppInstanceId parent_id, const char* title, const char* message, const char* buttonLabels[], uint32_t buttonLabelCount) {
std::vector<std::string> list;
for (int i = 0; i < buttonLabelCount; i++) {
list.emplace_back(buttonLabels[i]);
}
return tt::app::alertdialog::start(title, message, list);
}
int32_t tt_app_alertdialog_get_result_index(BundleHandle handle) {
return tt::app::alertdialog::getResultIndex(*(tt::Bundle*)handle);
// TODO: Get caller app instance id from task context?
return tt::app::alertdialog::start(parent_id, title, message, list);
}
}
+8 -11
View File
@@ -1,28 +1,25 @@
#include "tt_app_fileselection.h"
#include <Tactility/app/App.h>
#include <Tactility/app/fileselection/FileSelection.h>
#include <Tactility/Bundle.h>
#include <cstring>
#include <string>
extern "C" {
AppLaunchId tt_app_fileselection_start_for_existing_file() {
return tt::app::fileselection::startForExistingFile();
AppInstanceId tt_app_fileselection_start_for_existing_file(AppInstanceId app_id) {
return tt::app::fileselection::startForExistingFile(app_id);
}
AppLaunchId tt_app_fileselection_start_for_existing_or_new_file() {
return tt::app::fileselection::startForExistingOrNewFile();
AppInstanceId tt_app_fileselection_start_for_existing_or_new_file(AppInstanceId app_id) {
return tt::app::fileselection::startForExistingOrNewFile(app_id);
}
bool tt_app_fileselection_get_result_path(BundleHandle handle, char* buffer, uint32_t bufferSize) {
auto path = tt::app::fileselection::getResultPath(*(tt::Bundle*)handle);
if (path.empty() || bufferSize == 0) {
bool tt_app_fileselection_get_result_path(char* buffer, uint32_t bufferSize) {
const std::string path = tt::app::fileselection::getLastPath();
if (path.length() + 1 > bufferSize) {
return false;
}
strncpy(buffer, path.c_str(), bufferSize - 1);
buffer[bufferSize - 1] = '\0';
std::strcpy(buffer, path.c_str());
return true;
}
+2 -6
View File
@@ -3,16 +3,12 @@
extern "C" {
AppLaunchId tt_app_selectiondialog_start(const char* title, int argc, const char* argv[]) {
AppInstanceId tt_app_selectiondialog_start(AppInstanceId parent_id, const char* title, int argc, const char* argv[]) {
std::vector<std::string> list;
for (int i = 0; i < argc; i++) {
list.emplace_back(argv[i]);
}
return tt::app::selectiondialog::start(title, list);
}
int32_t tt_app_selectiondialog_get_result_index(BundleHandle handle) {
return tt::app::selectiondialog::getResultIndex(*(tt::Bundle*)handle);
return tt::app::selectiondialog::start(parent_id, title, list);
}
}
-53
View File
@@ -1,53 +0,0 @@
#include "tt_bundle.h"
#include <Tactility/Bundle.h>
#include <cstring>
#define HANDLE_AS_BUNDLE(handle) ((tt::Bundle*)(handle))
extern "C" {
BundleHandle tt_bundle_alloc() {
return new tt::Bundle();
}
void tt_bundle_free(BundleHandle handle) {
delete HANDLE_AS_BUNDLE(handle);
}
bool tt_bundle_opt_bool(BundleHandle handle, const char* key, bool* out) {
return HANDLE_AS_BUNDLE(handle)->optBool(key, *out);
}
bool tt_bundle_opt_int32(BundleHandle handle, const char* key, int32_t* out) {
return HANDLE_AS_BUNDLE(handle)->optInt32(key, *out);
}
bool tt_bundle_opt_string(BundleHandle handle, const char* key, char* out, uint32_t outSize) {
std::string out_string;
if (!HANDLE_AS_BUNDLE(handle)->optString(key, out_string)) {
return false;
}
if (out_string.length() >= outSize) {
// Need 1 byte to add 0 at the end
return false;
}
memcpy(out, out_string.c_str(), out_string.length());
out[out_string.length()] = 0x00;
return true;
}
void tt_bundle_put_bool(BundleHandle handle, const char* key, bool value) {
HANDLE_AS_BUNDLE(handle)->putBool(key, value);
}
void tt_bundle_put_int32(BundleHandle handle, const char* key, int32_t value) {
HANDLE_AS_BUNDLE(handle)->putInt32(key, value);
}
void tt_bundle_put_string(BundleHandle handle, const char* key, const char* value) {
HANDLE_AS_BUNDLE(handle)->putString(key, value);
}
}
-32
View File
@@ -1,11 +1,8 @@
#ifdef ESP_PLATFORM
#include "tt_app.h"
#include "tt_app_alertdialog.h"
#include "tt_app_fileselection.h"
#include "tt_app_selectiondialog.h"
#include "tt_bundle.h"
#include "tt_preferences.h"
#include "tt_time.h"
#include "symbols/cplusplus.h"
@@ -274,40 +271,11 @@ const esp_elfsym main_symbols[] {
ESP_ELFSYM_EXPORT(esp_log_timestamp),
ESP_ELFSYM_EXPORT(esp_err_to_name),
// Tactility
ESP_ELFSYM_EXPORT(tt_app_start),
ESP_ELFSYM_EXPORT(tt_app_start_with_bundle),
ESP_ELFSYM_EXPORT(tt_app_stop),
ESP_ELFSYM_EXPORT(tt_app_register),
ESP_ELFSYM_EXPORT(tt_app_get_parameters),
ESP_ELFSYM_EXPORT(tt_app_set_result),
ESP_ELFSYM_EXPORT(tt_app_has_result),
ESP_ELFSYM_EXPORT(tt_app_fileselection_start_for_existing_file),
ESP_ELFSYM_EXPORT(tt_app_fileselection_start_for_existing_or_new_file),
ESP_ELFSYM_EXPORT(tt_app_fileselection_get_result_path),
ESP_ELFSYM_EXPORT(tt_app_selectiondialog_start),
ESP_ELFSYM_EXPORT(tt_app_selectiondialog_get_result_index),
ESP_ELFSYM_EXPORT(tt_app_alertdialog_start),
ESP_ELFSYM_EXPORT(tt_app_alertdialog_get_result_index),
ESP_ELFSYM_EXPORT(tt_app_get_user_data_path),
ESP_ELFSYM_EXPORT(tt_app_get_user_data_child_path),
ESP_ELFSYM_EXPORT(tt_app_get_assets_path),
ESP_ELFSYM_EXPORT(tt_app_get_assets_child_path),
ESP_ELFSYM_EXPORT(tt_bundle_alloc),
ESP_ELFSYM_EXPORT(tt_bundle_free),
ESP_ELFSYM_EXPORT(tt_bundle_opt_bool),
ESP_ELFSYM_EXPORT(tt_bundle_opt_int32),
ESP_ELFSYM_EXPORT(tt_bundle_opt_string),
ESP_ELFSYM_EXPORT(tt_bundle_put_bool),
ESP_ELFSYM_EXPORT(tt_bundle_put_int32),
ESP_ELFSYM_EXPORT(tt_bundle_put_string),
ESP_ELFSYM_EXPORT(tt_preferences_alloc),
ESP_ELFSYM_EXPORT(tt_preferences_free),
ESP_ELFSYM_EXPORT(tt_preferences_opt_bool),
ESP_ELFSYM_EXPORT(tt_preferences_opt_int32),
ESP_ELFSYM_EXPORT(tt_preferences_opt_string),
ESP_ELFSYM_EXPORT(tt_preferences_put_bool),
ESP_ELFSYM_EXPORT(tt_preferences_put_int32),
ESP_ELFSYM_EXPORT(tt_preferences_put_string),
ESP_ELFSYM_EXPORT(tt_timezone_set),
ESP_ELFSYM_EXPORT(tt_timezone_get_name),
ESP_ELFSYM_EXPORT(tt_timezone_get_code),
-53
View File
@@ -1,53 +0,0 @@
#include "tt_preferences.h"
#include <Tactility/Preferences.h>
#include <cstring>
#define HANDLE_AS_PREFERENCES(handle) ((tt::Preferences*)(handle))
extern "C" {
PreferencesHandle tt_preferences_alloc(const char* identifier) {
return new tt::Preferences(identifier);
}
void tt_preferences_free(PreferencesHandle handle) {
delete HANDLE_AS_PREFERENCES(handle);
}
bool tt_preferences_opt_bool(PreferencesHandle handle, const char* key, bool* out) {
return HANDLE_AS_PREFERENCES(handle)->optBool(key, *out);
}
bool tt_preferences_opt_int32(PreferencesHandle handle, const char* key, int32_t* out) {
return HANDLE_AS_PREFERENCES(handle)->optInt32(key, *out);
}
bool tt_preferences_opt_string(PreferencesHandle handle, const char* key, char* out, uint32_t outSize) {
std::string out_string;
if (!HANDLE_AS_PREFERENCES(handle)->optString(key, out_string)) {
return false;
}
if (out_string.length() >= outSize) {
// Need 1 byte to add 0 at the end
return false;
}
memcpy(out, out_string.c_str(), out_string.length());
out[out_string.length()] = 0x00;
return true;
}
void tt_preferences_put_bool(PreferencesHandle handle, const char* key, bool value) {
HANDLE_AS_PREFERENCES(handle)->putBool(key, value);
}
void tt_preferences_put_int32(PreferencesHandle handle, const char* key, int32_t value) {
HANDLE_AS_PREFERENCES(handle)->putInt32(key, value);
}
void tt_preferences_put_string(PreferencesHandle handle, const char* key, const char* value) {
HANDLE_AS_PREFERENCES(handle)->putString(key, value);
}
}