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
-122
View File
@@ -1,122 +0,0 @@
#pragma once
#include <tt_bundle.h>
#include <stdio.h>
#include <stdbool.h>
#include <lvgl.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void* AppHandle;
/** Important: These values must map to tt::app::Result values exactly */
typedef enum {
APP_RESULT_OK = 0,
APP_RESULT_CANCELLED = 1,
APP_RESULT_ERROR = 2
} AppResult;
typedef unsigned int AppLaunchId;
/** Important: These function types must map to t::app types exactly. All void* data is nullable. */
typedef void* (*AppCreateData)();
typedef void (*AppDestroyData)(void* data);
typedef void (*AppOnCreate)(AppHandle app, void* data);
typedef void (*AppOnDestroy)(AppHandle app, void* data);
typedef void (*AppOnShow)(AppHandle app, void* data, lv_obj_t* parent);
typedef void (*AppOnHide)(AppHandle app, void* data);
typedef void (*AppOnResult)(AppHandle app, void* data, AppLaunchId launchId, AppResult result, BundleHandle resultData);
/** All callback types are nullable */
typedef struct {
/** The application can allocate data to re-use later (e.g. struct with state) */
AppCreateData createData;
/** If createData is specified, this one must be specified too */
AppDestroyData destroyData;
/** Called when the app is launched (started) */
AppOnCreate onCreate;
/** Called when the app is exited (stopped) */
AppOnDestroy onDestroy;
/** Called when the app is about to be shown to the user (app becomes visible) */
AppOnShow onShow;
/** Called when the app is about to be invisible to the user (e.g. other app was launched by this app, and this app goes to the background) */
AppOnHide onHide;
/** Called when the app receives a result after launching another app */
AppOnResult onResult;
} AppRegistration;
/** This is used to register the manifest of an external app. */
void tt_app_register(const AppRegistration app);
/** @return the bundle that belongs to this application, or null if it wasn't started with parameters. */
BundleHandle tt_app_get_parameters(AppHandle handle);
/**
* Set the result before closing an app.
* The result and bundle are passed along to the app that launched this app, when this app is closed.
* @param[in] handle the app handle to set the result for
* @param[in] result the result state to set
* @param[in] bundle the result bundle to set (can be null)
*/
void tt_app_set_result(AppHandle handle, AppResult result, BundleHandle bundle);
/** @return true if a result was set for this app context */
bool tt_app_has_result(AppHandle handle);
/** Get the path to the user data directory for this app.
* The app can store user-specific (mutable) data in there such as app settings.
* @param[in] handle the app handle
* @param[out] buffer the output buffer (recommended size is 256 bytes)
* @param[inout] size used as input for maximum buffer size (including null terminator) and is set with the path string length by this function
*/
void tt_app_get_user_data_path(AppHandle handle, char* buffer, size_t* size);
/** Resolve a child path in the user directory of this app.
* The app can store user-specific (mutable) data in there such as app settings.
* @param[in] handle the app handle
* @param[in] childPath the child path to resolve
* @param[out] buffer the output buffer (recommended size is 256 bytes)
* @param[inout] size used as input for maximum buffer size (including null terminator) and is set with the path string length by this function
*/
void tt_app_get_user_data_child_path(AppHandle handle, const char* childPath, char* buffer, size_t* size);
/** Get the path to the assets directory of this app.
* The content in this path should be treated as read-only.
* @param[in] handle the app handle
* @param[out] buffer the output buffer (recommended size is 256 bytes)
* @param[inout] size used as input for maximum buffer size (including null terminator) and is set with the path string length by this function
*/
void tt_app_get_assets_path(AppHandle handle, char* buffer, size_t* size);
/** Resolve a child path in the assets directory of this app.
* The content in this path should be treated as read-only.
* @param[in] handle the app handle
* @param[in] childPath the child path to resolve
* @param[out] buffer the output buffer (recommended size is 256 bytes)
* @param[inout] size used as input for maximum buffer size (including null terminator) and is set with the path string length by this function
*/
void tt_app_get_assets_child_path(AppHandle handle, const char* childPath, char* buffer, size_t* size);
/**
* Start an app by id.
* @param[in] appId the app manifest id
*/
void tt_app_start(const char* appId);
/** Stop the currently running app */
void tt_app_stop();
/**
* Start an app by id and bundle.
* @param[in] appId the app manifest id
* @param[in] parameters the parameters to pass onto the starting app
*/
void tt_app_start_with_bundle(const char* appId, BundleHandle parameters);
#ifdef __cplusplus
}
#endif
+8 -9
View File
@@ -1,7 +1,6 @@
#pragma once
#include "tt_app.h"
#include "tt_bundle.h"
#include <app/manager.h>
#ifdef __cplusplus
extern "C" {
@@ -11,18 +10,18 @@ extern "C" {
/**
* Show a dialog with the provided title, message and 0, 1 or more buttons.
* @warning AlertDialog is now a new-model app (see Modules/app-module); it delivers its result
* via APP_EVENT_RESULT to a caller's app_instance_id, which side-loaded ELF apps don't have.
* The dialog will show, but this app's onResult callback will NOT be invoked with the button
* that was pressed - there is currently no bridge back to the old ELF app result mechanism.
* @param[in] parent_id parent app ID or 0
* @param[in] title the title to show in the toolbar
* @param[in] message the message to display
* @param[in] buttonLabels the buttons to show, or null when there are none to show
* @param[in] buttonLabelCount the amount of buttons (0 or more)
* @return the launch ID of the dialog, which can be compared in onResult to identify the source
* @return the launch ID of the dialog (kept for source compatibility; no onResult will follow)
*/
AppLaunchId tt_app_alertdialog_start(const char* title, const char* message, const char* buttonLabels[], uint32_t buttonLabelCount);
/**
* @return the index of the button that was clicked (the index in the array when start() was called)
*/
int32_t tt_app_alertdialog_get_result_index(BundleHandle handle);
AppInstanceId tt_app_alertdialog_start(AppInstanceId parent_id, const char* title, const char* message, const char* buttonLabels[], uint32_t buttonLabelCount);
#ifdef __cplusplus
}
+10 -9
View File
@@ -1,7 +1,6 @@
#pragma once
#include "tt_app.h"
#include "tt_bundle.h"
#include <app/manager.h>
#ifdef __cplusplus
extern "C" {
@@ -9,23 +8,25 @@ extern "C" {
/**
* Show a file selection dialog that allows the user to select an existing file.
* @return the launch ID of the dialog, which can be compared in onResult to identify the source
* @return the launch ID of the dialog
*/
AppLaunchId tt_app_fileselection_start_for_existing_file();
AppInstanceId tt_app_fileselection_start_for_existing_file(AppInstanceId app_id);
/**
* Show a file selection dialog that allows the user to select a new or existing file.
* @return the launch ID of the dialog, which can be compared in onResult to identify the source
* @return the launch ID of the dialog
*/
AppLaunchId tt_app_fileselection_start_for_existing_or_new_file();
AppInstanceId tt_app_fileselection_start_for_existing_or_new_file(AppInstanceId app_id);
/**
* @param[in] handle the result bundle passed to onResult
* @return the path picked by the last FileSelection dialog that closed with result == Ok (see
* tt::app::fileselection::getLastPath()). Only one dialog is expected to be open at a time.
* @param[out] buffer the buffer to store the selected path in
* @param[in] bufferSize the size of the buffer (must include room for the null terminator)
* @return true if a path was selected and written to buffer, false otherwise
* @retval false @a bufferSize was too small - @a buffer is left untouched
* @retval true @a buffer was filled
*/
bool tt_app_fileselection_get_result_path(BundleHandle handle, char* buffer, uint32_t bufferSize);
bool tt_app_fileselection_get_result_path(char* buffer, uint32_t bufferSize);
#ifdef __cplusplus
}
+4 -7
View File
@@ -1,7 +1,6 @@
#pragma once
#include "tt_app.h"
#include "tt_bundle.h"
#include <app/manager.h>
#ifdef __cplusplus
extern "C" {
@@ -9,15 +8,13 @@ extern "C" {
/**
* Start an app that displays a list of items and allows the user to select one.
* @param[in] parent_id parent app ID or 0
* @param[in] title the title to show in the toolbar
* @param[in] argc the amount of items that the list contains
* @param[in] argv the labels of the items in the list
* @return the launch ID of the dialog, which can be compared in onResult to identify the source
* @return the app instance ID of the dialog, which can be compared in onResult to identify the source
*/
AppLaunchId tt_app_selectiondialog_start(const char* title, int argc, const char* argv[]);
/** @return the index of the item that was clicked by the user, or -1 when the user didn't select anything */
int32_t tt_app_selectiondialog_get_result_index(BundleHandle handle);
AppInstanceId tt_app_selectiondialog_start(AppInstanceId parent_id, const char* title, int argc, const char* argv[]);
#ifdef __cplusplus
}
-74
View File
@@ -1,74 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
/** The handle that represents a bundle instance */
typedef void* BundleHandle;
/** @return a new bundle instance */
BundleHandle tt_bundle_alloc();
/** Dealloc an existing bundle instance */
void tt_bundle_free(BundleHandle handle);
/**
* Try to get a boolean value from a Bundle
* @param[in] handle the handle that represents the bundle
* @param[in] key the identifier that represents the stored value (~variable name)
* @param[out] out the output value (only set when return value is set to true)
* @return true if "out" was set
*/
bool tt_bundle_opt_bool(BundleHandle handle, const char* key, bool* out);
/**
* Try to get an int32_t value from a Bundle
* @param[in] handle the handle that represents the bundle
* @param[in] key the identifier that represents the stored value (~variable name)
* @param[out] out the output value (only set when return value is set to true)
* @return true if "out" was set
*/
bool tt_bundle_opt_int32(BundleHandle handle, const char* key, int32_t* out);
/**
* Try to get a string from a Bundle
* @warning outSize must be large enough to include null terminator. This means that your string has to be the expected text length + 1 extra character.
* @param[in] handle the handle that represents the bundle
* @param[in] key the identifier that represents the stored value (~variable name)
* @param[out] out the buffer to store the string in
* @param[in] outSize the size of the buffer
* @return true if "out" was set
*/
bool tt_bundle_opt_string(BundleHandle handle, const char* key, char* out, uint32_t outSize);
/**
* Store a boolean value in a Bundle
* @param[in] handle the handle that represents the bundle
* @param[in] key the identifier that represents the stored value (~variable name)
* @param[in] value the value to store
*/
void tt_bundle_put_bool(BundleHandle handle, const char* key, bool value);
/**
* Store an int32_t value in a Bundle
* @param[in] handle the handle that represents the bundle
* @param[in] key the identifier that represents the stored value (~variable name)
* @param[in] value the value to store
*/
void tt_bundle_put_int32(BundleHandle handle, const char* key, int32_t value);
/**
* Store a string value in a Bundle
* @param[in] handle the handle that represents the bundle
* @param[in] key the identifier that represents the stored value (~variable name)
* @param[in] value the value to store
*/
void tt_bundle_put_string(BundleHandle handle, const char* key, const char* value);
#ifdef __cplusplus
}
#endif
-83
View File
@@ -1,83 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
/**
* Note that on ESP32, there are limitations:
* - namespace name is limited by NVS_NS_NAME_MAX_SIZE (generally 16 characters)
* - key is limited by NVS_KEY_NAME_MAX_SIZE (generally 16 characters)
*/
/** The handle that represents a Preferences instance */
typedef void* PreferencesHandle;
/**
* @param[in] identifier the name of the preferences. This determines the NVS namespace on ESP.
* @return a new preferences instance
*/
PreferencesHandle tt_preferences_alloc(const char* identifier);
/** Dealloc an existing preferences instance */
void tt_preferences_free(PreferencesHandle handle);
/**
* Try to get a boolean value
* @param[in] handle the handle that represents the preferences
* @param[in] key the identifier that represents the stored value (~variable name)
* @param[out] out the output value (only set when return value is set to true)
* @return true if "out" was set
*/
bool tt_preferences_opt_bool(PreferencesHandle handle, const char* key, bool* out);
/**
* Try to get an int32_t value
* @param[in] handle the handle that represents the preferences
* @param[in] key the identifier that represents the stored value (~variable name)
* @param[out] out the output value (only set when return value is set to true)
* @return true if "out" was set
*/
bool tt_preferences_opt_int32(PreferencesHandle handle, const char* key, int32_t* out);
/**
* Try to get a string
* @warning outSize must be large enough to include null terminator. This means that your string has to be the expected text length + 1 extra character.
* @param[in] handle the handle that represents the preferences
* @param[in] key the identifier that represents the stored value (~variable name)
* @param[out] out the buffer to store the string in
* @param[in] outSize the size of the buffer
* @return true if "out" was set
*/
bool tt_preferences_opt_string(PreferencesHandle handle, const char* key, char* out, uint32_t outSize);
/**
* Store a boolean value
* @param[in] handle the handle that represents the preferences
* @param[in] key the identifier that represents the stored value (~variable name)
* @param[in] value the value to store
*/
void tt_preferences_put_bool(PreferencesHandle handle, const char* key, bool value);
/**
* Store an int32_t value
* @param[in] handle the handle that represents the preferences
* @param[in] key the identifier that represents the stored value (~variable name)
* @param[in] value the value to store
*/
void tt_preferences_put_int32(PreferencesHandle handle, const char* key, int32_t value);
/**
* Store a string value
* @param[in] handle the handle that represents the preferences
* @param[in] key the identifier that represents the stored value (~variable name)
* @param[in] value the value to store
*/
void tt_preferences_put_string(PreferencesHandle handle, const char* key, const char* value);
#ifdef __cplusplus
}
#endif
-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);
}
}