view_module_entity.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #include "view_module_entity.h"
  2. #include "src/engine/game_manager.h"
  3. #include "input_converter.h"
  4. #include "view_i.h" // IWYU pragma: keep
  5. typedef struct
  6. {
  7. const ViewModuleDescription* description;
  8. void* view_module;
  9. InputConverter* input_converter;
  10. ViewModuleBackCallback back_callback;
  11. void* back_callback_context;
  12. } ViewModuleContext;
  13. static void
  14. view_module_stop(Entity* self, GameManager* manager, void* _entity_context)
  15. {
  16. UNUSED(self);
  17. UNUSED(manager);
  18. ViewModuleContext* view_module_context = _entity_context;
  19. view_module_context->description->free(view_module_context->view_module);
  20. input_converter_free(view_module_context->input_converter);
  21. }
  22. static bool
  23. need_call_back_callback(ViewModuleContext* entity_context, InputEvent* event)
  24. {
  25. return event->key == InputKeyBack &&
  26. (event->type == InputTypeShort || event->type == InputTypeLong) &&
  27. entity_context->back_callback != NULL;
  28. }
  29. static void
  30. view_module_update(Entity* self, GameManager* manager, void* _entity_context)
  31. {
  32. UNUSED(self);
  33. ViewModuleContext* entity_context = _entity_context;
  34. InputState input = game_manager_input_get(manager);
  35. input_converter_process_state(entity_context->input_converter, &input);
  36. View* view =
  37. entity_context->description->get_view(entity_context->view_module);
  38. InputEvent event;
  39. while (input_converter_get_event(entity_context->input_converter, &event) ==
  40. FuriStatusOk) {
  41. if (need_call_back_callback(entity_context, &event)) {
  42. bool is_consumed = entity_context->back_callback(
  43. entity_context->back_callback_context);
  44. if (is_consumed) {
  45. continue;
  46. }
  47. }
  48. view->input_callback(&event, view->context);
  49. }
  50. }
  51. static void
  52. view_module_render(Entity* self,
  53. GameManager* manager,
  54. Canvas* canvas,
  55. void* _entity_context)
  56. {
  57. UNUSED(self);
  58. UNUSED(manager);
  59. ViewModuleContext* entity_context = _entity_context;
  60. View* view =
  61. entity_context->description->get_view(entity_context->view_module);
  62. view->draw_callback(canvas, view_get_model(view));
  63. }
  64. Entity*
  65. view_module_add_to_level(Level* level,
  66. GameManager* manager,
  67. const ViewModuleDescription* module_description)
  68. {
  69. UNUSED(manager);
  70. furi_check(module_description);
  71. // Alloc entity
  72. Entity* entity = level_add_entity(level, &view_module_description);
  73. // Alloc view module
  74. ViewModuleContext* view_module_context = entity_context_get(entity);
  75. view_module_context->description = module_description;
  76. view_module_context->view_module = module_description->alloc();
  77. // Alloc converter
  78. view_module_context->input_converter = input_converter_alloc();
  79. // Callback
  80. view_module_context->back_callback = NULL;
  81. view_module_context->back_callback_context = NULL;
  82. return entity;
  83. }
  84. void*
  85. view_module_get_module(Entity* entity)
  86. {
  87. ViewModuleContext* view_module_context = entity_context_get(entity);
  88. return view_module_context->view_module;
  89. }
  90. void
  91. view_module_set_back_callback(Entity* entity,
  92. ViewModuleBackCallback back_callback,
  93. void* context)
  94. {
  95. ViewModuleContext* view_module_context = entity_context_get(entity);
  96. view_module_context->back_callback = back_callback;
  97. view_module_context->back_callback_context = context;
  98. }
  99. const EntityDescription view_module_description = {
  100. .start = NULL,
  101. .stop = view_module_stop,
  102. .update = view_module_update,
  103. .render = view_module_render,
  104. .collision = NULL,
  105. .event = NULL,
  106. .context_size = sizeof(ViewModuleContext),
  107. };