Simplify app registration with TactilityCpp (#7)
- Simplified app registration with a C++ wrapper for the TactilityC. - Rename the various app classes from `Application` to more specific names like `Calculator` etc.
This commit is contained in:
committed by
GitHub
parent
e1579d3cbd
commit
b39bd6b6f5
@@ -10,5 +10,6 @@ idf_component_register(
|
|||||||
# Library headers must be included directly,
|
# Library headers must be included directly,
|
||||||
# because all regular dependencies get stripped by elf_loader's cmake script
|
# because all regular dependencies get stripped by elf_loader's cmake script
|
||||||
INCLUDE_DIRS ../../../Libraries/Str/Include
|
INCLUDE_DIRS ../../../Libraries/Str/Include
|
||||||
|
INCLUDE_DIRS ../../../Libraries/TactilityCpp/Include
|
||||||
REQUIRES TactilitySDK
|
REQUIRES TactilitySDK
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,8 +5,9 @@
|
|||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <Str.h>
|
#include <Str.h>
|
||||||
|
#include <TactilityCpp/App.h>
|
||||||
|
|
||||||
class Calculator {
|
class Calculator final : public App {
|
||||||
|
|
||||||
lv_obj_t* displayLabel;
|
lv_obj_t* displayLabel;
|
||||||
lv_obj_t* resultLabel;
|
lv_obj_t* resultLabel;
|
||||||
@@ -23,5 +24,5 @@ class Calculator {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void onShow(AppHandle context, lv_obj_t* parent);
|
void onShow(AppHandle context, lv_obj_t* parent) override;
|
||||||
};
|
};
|
||||||
@@ -1,26 +1,10 @@
|
|||||||
#include <tt_app.h>
|
|
||||||
#include "Calculator.h"
|
#include "Calculator.h"
|
||||||
|
#include <TactilityCpp/App.h>
|
||||||
static void onShowApp(AppHandle appHandle, void* data, lv_obj_t* parent) {
|
|
||||||
static_cast<Calculator*>(data)->onShow(appHandle, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* createAppData() {
|
|
||||||
return new Calculator();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroyAppData(void* app) {
|
|
||||||
delete static_cast<Calculator*>(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
tt_app_register((AppRegistration) {
|
registerApp<Calculator>();
|
||||||
.createData = createAppData,
|
|
||||||
.destroyData = destroyAppData,
|
|
||||||
.onShow = onShowApp,
|
|
||||||
});
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ idf_component_register(
|
|||||||
# Library headers must be included directly,
|
# Library headers must be included directly,
|
||||||
# because all regular dependencies get stripped by elf_loader's cmake script
|
# because all regular dependencies get stripped by elf_loader's cmake script
|
||||||
INCLUDE_DIRS ../../../Libraries/Str/Include
|
INCLUDE_DIRS ../../../Libraries/Str/Include
|
||||||
|
INCLUDE_DIRS ../../../Libraries/TactilityCpp/Include
|
||||||
REQUIRES TactilitySDK
|
REQUIRES TactilitySDK
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+13
-13
@@ -1,4 +1,4 @@
|
|||||||
#include "Application.h"
|
#include "Diceware.h"
|
||||||
|
|
||||||
#include <tt_app_alertdialog.h>
|
#include <tt_app_alertdialog.h>
|
||||||
#include <tt_file.h>
|
#include <tt_file.h>
|
||||||
@@ -53,8 +53,8 @@ static Str readWordAtLine(const AppHandle handle, const int lineIndex) {
|
|||||||
return word;
|
return word;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Application::jobMain(void* data) {
|
int32_t Diceware::jobMain(void* data) {
|
||||||
Application* application = static_cast<Application*>(data);
|
Diceware* application = static_cast<Diceware*>(data);
|
||||||
Str result;
|
Str result;
|
||||||
for (int i = 0; i < application->wordCount; i++) {
|
for (int i = 0; i < application->wordCount; i++) {
|
||||||
constexpr int line_count = 7776;
|
constexpr int line_count = 7776;
|
||||||
@@ -68,7 +68,7 @@ int32_t Application::jobMain(void* data) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::cleanupJob() {
|
void Diceware::cleanupJob() {
|
||||||
if (jobThread != nullptr) {
|
if (jobThread != nullptr) {
|
||||||
tt_thread_join(jobThread, TT_MAX_TICKS);
|
tt_thread_join(jobThread, TT_MAX_TICKS);
|
||||||
tt_thread_free(jobThread);
|
tt_thread_free(jobThread);
|
||||||
@@ -76,7 +76,7 @@ void Application::cleanupJob() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::startJob(uint32_t jobWordCount) {
|
void Diceware::startJob(uint32_t jobWordCount) {
|
||||||
cleanupJob();
|
cleanupJob();
|
||||||
|
|
||||||
wordCount = jobWordCount;
|
wordCount = jobWordCount;
|
||||||
@@ -84,14 +84,14 @@ void Application::startJob(uint32_t jobWordCount) {
|
|||||||
tt_thread_start(jobThread);
|
tt_thread_start(jobThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onFinishJob(Str result) {
|
void Diceware::onFinishJob(Str result) {
|
||||||
tt_lvgl_lock();
|
tt_lvgl_lock();
|
||||||
lv_label_set_text(resultLabel, result.c_str());
|
lv_label_set_text(resultLabel, result.c_str());
|
||||||
tt_lvgl_unlock();
|
tt_lvgl_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onClickGenerate(lv_event_t* e) {
|
void Diceware::onClickGenerate(lv_event_t* e) {
|
||||||
auto* application = static_cast<Application*>(lv_event_get_user_data(e));
|
auto* application = static_cast<Diceware*>(lv_event_get_user_data(e));
|
||||||
auto* spinbox = application->spinbox;
|
auto* spinbox = application->spinbox;
|
||||||
|
|
||||||
lv_label_set_text(application->resultLabel, "Generating...");
|
lv_label_set_text(application->resultLabel, "Generating...");
|
||||||
@@ -100,22 +100,22 @@ void Application::onClickGenerate(lv_event_t* e) {
|
|||||||
application->startJob(word_count);
|
application->startJob(word_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onSpinboxDecrement(lv_event_t* e) {
|
void Diceware::onSpinboxDecrement(lv_event_t* e) {
|
||||||
auto* spinbox = static_cast<lv_obj_t*>(lv_event_get_user_data(e));
|
auto* spinbox = static_cast<lv_obj_t*>(lv_event_get_user_data(e));
|
||||||
lv_spinbox_decrement(spinbox);
|
lv_spinbox_decrement(spinbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onSpinboxIncrement(lv_event_t* e) {
|
void Diceware::onSpinboxIncrement(lv_event_t* e) {
|
||||||
auto* spinbox = static_cast<lv_obj_t*>(lv_event_get_user_data(e));
|
auto* spinbox = static_cast<lv_obj_t*>(lv_event_get_user_data(e));
|
||||||
lv_spinbox_increment(spinbox);
|
lv_spinbox_increment(spinbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onHelpClicked(lv_event_t* e) {
|
void Diceware::onHelpClicked(lv_event_t* e) {
|
||||||
const char* buttons[] = { "OK" };
|
const char* buttons[] = { "OK" };
|
||||||
tt_app_alertdialog_start("Diceware Info", "The hardware random number generator can use the Wi-Fi radio to improve randomness. There's no need to connect to a Wi-Fi network for this to work.", buttons, 1);
|
tt_app_alertdialog_start("Diceware Info", "The hardware random number generator can use the Wi-Fi radio to improve randomness. There's no need to connect to a Wi-Fi network for this to work.", buttons, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onShow(AppHandle appHandle, lv_obj_t* parent) {
|
void Diceware::onShow(AppHandle appHandle, lv_obj_t* parent) {
|
||||||
handle = appHandle;
|
handle = appHandle;
|
||||||
|
|
||||||
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
|
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
|
||||||
@@ -179,6 +179,6 @@ void Application::onShow(AppHandle appHandle, lv_obj_t* parent) {
|
|||||||
lv_obj_set_style_text_align(resultLabel, LV_TEXT_ALIGN_CENTER, LV_STATE_DEFAULT);
|
lv_obj_set_style_text_align(resultLabel, LV_TEXT_ALIGN_CENTER, LV_STATE_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onHide(AppHandle context) {
|
void Diceware::onHide(AppHandle context) {
|
||||||
cleanupJob();
|
cleanupJob();
|
||||||
}
|
}
|
||||||
@@ -5,8 +5,9 @@
|
|||||||
|
|
||||||
#include <Str.h>
|
#include <Str.h>
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
#include <TactilityCpp/App.h>
|
||||||
|
|
||||||
class Application final {
|
class Diceware final : public App {
|
||||||
|
|
||||||
AppHandle handle = nullptr;
|
AppHandle handle = nullptr;
|
||||||
lv_obj_t* spinbox = nullptr;
|
lv_obj_t* spinbox = nullptr;
|
||||||
@@ -27,6 +28,6 @@ class Application final {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void onShow(AppHandle context, lv_obj_t* parent);
|
void onShow(AppHandle context, lv_obj_t* parent) override;
|
||||||
void onHide(AppHandle context);
|
void onHide(AppHandle context) override;
|
||||||
};
|
};
|
||||||
@@ -1,31 +1,10 @@
|
|||||||
#include <tt_app.h>
|
#include "Diceware.h"
|
||||||
#include "Application.h"
|
#include <TactilityCpp/App.h>
|
||||||
|
|
||||||
static void onShowApp(AppHandle appHandle, void* data, lv_obj_t* parent) {
|
|
||||||
static_cast<Application*>(data)->onShow(appHandle, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onHideApp(AppHandle appHandle, void* data) {
|
|
||||||
static_cast<Application*>(data)->onHide(appHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* createAppData() {
|
|
||||||
return new Application();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroyAppData(void* app) {
|
|
||||||
delete static_cast<Application*>(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
tt_app_register((AppRegistration) {
|
registerApp<Diceware>();
|
||||||
.createData = createAppData,
|
|
||||||
.destroyData = destroyAppData,
|
|
||||||
.onShow = onShowApp,
|
|
||||||
.onHide = onHideApp,
|
|
||||||
});
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ idf_component_register(
|
|||||||
# Library headers must be included directly,
|
# Library headers must be included directly,
|
||||||
# because all regular dependencies get stripped by elf_loader's cmake script
|
# because all regular dependencies get stripped by elf_loader's cmake script
|
||||||
INCLUDE_DIRS ../../../Libraries/Str/Include
|
INCLUDE_DIRS ../../../Libraries/Str/Include
|
||||||
|
INCLUDE_DIRS ../../../Libraries/TactilityCpp/Include
|
||||||
REQUIRES TactilitySDK
|
REQUIRES TactilitySDK
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "Application.h"
|
#include "Gpio.h"
|
||||||
|
|
||||||
#include <tt_app_alertdialog.h>
|
#include <tt_app_alertdialog.h>
|
||||||
#include <tt_hal.h>
|
#include <tt_hal.h>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
constexpr char* TAG = "GPIO";
|
constexpr char* TAG = "GPIO";
|
||||||
|
|
||||||
void Application::updatePinStates() {
|
void Gpio::updatePinStates() {
|
||||||
tt_mutex_lock(mutex, TT_MAX_TICKS);
|
tt_mutex_lock(mutex, TT_MAX_TICKS);
|
||||||
// Update pin states
|
// Update pin states
|
||||||
for (int i = 0; i < pinStates.size(); ++i) {
|
for (int i = 0; i < pinStates.size(); ++i) {
|
||||||
@@ -19,7 +19,7 @@ void Application::updatePinStates() {
|
|||||||
tt_mutex_unlock(mutex);
|
tt_mutex_unlock(mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::updatePinWidgets() {
|
void Gpio::updatePinWidgets() {
|
||||||
tt_lvgl_lock();
|
tt_lvgl_lock();
|
||||||
assert(pinStates.size() == pinWidgets.size());
|
assert(pinStates.size() == pinWidgets.size());
|
||||||
for (int j = 0; j < pinStates.size(); ++j) {
|
for (int j = 0; j < pinStates.size(); ++j) {
|
||||||
@@ -39,7 +39,7 @@ void Application::updatePinWidgets() {
|
|||||||
tt_lvgl_unlock();
|
tt_lvgl_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_obj_t* Application::createGpioRowWrapper(lv_obj_t* parent) {
|
lv_obj_t* Gpio::createGpioRowWrapper(lv_obj_t* parent) {
|
||||||
lv_obj_t* wrapper = lv_obj_create(parent);
|
lv_obj_t* wrapper = lv_obj_create(parent);
|
||||||
lv_obj_set_style_pad_all(wrapper, 0, LV_STATE_DEFAULT);
|
lv_obj_set_style_pad_all(wrapper, 0, LV_STATE_DEFAULT);
|
||||||
lv_obj_set_style_border_width(wrapper, 0, LV_STATE_DEFAULT);
|
lv_obj_set_style_border_width(wrapper, 0, LV_STATE_DEFAULT);
|
||||||
@@ -49,13 +49,13 @@ lv_obj_t* Application::createGpioRowWrapper(lv_obj_t* parent) {
|
|||||||
|
|
||||||
// region Task
|
// region Task
|
||||||
|
|
||||||
void Application::onTimer(void* context) {
|
void Gpio::onTimer(void* context) {
|
||||||
Application* app = static_cast<Application*>(context);
|
Gpio* app = static_cast<Gpio*>(context);
|
||||||
app->updatePinStates();
|
app->updatePinStates();
|
||||||
app->updatePinWidgets();
|
app->updatePinWidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::startTask() {
|
void Gpio::startTask() {
|
||||||
tt_mutex_lock(mutex, TT_MAX_TICKS);
|
tt_mutex_lock(mutex, TT_MAX_TICKS);
|
||||||
assert(timer == nullptr);
|
assert(timer == nullptr);
|
||||||
timer = tt_timer_alloc(TimerTypePeriodic, onTimer, this);
|
timer = tt_timer_alloc(TimerTypePeriodic, onTimer, this);
|
||||||
@@ -63,7 +63,7 @@ void Application::startTask() {
|
|||||||
tt_mutex_unlock(mutex);
|
tt_mutex_unlock(mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::stopTask() {
|
void Gpio::stopTask() {
|
||||||
assert(timer);
|
assert(timer);
|
||||||
|
|
||||||
tt_timer_stop(timer);
|
tt_timer_stop(timer);
|
||||||
@@ -81,15 +81,15 @@ static int getSquareSpacing(UiScale scale) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onCreate(AppHandle app) {
|
void Gpio::onCreate(AppHandle app) {
|
||||||
mutex = tt_mutex_alloc(MUTEX_TYPE_RECURSIVE);
|
mutex = tt_mutex_alloc(MUTEX_TYPE_RECURSIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onDestroy(AppHandle app) {
|
void Gpio::onDestroy(AppHandle app) {
|
||||||
tt_mutex_free(mutex);
|
tt_mutex_free(mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onShow(AppHandle app, lv_obj_t* parent) {
|
void Gpio::onShow(AppHandle app, lv_obj_t* parent) {
|
||||||
// auto ui_scale = hal::getConfiguration()->uiScale;
|
// auto ui_scale = hal::getConfiguration()->uiScale;
|
||||||
|
|
||||||
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
|
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
|
||||||
@@ -171,7 +171,7 @@ void Application::onShow(AppHandle app, lv_obj_t* parent) {
|
|||||||
startTask();
|
startTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onHide(AppHandle app) {
|
void Gpio::onHide(AppHandle app) {
|
||||||
stopTask();
|
stopTask();
|
||||||
|
|
||||||
tt_mutex_lock(mutex, TT_MAX_TICKS);
|
tt_mutex_lock(mutex, TT_MAX_TICKS);
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "tt_app.h"
|
#include <TactilityCpp/App.h>
|
||||||
#include "tt_mutex.h"
|
|
||||||
#include "tt_timer.h"
|
#include <tt_app.h>
|
||||||
|
#include <tt_mutex.h>
|
||||||
|
#include <tt_timer.h>
|
||||||
|
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class Application final {
|
class Gpio final : public App {
|
||||||
|
|
||||||
std::vector<lv_obj_t*> pinWidgets;
|
std::vector<lv_obj_t*> pinWidgets;
|
||||||
std::vector<bool> pinStates;
|
std::vector<bool> pinStates;
|
||||||
@@ -19,10 +21,10 @@ class Application final {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void onCreate(AppHandle app);
|
void onCreate(AppHandle app) override;
|
||||||
void onDestroy(AppHandle app);
|
void onDestroy(AppHandle app) override;
|
||||||
void onShow(AppHandle context, lv_obj_t* parent);
|
void onShow(AppHandle context, lv_obj_t* parent) override;
|
||||||
void onHide(AppHandle context);
|
void onHide(AppHandle context) override;
|
||||||
|
|
||||||
void startTask();
|
void startTask();
|
||||||
void stopTask();
|
void stopTask();
|
||||||
@@ -1,41 +1,9 @@
|
|||||||
#include <tt_app.h>
|
#include "Gpio.h"
|
||||||
#include "Application.h"
|
|
||||||
|
|
||||||
static void onCreateApp(AppHandle appHandle, void* data) {
|
|
||||||
static_cast<Application*>(data)->onCreate(appHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onDestroyApp(AppHandle appHandle, void* data) {
|
|
||||||
static_cast<Application*>(data)->onDestroy(appHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onShowApp(AppHandle appHandle, void* data, lv_obj_t* parent) {
|
|
||||||
static_cast<Application*>(data)->onShow(appHandle, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onHideApp(AppHandle appHandle, void* data) {
|
|
||||||
static_cast<Application*>(data)->onHide(appHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* createAppData() {
|
|
||||||
return new Application();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroyAppData(void* app) {
|
|
||||||
delete static_cast<Application*>(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
tt_app_register((AppRegistration) {
|
registerApp<Gpio>();
|
||||||
.createData = createAppData,
|
|
||||||
.destroyData = destroyAppData,
|
|
||||||
.onCreate = onCreateApp,
|
|
||||||
.onDestroy = onDestroyApp,
|
|
||||||
.onShow = onShowApp,
|
|
||||||
.onHide = onHideApp,
|
|
||||||
});
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <concepts>
|
||||||
|
#include <tt_app.h>
|
||||||
|
|
||||||
|
class App {
|
||||||
|
public:
|
||||||
|
virtual void onCreate(AppHandle app) {}
|
||||||
|
virtual void onDestroy(AppHandle app) {}
|
||||||
|
virtual void onShow(AppHandle context, lv_obj_t* parent) {}
|
||||||
|
virtual void onHide(AppHandle context) {}
|
||||||
|
virtual void onResult(AppHandle app, void* _Nullable data, AppLaunchId launchId, AppResult result, BundleHandle resultData) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept AppClass = std::is_base_of<App, T>::value;
|
||||||
|
|
||||||
|
template<AppClass T>
|
||||||
|
void onAppCreate(AppHandle app, void* _Nullable data) {
|
||||||
|
static_cast<T*>(data)->onCreate(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<AppClass T>
|
||||||
|
void onAppDestroy(AppHandle app, void* _Nullable data) {
|
||||||
|
static_cast<T*>(data)->onDestroy(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<AppClass T>
|
||||||
|
void onAppShow(AppHandle context, void* _Nullable data, lv_obj_t* parent) {
|
||||||
|
static_cast<T*>(data)->onShow(context, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<AppClass T>
|
||||||
|
void onAppHide(AppHandle context, void* _Nullable data) {
|
||||||
|
static_cast<T*>(data)->onHide(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<AppClass T>
|
||||||
|
void onAppResult(AppHandle app, void* _Nullable data, AppLaunchId launchId, AppResult result, BundleHandle resultData) {
|
||||||
|
static_cast<T*>(data)->onResult(app, data, launchId, result, resultData);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<AppClass T>
|
||||||
|
void* createAppData() {
|
||||||
|
return new T();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<AppClass T>
|
||||||
|
void destroyAppData(void* appData) {
|
||||||
|
auto* app = static_cast<T*>(appData);
|
||||||
|
delete app;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<AppClass T>
|
||||||
|
void registerApp() {
|
||||||
|
tt_app_register((AppRegistration) {
|
||||||
|
.createData = createAppData<T>,
|
||||||
|
.destroyData = destroyAppData<T>,
|
||||||
|
.onCreate = onAppCreate<T>,
|
||||||
|
.onDestroy = onAppDestroy<T>,
|
||||||
|
.onShow = onAppShow<T>,
|
||||||
|
.onHide = onAppHide<T>,
|
||||||
|
.onResult = onAppResult<T>
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user