sandbox.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include <furi.h>
  2. #include <gui/gui.h>
  3. #include "sandbox.h"
  4. FuriMessageQueue* sandbox_event_queue;
  5. FuriMutex** sandbox_mutex;
  6. ViewPort* sandbox_view_port;
  7. Gui* sandbox_gui;
  8. FuriTimer* sandbox_timer;
  9. bool sandbox_loop_processing;
  10. SandboxRenderCallback sandbox_user_render_callback;
  11. SandboxEventHandler sandbox_user_event_handler;
  12. static void sandbox_render_callback(Canvas* const canvas, void* context) {
  13. UNUSED(context);
  14. if (furi_mutex_acquire(sandbox_mutex, 25) != FuriStatusOk)
  15. return;
  16. if (sandbox_user_render_callback)
  17. sandbox_user_render_callback(canvas);
  18. furi_mutex_release(sandbox_mutex);
  19. }
  20. static void sandbox_input_callback(InputEvent* input_event, void* context) {
  21. UNUSED(context);
  22. GameEvent event = {.type = EventTypeKey, .input = *input_event};
  23. furi_message_queue_put(sandbox_event_queue, &event, FuriWaitForever);
  24. }
  25. static void sandbox_timer_callback(void* context ) {
  26. UNUSED(context);
  27. GameEvent event = {.type = EventTypeTick};
  28. furi_message_queue_put(sandbox_event_queue, &event, 0);
  29. }
  30. void sandbox_loop() {
  31. sandbox_loop_processing = true;
  32. while( sandbox_loop_processing ) {
  33. GameEvent event;
  34. FuriStatus event_status = furi_message_queue_get(sandbox_event_queue, &event, 100);
  35. if (event_status != FuriStatusOk) {
  36. // timeout
  37. continue;
  38. }
  39. furi_mutex_acquire(sandbox_mutex, FuriWaitForever);
  40. if (sandbox_user_event_handler)
  41. sandbox_user_event_handler(event);
  42. view_port_update(sandbox_view_port);
  43. furi_mutex_release(sandbox_mutex);
  44. }
  45. }
  46. void sandbox_loop_exit() {
  47. sandbox_loop_processing = false;
  48. }
  49. void sandbox_init(uint8_t fps, SandboxRenderCallback u_render_callback, SandboxEventHandler u_event_handler)
  50. {
  51. sandbox_user_render_callback = u_render_callback;
  52. sandbox_user_event_handler = u_event_handler;
  53. sandbox_event_queue = furi_message_queue_alloc(8, sizeof(GameEvent));
  54. sandbox_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
  55. sandbox_view_port = view_port_alloc();
  56. view_port_draw_callback_set(sandbox_view_port, sandbox_render_callback, NULL);
  57. view_port_input_callback_set(sandbox_view_port, sandbox_input_callback, NULL);
  58. sandbox_gui = furi_record_open(RECORD_GUI);
  59. gui_add_view_port(sandbox_gui, sandbox_view_port, GuiLayerFullscreen);
  60. if (fps > 0) {
  61. sandbox_timer = furi_timer_alloc(sandbox_timer_callback, FuriTimerTypePeriodic, NULL);
  62. furi_timer_start(sandbox_timer, furi_kernel_get_tick_frequency() / fps);
  63. } else
  64. sandbox_timer = NULL;
  65. }
  66. void sandbox_free()
  67. {
  68. if (sandbox_timer)
  69. furi_timer_free(sandbox_timer);
  70. gui_remove_view_port(sandbox_gui, sandbox_view_port);
  71. view_port_enabled_set(sandbox_view_port, false);
  72. view_port_free(sandbox_view_port);
  73. if(furi_mutex_acquire(sandbox_mutex, FuriWaitForever) == FuriStatusOk) {
  74. furi_mutex_free(sandbox_mutex);
  75. }
  76. furi_message_queue_free(sandbox_event_queue);
  77. }