|
@@ -0,0 +1,101 @@
|
|
|
|
|
+#include "../main.h"
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * SceneManagerHandlers initialization using the macro.
|
|
|
|
|
+ */
|
|
|
|
|
+void (*const scene_on_enter_handlers[])(void* context) = {
|
|
|
|
|
+#define SCENE_ACTION(scene) scene##_on_enter,
|
|
|
|
|
+#include "list.h"
|
|
|
|
|
+#undef SCENE_ACTION
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+bool (*const scene_on_event_handlers[])(void* context, SceneManagerEvent event) = {
|
|
|
|
|
+#define SCENE_ACTION(scene) scene##_on_event,
|
|
|
|
|
+#include "list.h"
|
|
|
|
|
+#undef SCENE_ACTION
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+void (*const scene_on_exit_handlers[])(void* context) = {
|
|
|
|
|
+#define SCENE_ACTION(scene) scene##_on_exit,
|
|
|
|
|
+#include "list.h"
|
|
|
|
|
+#undef SCENE_ACTION
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const SceneManagerHandlers scene_handlers = {
|
|
|
|
|
+ .on_enter_handlers = scene_on_enter_handlers,
|
|
|
|
|
+ .on_event_handlers = scene_on_event_handlers,
|
|
|
|
|
+ .on_exit_handlers = scene_on_exit_handlers,
|
|
|
|
|
+ .scene_num = AppSceneNum,
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * Register all scenes.
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+void register_scenes(App* app) {
|
|
|
|
|
+ app->scene_manager = scene_manager_alloc(&scene_handlers, app);
|
|
|
|
|
+ furi_assert(app->scene_manager != NULL, "Failed to allocate scene manager.");
|
|
|
|
|
+
|
|
|
|
|
+ app->view_dispatcher = view_dispatcher_alloc();
|
|
|
|
|
+ furi_assert(app->view_dispatcher != NULL, "Failed to allocate view dispatcher.");
|
|
|
|
|
+
|
|
|
|
|
+ if(app->allocated_scenes == NULL) {
|
|
|
|
|
+ app->allocated_scenes = (void**)malloc(sizeof(void*) * AppSceneNum);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ view_dispatcher_enable_queue(app->view_dispatcher);
|
|
|
|
|
+
|
|
|
|
|
+ view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
|
|
|
|
|
+ view_dispatcher_set_custom_event_callback(app->view_dispatcher, scene_handler_event_forwarder);
|
|
|
|
|
+ view_dispatcher_set_navigation_event_callback(
|
|
|
|
|
+ app->view_dispatcher, scene_handler_navigation_forwarder);
|
|
|
|
|
+
|
|
|
|
|
+ View* view = NULL;
|
|
|
|
|
+#define SCENE_ACTION(scene) \
|
|
|
|
|
+ app->allocated_scenes[scene] = (void*)scene##_alloc(); \
|
|
|
|
|
+ furi_assert( \
|
|
|
|
|
+ app->allocated_scenes[scene] != NULL, "Failed to allocate scene: " STRINGIFY(scene)); \
|
|
|
|
|
+ view = scene##_get_view(app->allocated_scenes[scene]); \
|
|
|
|
|
+ furi_assert(view != NULL, "Failed to get view for scene: " STRINGIFY(scene)); \
|
|
|
|
|
+ view_dispatcher_add_view(app->view_dispatcher, scene, view);
|
|
|
|
|
+#include "list.h"
|
|
|
|
|
+#undef SCENE_ACTION
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * Free all scenes.
|
|
|
|
|
+ */
|
|
|
|
|
+void free_scenes(App* app) {
|
|
|
|
|
+ FURI_LOG_I("DemoApp", "Freeing scenes.");
|
|
|
|
|
+ furi_assert(app != NULL, "App is NULL.");
|
|
|
|
|
+ void* tmp;
|
|
|
|
|
+#define SCENE_ACTION(scene) \
|
|
|
|
|
+ if(app->allocated_scenes != NULL) { \
|
|
|
|
|
+ tmp = app->allocated_scenes[scene]; \
|
|
|
|
|
+ app->allocated_scenes[scene] = NULL; \
|
|
|
|
|
+ FURI_LOG_I("DemoApp", "Freeing scene " STRINGIFY(scene) "."); \
|
|
|
|
|
+ if(tmp != NULL) scene##_free(tmp); \
|
|
|
|
|
+ FURI_LOG_I("DemoApp", "Free'd scene " STRINGIFY(scene) "."); \
|
|
|
|
|
+ } \
|
|
|
|
|
+ if(app->view_dispatcher != NULL) view_dispatcher_remove_view(app->view_dispatcher, scene); \
|
|
|
|
|
+ FURI_LOG_I("DemoApp", "Removed from dispatcher " STRINGIFY(scene) ".");
|
|
|
|
|
+
|
|
|
|
|
+#include "list.h"
|
|
|
|
|
+#undef SCENE_ACTION
|
|
|
|
|
+
|
|
|
|
|
+ FURI_LOG_I("DemoApp", "Freeing allocated scenes.");
|
|
|
|
|
+ furi_assert(app->allocated_scenes != NULL, "Allocated scenes is NULL.");
|
|
|
|
|
+ free(app->allocated_scenes);
|
|
|
|
|
+ app->allocated_scenes = NULL;
|
|
|
|
|
+
|
|
|
|
|
+ FURI_LOG_I("DemoApp", "Freeing View dispatcher.");
|
|
|
|
|
+ furi_assert(app->view_dispatcher != NULL, "View dispatcher is NULL.");
|
|
|
|
|
+ view_dispatcher_free(app->view_dispatcher);
|
|
|
|
|
+
|
|
|
|
|
+ FURI_LOG_I("DemoApp", "Freeing SceneManager");
|
|
|
|
|
+ furi_assert(app->scene_manager != NULL, "Scene manager is NULL.");
|
|
|
|
|
+ scene_manager_free(app->scene_manager);
|
|
|
|
|
+
|
|
|
|
|
+ FURI_LOG_I("DemoApp", "Freeing App");
|
|
|
|
|
+ free(app);
|
|
|
|
|
+}
|