app_context.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include <gui/modules/menu.h>
  2. #include <gui/modules/popup.h>
  3. #include "tone_gen.h"
  4. #include "app_context.h"
  5. /** custom event handler - passes the event to the scene manager */
  6. bool viewDispatcherCustomCallback(void* context, uint32_t custom_event) {
  7. furi_assert(context);
  8. struct AppContext_t* appContext = context;
  9. return scene_manager_handle_custom_event(appContext->scene_manager, custom_event);
  10. }
  11. /** navigation event handler - passes the event to the scene manager */
  12. bool viewDispatcherNavigationCallback(void* context) {
  13. furi_assert(context);
  14. struct AppContext_t* appContext = context;
  15. return scene_manager_handle_back_event(appContext->scene_manager);
  16. }
  17. AppContextStatus initializeAppContext(
  18. struct AppContext_t** context,
  19. int viewsCount,
  20. const SceneManagerHandlers* sceneManagerHandlers) {
  21. FURI_LOG_I(TAG, "Allocating memory for app context");
  22. *context = malloc(sizeof(struct AppContext_t));
  23. if(*context == NULL) {
  24. FURI_LOG_E(TAG, "Failed to allocate memory for app context");
  25. return APP_CONTEXT_CANT_ALLOCATE;
  26. }
  27. // Allocate our scene manager with the handlers provided
  28. FURI_LOG_I(TAG, "Setting up the scene manager");
  29. (*context)->scene_manager = scene_manager_alloc(sceneManagerHandlers, *context);
  30. // Now setup our view dispatchers
  31. FURI_LOG_I(TAG, "Setting up the view dispatcher");
  32. (*context)->view_dispatcher = view_dispatcher_alloc();
  33. view_dispatcher_enable_queue((*context)->view_dispatcher);
  34. FURI_LOG_I(TAG, "Setting view dispatcher callbacks");
  35. view_dispatcher_set_event_callback_context((*context)->view_dispatcher, (*context));
  36. FURI_LOG_I(TAG, "Setting view dispatcher custom event callbacks");
  37. view_dispatcher_set_custom_event_callback(
  38. (*context)->view_dispatcher, viewDispatcherCustomCallback);
  39. FURI_LOG_I(TAG, "Setting view dispatcher navigation event callbacks");
  40. view_dispatcher_set_navigation_event_callback(
  41. (*context)->view_dispatcher, viewDispatcherNavigationCallback);
  42. FURI_LOG_I(TAG, "Setting view dispatcher callbacks done");
  43. (*context)->activeViews = malloc(sizeof(struct View_t) * viewsCount);
  44. if((*context)->activeViews == NULL) {
  45. return APP_CONTEXT_CANT_ALLOCATE;
  46. }
  47. (*context)->activeViewsCount = viewsCount;
  48. return APP_CONTEXT_OK;
  49. }
  50. AppContextStatus addViewToAppContext(struct AppContext_t** context, struct View_t* view) {
  51. if(view->viewId > (*context)->activeViewsCount || view->viewId < 0) {
  52. FURI_LOG_I(TAG, "Not enough views!");
  53. return APP_CONTEXT_NOT_ENOUGH_VIEWS;
  54. }
  55. (*context)->activeViews[view->viewId] = view;
  56. return APP_CONTEXT_OK;
  57. }
  58. AppContextStatus freeAppContextViews(struct AppContext_t** context) {
  59. FURI_LOG_I(TAG, "Freeing views");
  60. for(int i = 0; i < (*context)->activeViewsCount; i++) {
  61. struct View_t* view = (*context)->activeViews[i];
  62. if(view != NULL) {
  63. view_dispatcher_remove_view((*context)->view_dispatcher, view->viewId);
  64. switch(view->type) {
  65. case MENU:
  66. menu_free(view->viewData);
  67. break;
  68. case VIEW:
  69. view_free(view->viewData);
  70. break;
  71. case POPUP:
  72. popup_free(view->viewData);
  73. break;
  74. }
  75. free(view);
  76. }
  77. }
  78. FURI_LOG_I(TAG, "Removing all views from list");
  79. free((*context)->activeViews);
  80. (*context)->activeViewsCount = 0;
  81. return APP_CONTEXT_OK;
  82. }
  83. AppContextStatus freeAppContext(struct AppContext_t** context) {
  84. FURI_LOG_I(TAG, "Ensuring views are free'd");
  85. AppContextStatus result = freeAppContextViews(context);
  86. if(result != APP_CONTEXT_OK) {
  87. return APP_CONTEXT_CANT_FREE_VIEWS;
  88. }
  89. FURI_LOG_I(TAG, "Freeing the scene");
  90. scene_manager_free((*context)->scene_manager);
  91. FURI_LOG_I(TAG, "Freeing the view dispatcher");
  92. view_dispatcher_free((*context)->view_dispatcher);
  93. FURI_LOG_I(TAG, "Freeing the app context");
  94. free((*context));
  95. return APP_CONTEXT_OK;
  96. }