sandbox.c 2.9 KB

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