app_state.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include "app_state.h"
  2. #include "longwave_clock_app.h"
  3. static LWCScene protocol_scene[] = {LWCDCF77Scene, LWCMSFScene};
  4. App* app_alloc() {
  5. App* app = malloc(sizeof(App));
  6. app->scene_manager = scene_manager_alloc(&lwc_scene_manager_handlers, app);
  7. app->view_dispatcher = view_dispatcher_alloc();
  8. view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
  9. view_dispatcher_set_custom_event_callback(app->view_dispatcher, lwc_custom_callback);
  10. view_dispatcher_set_navigation_event_callback(app->view_dispatcher, lwc_back_event_callback);
  11. view_dispatcher_set_tick_event_callback(
  12. app->view_dispatcher, lwc_tick_event_callback, furi_ms_to_ticks(100));
  13. app->main_menu = submenu_alloc();
  14. app->sub_menu = variable_item_list_alloc();
  15. app->about = text_box_alloc();
  16. app->info_text = text_box_alloc();
  17. app->dcf77_view = lwc_dcf77_scene_alloc();
  18. app->msf_view = lwc_msf_scene_alloc();
  19. app->notifications = furi_record_open(RECORD_NOTIFICATION);
  20. view_dispatcher_add_view(
  21. app->view_dispatcher, LWCMainMenuView, submenu_get_view(app->main_menu));
  22. view_dispatcher_add_view(
  23. app->view_dispatcher, LWCSubMenuView, variable_item_list_get_view(app->sub_menu));
  24. view_dispatcher_add_view(app->view_dispatcher, LWCAboutView, text_box_get_view(app->about));
  25. view_dispatcher_add_view(app->view_dispatcher, LWCInfoView, text_box_get_view(app->info_text));
  26. view_dispatcher_add_view(app->view_dispatcher, LWCDCF77View, app->dcf77_view);
  27. view_dispatcher_add_view(app->view_dispatcher, LWCMSFView, app->msf_view);
  28. return app;
  29. }
  30. AppState* app_state_alloc() {
  31. AppState* state = malloc(sizeof(AppState));
  32. state->storage = furi_record_open(RECORD_STORAGE);
  33. for(uint8_t i = 0; i < __lwc_number_of_protocols; i++) {
  34. state->proto_configs[i] = malloc(sizeof(ProtoConfig));
  35. File* file = storage_file_alloc(state->storage);
  36. bool read = false;
  37. if(storage_file_open(
  38. file, get_protocol_config_filename((LWCType)i), FSAM_READ, FSOM_OPEN_EXISTING)) {
  39. read = storage_file_read(file, state->proto_configs[i], sizeof(ProtoConfig)) ==
  40. sizeof(ProtoConfig);
  41. }
  42. if(!read) {
  43. state->proto_configs[i]->run_mode = Demo;
  44. state->proto_configs[i]->data_pin = GPIOPinC0;
  45. state->proto_configs[i]->data_mode = Regular;
  46. }
  47. storage_file_close(file);
  48. storage_file_free(file);
  49. }
  50. state->display_on = false;
  51. state->gpio = NULL;
  52. return state;
  53. }
  54. void store_proto_config(AppState* app_state) {
  55. File* file = storage_file_alloc(app_state->storage);
  56. if(storage_file_open(
  57. file,
  58. get_protocol_config_filename(app_state->lwc_type),
  59. FSAM_WRITE,
  60. FSOM_CREATE_ALWAYS)) {
  61. if(!storage_file_write(
  62. file, app_state->proto_configs[app_state->lwc_type], sizeof(ProtoConfig))) {
  63. FURI_LOG_E(TAG, "Failed to write to open proto config file.");
  64. }
  65. } else {
  66. FURI_LOG_E(TAG, "Failed to open proto config file for writing.");
  67. }
  68. storage_file_close(file);
  69. storage_file_free(file);
  70. }
  71. void app_init_lwc(App* app, LWCType type) {
  72. app->state->lwc_type = type;
  73. }
  74. void app_quit(App* app) {
  75. scene_manager_stop(app->scene_manager);
  76. }
  77. void app_free(App* app) {
  78. furi_assert(app);
  79. FURI_LOG_D(TAG, "Removing the view dispatcher views.");
  80. view_dispatcher_remove_view(app->view_dispatcher, LWCMainMenuView);
  81. view_dispatcher_remove_view(app->view_dispatcher, LWCSubMenuView);
  82. view_dispatcher_remove_view(app->view_dispatcher, LWCAboutView);
  83. view_dispatcher_remove_view(app->view_dispatcher, LWCInfoView);
  84. view_dispatcher_remove_view(app->view_dispatcher, LWCDCF77View);
  85. view_dispatcher_remove_view(app->view_dispatcher, LWCMSFView);
  86. FURI_LOG_D(TAG, "Removing the scene manager and view dispatcher.");
  87. scene_manager_free(app->scene_manager);
  88. view_dispatcher_free(app->view_dispatcher);
  89. FURI_LOG_D(TAG, "Removing the single scenes...");
  90. submenu_free(app->main_menu);
  91. variable_item_list_free(app->sub_menu);
  92. text_box_free(app->about);
  93. text_box_free(app->info_text);
  94. FURI_LOG_D(TAG, "Removing the DCF77 scene...");
  95. lwc_dcf77_scene_free(app->dcf77_view);
  96. FURI_LOG_D(TAG, "Removing the MSF scene...");
  97. lwc_msf_scene_free(app->msf_view);
  98. FURI_LOG_D(TAG, "Desubscribing from notification...");
  99. furi_record_close(RECORD_NOTIFICATION);
  100. FURI_LOG_D(TAG, "Removing the protocol configs.");
  101. for(uint8_t i = 0; i < __lwc_number_of_protocols; i++) {
  102. free(app->state->proto_configs[i]);
  103. }
  104. furi_record_close(RECORD_STORAGE);
  105. FURI_LOG_D(TAG, "Removing the AppState*.");
  106. free(app->state);
  107. FURI_LOG_D(TAG, "Freeing the App*...");
  108. free(app);
  109. }
  110. ProtoConfig* lwc_get_protocol_config(AppState* app_state) {
  111. return app_state->proto_configs[app_state->lwc_type];
  112. }
  113. LWCScene lwc_get_start_scene_for_protocol(AppState* app_state) {
  114. return protocol_scene[app_state->lwc_type];
  115. }