From 83e226f696da6fe5acb6252b0dc27abcf715de55 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Sat, 6 Jan 2024 20:37:41 +0100 Subject: [PATCH] implemented service registry (#8) + implemented app and service context for data sharing --- components/furi/src/app.c | 10 +- components/furi/src/app_i.h | 4 +- components/furi/src/app_manifest.h | 11 +- components/furi/src/context.h | 11 ++ components/furi/src/furi.c | 3 + components/furi/src/service.c | 21 +++ components/furi/src/service_i.h | 12 ++ components/furi/src/service_manifest.h | 5 +- components/furi/src/service_registry.c | 136 ++++++++++++++++++ components/furi/src/service_registry.h | 25 ++++ components/tactility/CMakeLists.txt | 13 +- .../src/apps/system/system_info/system_info.c | 6 +- .../src/apps/system/system_info/system_info.h | 13 -- .../tactility/src/services/desktop/desktop.c | 4 +- components/tactility/src/services/gui/gui.c | 8 +- components/tactility/src/services/gui/gui.h | 2 - components/tactility/src/services/gui/gui_i.h | 6 - .../tactility/src/services/gui/view_port.c | 4 +- .../tactility/src/services/gui/view_port.h | 5 +- .../tactility/src/services/gui/view_port_i.h | 3 +- .../tactility/src/services/loader/loader.c | 38 ++--- .../tactility/src/services/loader/loader.h | 9 +- .../tactility/src/services/loader/loader_i.h | 2 - components/tactility/src/tactility.c | 30 ++-- main/src/hello_world/hello_world.c | 2 +- 25 files changed, 282 insertions(+), 101 deletions(-) create mode 100644 components/furi/src/context.h create mode 100644 components/furi/src/service.c create mode 100644 components/furi/src/service_i.h create mode 100644 components/furi/src/service_registry.c create mode 100644 components/furi/src/service_registry.h delete mode 100644 components/tactility/src/apps/system/system_info/system_info.h diff --git a/components/furi/src/app.c b/components/furi/src/app.c index 359290c8..6728aaf1 100644 --- a/components/furi/src/app.c +++ b/components/furi/src/app.c @@ -8,7 +8,9 @@ App* furi_app_alloc(const AppManifest* _Nonnull manifest) { App app = { .manifest = manifest, - .ep_thread_args = NULL + .context = { + .data = NULL + } }; App* app_ptr = malloc(sizeof(App)); return memcpy(app_ptr, &app, sizeof(App)); @@ -16,11 +18,5 @@ App* furi_app_alloc(const AppManifest* _Nonnull manifest) { void furi_app_free(App* app) { furi_assert(app); - - if (app->ep_thread_args) { - free(app->ep_thread_args); - app->ep_thread_args = NULL; - } - free(app); } diff --git a/components/furi/src/app_i.h b/components/furi/src/app_i.h index 984f1646..c5b08eaa 100644 --- a/components/furi/src/app_i.h +++ b/components/furi/src/app_i.h @@ -9,11 +9,9 @@ extern "C" { typedef struct { const AppManifest* manifest; - void* ep_thread_args; + Context context; } App; -const char* furi_app_type_to_string(AppType type); -FuriThread* furi_app_alloc_thread(App* _Nonnull app, const char* args); App* furi_app_alloc(const AppManifest* _Nonnull manifest); void furi_app_free(App* _Nonnull app); diff --git a/components/furi/src/app_manifest.h b/components/furi/src/app_manifest.h index 0b84d93e..1ae4804f 100644 --- a/components/furi/src/app_manifest.h +++ b/components/furi/src/app_manifest.h @@ -1,5 +1,6 @@ #pragma once +#include "context.h" #include #ifdef __cplusplus @@ -15,20 +16,20 @@ typedef enum { AppTypeUser } AppType; -typedef void (*AppOnStart)(void _Nonnull* parameter); -typedef void (*AppOnStop)(); -typedef void (*AppOnShow)(lv_obj_t* parent, void* context); +typedef void (*AppOnStart)(Context* context); +typedef void (*AppOnStop)(Context* context); +typedef void (*AppOnShow)(Context* context, lv_obj_t* parent); typedef struct { /** * The identifier by which the app is launched by the system and other apps. */ - const char* _Nonnull id; + const char* id; /** * The user-readable name of the app. Used in UI. */ - const char* _Nonnull name; + const char* name; /** * Optional icon. diff --git a/components/furi/src/context.h b/components/furi/src/context.h new file mode 100644 index 00000000..620571d4 --- /dev/null +++ b/components/furi/src/context.h @@ -0,0 +1,11 @@ +#pragma once + +typedef struct { + /** Contextual data related to the running app's instance + * + * The app can attach its data to this. + * The lifecycle is determined by the on_start and on_stop methods in the AppManifest. + * These manifest methods can optionally allocate/free data that is attached here. + */ + void* data; +} Context; diff --git a/components/furi/src/furi.c b/components/furi/src/furi.c index b21ce6dc..4444c7cd 100644 --- a/components/furi/src/furi.c +++ b/components/furi/src/furi.c @@ -1,7 +1,9 @@ #include "furi.h" + #include "app_manifest_registry.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" +#include "service_registry.h" #define TAG "furi" @@ -22,6 +24,7 @@ void furi_init() { NVIC_SetPriority(SVCall_IRQn, 0U); #endif + service_registry_init(); app_manifest_registry_init(); FURI_LOG_I(TAG, "init complete"); } diff --git a/components/furi/src/service.c b/components/furi/src/service.c new file mode 100644 index 00000000..19a3727e --- /dev/null +++ b/components/furi/src/service.c @@ -0,0 +1,21 @@ +#include "service_i.h" +#include "furi_core.h" +#include "log.h" + +#define TAG "service" + +Service* furi_service_alloc(const ServiceManifest* _Nonnull manifest) { + Service app = { + .manifest = manifest, + .context = { + .data = NULL + } + }; + Service* app_ptr = malloc(sizeof(Service)); + return memcpy(app_ptr, &app, sizeof(Service)); +} + +void furi_service_free(Service* app) { + furi_assert(app); + free(app); +} diff --git a/components/furi/src/service_i.h b/components/furi/src/service_i.h new file mode 100644 index 00000000..fb34348f --- /dev/null +++ b/components/furi/src/service_i.h @@ -0,0 +1,12 @@ +#pragma once + +#include "service_manifest.h" +#include "context.h" + +typedef struct { + const ServiceManifest* manifest; + Context context; +} Service; + +Service* furi_service_alloc(const ServiceManifest* _Nonnull manifest); +void furi_service_free(Service* _Nonnull service); diff --git a/components/furi/src/service_manifest.h b/components/furi/src/service_manifest.h index 6418d86a..b065ba13 100644 --- a/components/furi/src/service_manifest.h +++ b/components/furi/src/service_manifest.h @@ -1,13 +1,14 @@ #pragma once #include +#include "context.h" #ifdef __cplusplus extern "C" { #endif -typedef void (*ServiceOnStart)(void _Nonnull* parameter); -typedef void (*ServiceOnStop)(); +typedef void (*ServiceOnStart)(Context* context); +typedef void (*ServiceOnStop)(Context* context); typedef struct { /** diff --git a/components/furi/src/service_registry.c b/components/furi/src/service_registry.c new file mode 100644 index 00000000..61c4ef8d --- /dev/null +++ b/components/furi/src/service_registry.c @@ -0,0 +1,136 @@ +#include "service_registry.h" + +#include "furi_core.h" +#include "m-dict.h" +#include "m_cstr_dup.h" +#include "mutex.h" +#include "service_i.h" + +#define TAG "service_registry" + +DICT_DEF2(ServiceManifestDict, const char*, M_CSTR_DUP_OPLIST, const ServiceManifest*, M_PTR_OPLIST) +DICT_DEF2(ServiceInstanceDict, const char*, M_CSTR_DUP_OPLIST, const Service*, M_PTR_OPLIST) + +#define APP_REGISTRY_FOR_EACH(manifest_var_name, code_to_execute) \ + { \ + service_registry_manifest_lock(); \ + ServiceManifestDict_it_t it; \ + for (ServiceManifestDict_it(it, service_manifest_dict); !ServiceManifestDict_end_p(it); ServiceManifestDict_next(it)) { \ + const ServiceManifest*(manifest_var_name) = ServiceManifestDict_cref(it)->value; \ + code_to_execute; \ + } \ + service_registry_manifest_unlock(); \ + } + +ServiceManifestDict_t service_manifest_dict; +ServiceInstanceDict_t service_instance_dict; +FuriMutex* manifest_mutex = NULL; +FuriMutex* instance_mutex = NULL; + +void service_registry_init() { + furi_assert(manifest_mutex == NULL); + manifest_mutex = furi_mutex_alloc(FuriMutexTypeNormal); + ServiceManifestDict_init(service_manifest_dict); + + furi_assert(instance_mutex == NULL); + instance_mutex = furi_mutex_alloc(FuriMutexTypeNormal); + ServiceInstanceDict_init(service_instance_dict); +} + +void service_registry_instance_lock() { + furi_assert(instance_mutex != NULL); + furi_mutex_acquire(instance_mutex, FuriWaitForever); +} + +void service_registry_instance_unlock() { + furi_assert(instance_mutex != NULL); + furi_mutex_release(instance_mutex); +} + +void service_registry_manifest_lock() { + furi_assert(manifest_mutex != NULL); + furi_mutex_acquire(manifest_mutex, FuriWaitForever); +} + +void service_registry_manifest_unlock() { + furi_assert(manifest_mutex != NULL); + furi_mutex_release(manifest_mutex); +} +void service_registry_add(const ServiceManifest _Nonnull* manifest) { + FURI_LOG_I(TAG, "adding %s", manifest->id); + + service_registry_manifest_lock(); + ServiceManifestDict_set_at(service_manifest_dict, manifest->id, manifest); + service_registry_manifest_unlock(); +} + +void service_registry_remove(const ServiceManifest _Nonnull* manifest) { + FURI_LOG_I(TAG, "removing %s", manifest->id); + service_registry_manifest_lock(); + ServiceManifestDict_erase(service_manifest_dict, manifest->id); + service_registry_manifest_unlock(); +} + +const ServiceManifest* _Nullable service_registry_find_manifest_by_id(const char* id) { + service_registry_manifest_lock(); + const ServiceManifest** _Nullable manifest = ServiceManifestDict_get(service_manifest_dict, id); + service_registry_manifest_unlock(); + return (manifest != NULL) ? *manifest : NULL; +} + +Service* _Nullable service_registry_find_instance_by_id(const char* id) { + service_registry_instance_lock(); + const Service** _Nullable service_ptr = ServiceInstanceDict_get(service_instance_dict, id); + if (service_ptr == NULL) { + return NULL; + } + Service* service = (Service*) *service_ptr; + service_registry_instance_unlock(); + return service; +} + +void service_registry_for_each_manifest(ServiceManifestCallback callback, void* _Nullable context) { + APP_REGISTRY_FOR_EACH(manifest, { + callback(manifest, context); + }); +} + +// TODO: return proper error/status instead of BOOL +bool service_registry_start(const char* service_id) { + FURI_LOG_I(TAG, "starting %s", service_id); + const ServiceManifest* manifest = service_registry_find_manifest_by_id(service_id); + if (manifest == NULL) { + FURI_LOG_I(TAG, "manifest not found for %s", service_id); + return false; + } + + Service* service = furi_service_alloc(manifest); + service->manifest->on_start(&service->context); + + service_registry_instance_lock(); + ServiceInstanceDict_set_at(service_instance_dict, manifest->id, service); + service_registry_instance_unlock(); + FURI_LOG_I(TAG, "started %s", service_id); + + return true; +} + +bool service_registry_stop(const char* service_id) { + FURI_LOG_I(TAG, "stopping %s", service_id); + Service* service = service_registry_find_instance_by_id(service_id); + if (service == NULL) { + FURI_LOG_I(TAG, "service not running: %s", service_id); + return false; + } + + service->manifest->on_stop(&service->context); + furi_service_free(service); + + service_registry_instance_lock(); + ServiceInstanceDict_erase(service_instance_dict, service_id); + service_registry_instance_unlock(); + + FURI_LOG_I(TAG, "stopped %s", service_id); + + return true; +} diff --git a/components/furi/src/service_registry.h b/components/furi/src/service_registry.h new file mode 100644 index 00000000..4a053cf6 --- /dev/null +++ b/components/furi/src/service_registry.h @@ -0,0 +1,25 @@ +#pragma once + +#include "service_manifest.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef void (*ServiceManifestCallback)(const ServiceManifest*, void* context); + +void service_registry_init(); + +void service_registry_add(const ServiceManifest* manifest); +void service_registry_remove(const ServiceManifest* manifest); +const ServiceManifest _Nullable* service_registry_find_manifest_by_id(const char* id); +void service_registry_for_each_manifest(ServiceManifestCallback callback, void* _Nullable context); + +bool service_registry_start(const char* service_id); +bool service_registry_stop(const char* service_id); + +#ifdef __cplusplus +} +#endif diff --git a/components/tactility/CMakeLists.txt b/components/tactility/CMakeLists.txt index e83d2717..31c9e8c4 100644 --- a/components/tactility/CMakeLists.txt +++ b/components/tactility/CMakeLists.txt @@ -5,8 +5,19 @@ idf_component_register( "src/services/loader" "src/services/gui" "src/services/gui/widgets" + INCLUDE_DIRS "src" - REQUIRES esp_lvgl_port esp_lcd esp_lcd_touch driver mlib cmsis_core furi nvs_flash spiffs fatfs + + REQUIRES cmsis_core + esp_lcd + esp_lcd_touch + esp_lvgl_port + driver + fatfs + furi + mlib + nvs_flash + spiffs ) set(ASSETS_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/assets") diff --git a/components/tactility/src/apps/system/system_info/system_info.c b/components/tactility/src/apps/system/system_info/system_info.c index 93a86728..a14d3a5e 100644 --- a/components/tactility/src/apps/system/system_info/system_info.c +++ b/components/tactility/src/apps/system/system_info/system_info.c @@ -1,9 +1,9 @@ -#include "system_info.h" +#include "app_manifest.h" #include "furi_extra_defines.h" #include "thread.h" #include "lvgl.h" -static void app_show(lv_obj_t* parent, void* context) { +static void app_show(Context* context, lv_obj_t* parent) { UNUSED(context); lv_obj_t* heap_info = lv_label_create(parent); @@ -38,5 +38,5 @@ AppManifest system_info_app = { .type = AppTypeSystem, .on_start = NULL, .on_stop = NULL, - .on_show = app_show + .on_show = &app_show }; diff --git a/components/tactility/src/apps/system/system_info/system_info.h b/components/tactility/src/apps/system/system_info/system_info.h deleted file mode 100644 index f86ee622..00000000 --- a/components/tactility/src/apps/system/system_info/system_info.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "app_manifest.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern AppManifest system_info_app; - -#ifdef __cplusplus -} -#endif diff --git a/components/tactility/src/services/desktop/desktop.c b/components/tactility/src/services/desktop/desktop.c index 6e56b612..6b19bb05 100644 --- a/components/tactility/src/services/desktop/desktop.c +++ b/components/tactility/src/services/desktop/desktop.c @@ -9,7 +9,7 @@ static void on_open_app(lv_event_t* e) { lv_event_code_t code = lv_event_get_code(e); if (code == LV_EVENT_CLICKED) { const AppManifest* manifest = lv_event_get_user_data(e); - loader_start_app_nonblocking(manifest->id, NULL); + loader_start_app_nonblocking(manifest->id); } } @@ -20,7 +20,7 @@ static void add_app_to_list(const AppManifest* manifest, void* _Nullable parent) lv_obj_add_event_cb(btn, &on_open_app, LV_EVENT_CLICKED, (void*)manifest); } -static void desktop_show(lv_obj_t* parent, void* context) { +static void desktop_show(Context* context, lv_obj_t* parent) { lv_obj_t* list = lv_list_create(parent); lv_obj_set_size(list, LV_PCT(100), LV_PCT(100)); lv_obj_center(list); diff --git a/components/tactility/src/services/gui/gui.c b/components/tactility/src/services/gui/gui.c index 0d51c123..23d80134 100644 --- a/components/tactility/src/services/gui/gui.c +++ b/components/tactility/src/services/gui/gui.c @@ -143,8 +143,8 @@ static int32_t gui_main(void* p) { // region AppManifest -static void gui_start(void* parameter) { - UNUSED(parameter); +static void gui_start(Context* context) { + UNUSED(context); gui = gui_alloc(); @@ -152,7 +152,9 @@ static void gui_start(void* parameter) { furi_thread_start(gui->thread); } -static void gui_stop() { +static void gui_stop(Context* context) { + UNUSED(context); + gui_lock(); FuriThreadId thread_id = furi_thread_get_id(gui->thread); diff --git a/components/tactility/src/services/gui/gui.h b/components/tactility/src/services/gui/gui.h index 5f5a18f3..0757dd6d 100644 --- a/components/tactility/src/services/gui/gui.h +++ b/components/tactility/src/services/gui/gui.h @@ -21,7 +21,6 @@ typedef struct Gui Gui; * * @remark thread safe * - * @param gui Gui instance * @param view_port ViewPort instance * @param[in] layer GuiLayer where to place view_port */ @@ -31,7 +30,6 @@ void gui_add_view_port(ViewPort* view_port, GuiLayer layer); * * @remark thread safe * - * @param gui Gui instance * @param view_port ViewPort instance */ void gui_remove_view_port(ViewPort* view_port); diff --git a/components/tactility/src/services/gui/gui_i.h b/components/tactility/src/services/gui/gui_i.h index 775c2ea7..6a2db07c 100644 --- a/components/tactility/src/services/gui/gui_i.h +++ b/components/tactility/src/services/gui/gui_i.h @@ -33,8 +33,6 @@ struct Gui { }; /** Update GUI, request redraw - * - * @param gui Gui instance */ void gui_request_draw(); @@ -48,13 +46,9 @@ void gui_request_draw(); //void gui_input_events_callback(const void* value, void* ctx); /** Lock GUI - * - * @param gui The Gui instance */ void gui_lock(); /** Unlock GUI - * - * @param gui The Gui instance */ void gui_unlock(); diff --git a/components/tactility/src/services/gui/view_port.c b/components/tactility/src/services/gui/view_port.c index c88dd70f..bf009d73 100644 --- a/components/tactility/src/services/gui/view_port.c +++ b/components/tactility/src/services/gui/view_port.c @@ -48,7 +48,7 @@ bool view_port_is_enabled(const ViewPort* view_port) { return is_enabled; } -void view_port_draw_callback_set(ViewPort* view_port, ViewPortDrawCallback callback, void* context) { +void view_port_draw_callback_set(ViewPort* view_port, ViewPortDrawCallback callback, Context* context) { furi_assert(view_port); furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); view_port->draw_callback = callback; @@ -91,7 +91,7 @@ void view_port_draw(ViewPort* view_port, lv_obj_t* parent) { if (view_port->draw_callback) { lv_obj_clean(parent); lv_obj_set_style_no_padding(parent); - view_port->draw_callback(parent, view_port->draw_callback_context); + view_port->draw_callback(view_port->draw_callback_context, parent); } furi_mutex_release(view_port->mutex); diff --git a/components/tactility/src/services/gui/view_port.h b/components/tactility/src/services/gui/view_port.h index 19d3917d..afde4466 100644 --- a/components/tactility/src/services/gui/view_port.h +++ b/components/tactility/src/services/gui/view_port.h @@ -5,6 +5,7 @@ extern "C" { #endif #include "lvgl.h" +#include "context.h" typedef struct ViewPort ViewPort; @@ -19,7 +20,7 @@ typedef enum { /** ViewPort Draw callback * @warning called from GUI thread */ -typedef void (*ViewPortDrawCallback)(lv_obj_t* parent, void* context); +typedef void (*ViewPortDrawCallback)(Context* context, lv_obj_t* parent); /** ViewPort allocator * @@ -52,7 +53,7 @@ bool view_port_is_enabled(const ViewPort* view_port); * @param callback appropriate callback function * @param context context to pass to callback */ -void view_port_draw_callback_set(ViewPort* view_port, ViewPortDrawCallback callback, void* context); +void view_port_draw_callback_set(ViewPort* view_port, ViewPortDrawCallback callback, Context* context); /** Emit update signal to GUI system. * * Rendering will happen later after GUI system process signal. diff --git a/components/tactility/src/services/gui/view_port_i.h b/components/tactility/src/services/gui/view_port_i.h index 9edd0023..4eddebfa 100644 --- a/components/tactility/src/services/gui/view_port_i.h +++ b/components/tactility/src/services/gui/view_port_i.h @@ -1,5 +1,6 @@ #pragma once +#include "context.h" #include "gui_i.h" #include "mutex.h" #include "view_port.h" @@ -10,7 +11,7 @@ struct ViewPort { bool is_enabled; ViewPortDrawCallback draw_callback; - void* draw_callback_context; + Context* draw_callback_context; /* ViewPortInputCallback input_callback; diff --git a/components/tactility/src/services/loader/loader.c b/components/tactility/src/services/loader/loader.c index 859ac6ef..a0bf75c5 100644 --- a/components/tactility/src/services/loader/loader.c +++ b/components/tactility/src/services/loader/loader.c @@ -27,7 +27,6 @@ static Loader* loader_alloc() { &loader_main, NULL ); - loader->app_data.args = NULL; loader->app_data.app = NULL; loader->app_data.view_port = NULL; loader->mutex = xSemaphoreCreateRecursiveMutex(); @@ -55,13 +54,12 @@ void loader_unlock() { furi_check(xSemaphoreGiveRecursive(loader->mutex) == pdPASS); } -LoaderStatus loader_start_app(const char* id, const char* args, FuriString* error_message) { +LoaderStatus loader_start_app(const char* id, FuriString* error_message) { LoaderMessage message; LoaderMessageLoaderStatusResult result; message.type = LoaderMessageTypeAppStart; message.start.id = id; - message.start.args = args; message.start.error_message = error_message; message.api_lock = api_lock_alloc_locked(); message.status_value = &result; @@ -70,13 +68,12 @@ LoaderStatus loader_start_app(const char* id, const char* args, FuriString* erro return result.value; } -void loader_start_app_nonblocking(const char* id, const char* args) { +void loader_start_app_nonblocking(const char* id) { LoaderMessage message; LoaderMessageLoaderStatusResult result; message.type = LoaderMessageTypeAppStart; message.start.id = id; - message.start.args = args; message.start.error_message = NULL; message.api_lock = NULL; message.status_value = &result; @@ -142,8 +139,7 @@ static LoaderStatus loader_make_success_status(FuriString* error_message) { } static void loader_start_app_with_manifest( - const AppManifest* _Nonnull manifest, - const char* args + const AppManifest* _Nonnull manifest ) { FURI_LOG_I(TAG, "start with manifest %s", manifest->id); @@ -156,17 +152,19 @@ static void loader_start_app_with_manifest( loader_lock(); loader->app_data.app = app; - loader->app_data.args = (void*)args; if (manifest->on_start != NULL) { - manifest->on_start((void*)args); + manifest->on_start(&loader->app_data.app->context); } if (manifest->on_show != NULL) { ViewPort* view_port = view_port_alloc(); loader->app_data.view_port = view_port; - view_port_draw_callback_set(view_port, manifest->on_show, NULL); - + view_port_draw_callback_set( + view_port, + manifest->on_show, + &loader->app_data.app->context + ); gui_add_view_port(view_port, GuiLayerWindow); } else { loader->app_data.view_port = NULL; @@ -182,7 +180,6 @@ static void loader_start_app_with_manifest( static LoaderStatus loader_do_start_by_id( const char* id, - const char* args, FuriString* _Nullable error_message ) { FURI_LOG_I(TAG, "Start by id %s", id); @@ -197,7 +194,7 @@ static LoaderStatus loader_do_start_by_id( ); } - loader_start_app_with_manifest(manifest, args); + loader_start_app_with_manifest(manifest); return loader_make_success_status(error_message); } @@ -220,12 +217,7 @@ static void loader_do_stop_app() { } if (app->manifest->on_stop) { - app->manifest->on_stop(); - } - - if (loader->app_data.args) { - free(loader->app_data.args); - loader->app_data.args = NULL; + app->manifest->on_stop(&app->context); } furi_app_free(loader->app_data.app); @@ -268,7 +260,6 @@ static int32_t loader_main(void* p) { } message.status_value->value = loader_do_start_by_id( message.start.id, - message.start.args, message.start.error_message ); if (message.api_lock) { @@ -290,8 +281,8 @@ static int32_t loader_main(void* p) { // region AppManifest -static void loader_start(void* parameter) { - UNUSED(parameter); +static void loader_start(Context* context) { + UNUSED(context); furi_check(loader == NULL); loader = loader_alloc(); @@ -299,7 +290,8 @@ static void loader_start(void* parameter) { furi_thread_start(loader->thread); } -static void loader_stop() { +static void loader_stop(Context* context) { + UNUSED(context); furi_check(loader != NULL); LoaderMessage message = { .api_lock = NULL, diff --git a/components/tactility/src/services/loader/loader.h b/components/tactility/src/services/loader/loader.h index 75e914f8..4be0df0b 100644 --- a/components/tactility/src/services/loader/loader.h +++ b/components/tactility/src/services/loader/loader.h @@ -29,21 +29,19 @@ typedef struct { /** * @brief Close any running app, then start new one. Blocking. - * @param[in] loader loader instance * @param[in] id application name or id * @param[in] args application arguments * @param[out] error_message detailed error message, can be NULL * @return LoaderStatus */ -LoaderStatus loader_start_app(const char* id, const char* args, FuriString* error_message); +LoaderStatus loader_start_app(const char* id, FuriString* error_message); /** * @brief Close any running app, then start new one. Non-blocking. - * @param[in] loader loader instance * @param[in] id application name or id * @param[in] args application arguments */ -void loader_start_app_nonblocking(const char* id, const char* args); +void loader_start_app_nonblocking(const char* id); void loader_stop_app(); @@ -52,7 +50,6 @@ bool loader_is_app_running(); const AppManifest* _Nullable loader_get_current_app(); /** * @brief Start application with GUI error message - * @param[in] instance loader instance * @param[in] name application name or id * @param[in] args application arguments * @return LoaderStatus @@ -61,13 +58,11 @@ const AppManifest* _Nullable loader_get_current_app(); /** * @brief Show loader menu - * @param[in] instance loader instance */ void loader_show_menu(); /** * @brief Get loader pubsub - * @param[in] instance loader instance * @return FuriPubSub* */ FuriPubSub* loader_get_pubsub(); diff --git a/components/tactility/src/services/loader/loader_i.h b/components/tactility/src/services/loader/loader_i.h index 64b079f7..0fc5023d 100644 --- a/components/tactility/src/services/loader/loader_i.h +++ b/components/tactility/src/services/loader/loader_i.h @@ -11,7 +11,6 @@ #include "thread.h" typedef struct { - char* args; App* app; ViewPort* view_port; } LoaderAppData; @@ -32,7 +31,6 @@ typedef enum { typedef struct { const char* id; - const char* args; FuriString* error_message; } LoaderMessageAppStart; diff --git a/components/tactility/src/tactility.c b/components/tactility/src/tactility.c index 532fa1de..7948c6ad 100644 --- a/components/tactility/src/tactility.c +++ b/components/tactility/src/tactility.c @@ -1,15 +1,14 @@ +#include "tactility.h" + #include "app_manifest_registry.h" #include "devices_i.h" #include "furi.h" #include "graphics_i.h" #include "partitions.h" -#include "services/gui/gui.h" -#include "tactility.h" +#include "service_registry.h" #define TAG "tactility" -Gui* gui_alloc(); - // System services extern const ServiceManifest gui_service; extern const ServiceManifest loader_service; @@ -18,13 +17,6 @@ extern const ServiceManifest desktop_service; // System apps extern const AppManifest system_info_app; -void start_service(const ServiceManifest* _Nonnull manifest) { - FURI_LOG_I(TAG, "Starting service %s", manifest->id); - furi_check(manifest->on_start, "service must define on_start"); - manifest->on_start(NULL); - // TODO: keep track of running services -} - static void register_system_apps() { FURI_LOG_I(TAG, "Registering default apps"); app_manifest_registry_add(&system_info_app); @@ -43,12 +35,18 @@ static void register_user_apps(const Config* _Nonnull config) { } } +static void register_system_services() { + FURI_LOG_I(TAG, "Registering system services"); + service_registry_add(&gui_service); + service_registry_add(&loader_service); + service_registry_add(&desktop_service); +} + static void start_system_services() { FURI_LOG_I(TAG, "Starting system services"); - start_service(&gui_service); - start_service(&loader_service); - start_service(&desktop_service); - FURI_LOG_I(TAG, "System services started"); + service_registry_start(gui_service.id); + service_registry_start(loader_service.id); + service_registry_start(desktop_service.id); } static void start_user_services(const Config* _Nonnull config) { @@ -63,7 +61,6 @@ static void start_user_services(const Config* _Nonnull config) { break; } } - FURI_LOG_I(TAG, "User services started"); } __attribute__((unused)) extern void tactility_start(const Config* _Nonnull config) { @@ -75,6 +72,7 @@ __attribute__((unused)) extern void tactility_start(const Config* _Nonnull confi /*NbLvgl lvgl =*/tt_graphics_init(&hardware); // Register all apps + register_system_services(); register_system_apps(); register_user_apps(config); diff --git a/main/src/hello_world/hello_world.c b/main/src/hello_world/hello_world.c index c5f7015d..59d6c348 100644 --- a/main/src/hello_world/hello_world.c +++ b/main/src/hello_world/hello_world.c @@ -2,7 +2,7 @@ #include "services/gui/gui.h" #include "services/loader/loader.h" -static void app_show(lv_obj_t* parent, void* context) { +static void app_show(Context* context, lv_obj_t* parent) { UNUSED(context); lv_obj_t* label = lv_label_create(parent);