furi_value_expanders_test.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #include "flipper_v2.h"
  2. #include "minunit.h"
  3. #include <stdint.h>
  4. typedef struct {
  5. uint8_t red;
  6. uint8_t green;
  7. uint8_t blue;
  8. } Rgb;
  9. static uint32_t rgb_final_state;
  10. static void rgb_clear(void* ctx, void* state) {
  11. Rgb* rgb = state;
  12. rgb->red = 0;
  13. rgb->green = 0;
  14. rgb->blue = 0;
  15. }
  16. static void rgb_commit(void* ctx, void* state) {
  17. Rgb* rgb = state;
  18. rgb_final_state = ((uint32_t)rgb->red) | (((uint32_t)rgb->green) << 8) |
  19. (((uint32_t)rgb->blue) << 16);
  20. }
  21. static void set_red_composer(void* ctx, void* state) {
  22. Rgb* rgb = state;
  23. uint8_t* red = ctx;
  24. rgb->red = *red;
  25. }
  26. void test_furi_value_composer() {
  27. Rgb rgb = {0, 0, 0};
  28. ValueComposer composer;
  29. Rgb layer1_rgb = {0, 0, 0};
  30. ValueMutex layer1_mutex;
  31. uint8_t layer2_red = 0;
  32. rgb_final_state = 0xdeadbeef;
  33. mu_check(init_composer(&composer, &rgb));
  34. mu_check(init_mutex(&layer1_mutex, &layer1_rgb, sizeof(layer1_rgb)));
  35. perform_compose(&composer, rgb_clear, rgb_commit, NULL);
  36. mu_assert_int_eq(0xdeadbeef, rgb_final_state);
  37. ValueComposerHandle* layer1_handle =
  38. add_compose_layer(&composer, COPY_COMPOSE, &layer1_mutex, UiLayerNotify);
  39. mu_assert_pointers_not_eq(layer1_handle, NULL);
  40. // RGB state should be updated with the layer1 state
  41. perform_compose(&composer, rgb_clear, rgb_commit, NULL);
  42. mu_assert_int_eq(0x000000, rgb_final_state);
  43. layer2_red = 0xcc;
  44. ValueComposerHandle* layer2_handle =
  45. add_compose_layer(&composer, set_red_composer, &layer2_red, UiLayerAboveNotify);
  46. mu_assert_pointers_not_eq(layer2_handle, NULL);
  47. // RGB state should be updated with the layer1 and layer2 state, in order
  48. perform_compose(&composer, rgb_clear, rgb_commit, NULL);
  49. mu_assert_int_eq(0x0000cc, rgb_final_state);
  50. // Change layer1 state
  51. Rgb* state = acquire_mutex(&layer1_mutex, 0);
  52. mu_assert_pointers_not_eq(state, NULL);
  53. state->red = 0x12;
  54. state->green = 0x34;
  55. state->blue = 0x56;
  56. release_mutex(&layer1_mutex, state);
  57. // Nothing should happen, we need to trigger composition request first
  58. perform_compose(&composer, rgb_clear, rgb_commit, NULL);
  59. mu_assert_int_eq(0x0000cc, rgb_final_state);
  60. request_compose(layer1_handle);
  61. perform_compose(&composer, rgb_clear, rgb_commit, NULL);
  62. mu_assert_int_eq(0x5634cc, rgb_final_state);
  63. // Change layer2 state
  64. layer2_red = 0xff;
  65. // Nothing should happen, we need to trigger composition request first
  66. perform_compose(&composer, rgb_clear, rgb_commit, NULL);
  67. mu_assert_int_eq(0x5634cc, rgb_final_state);
  68. request_compose(layer2_handle);
  69. perform_compose(&composer, rgb_clear, rgb_commit, NULL);
  70. mu_assert_int_eq(0x5634ff, rgb_final_state);
  71. // Remove layer1
  72. mu_check(remove_compose_layer(layer1_handle));
  73. perform_compose(&composer, rgb_clear, rgb_commit, NULL);
  74. mu_assert_int_eq(0x0000ff, rgb_final_state);
  75. // Remove layer2
  76. mu_check(remove_compose_layer(layer2_handle));
  77. perform_compose(&composer, rgb_clear, rgb_commit, NULL);
  78. mu_assert_int_eq(0x000000, rgb_final_state);
  79. mu_check(delete_composer(&composer));
  80. }
  81. static const uint32_t notify_value_0 = 0x12345678;
  82. static const uint32_t notify_value_1 = 0x11223344;
  83. static uint32_t pubsub_value = 0;
  84. void test_value_manager_handler(const void* arg, void* ctx) {
  85. pubsub_value = *(uint32_t*)arg;
  86. }
  87. void test_furi_value_manager() {
  88. uint32_t value = 0;
  89. ValueManager managed;
  90. mu_check(init_managed(&managed, &value, sizeof(value)));
  91. pubsub_value = 0;
  92. PubSubItem* test_pubsub_item;
  93. test_pubsub_item = subscribe_pubsub(&managed.pubsub, test_value_manager_handler, 0);
  94. mu_assert_pointers_not_eq(test_pubsub_item, NULL);
  95. mu_check(write_managed(&managed, (void*)&notify_value_0, sizeof(notify_value_0), 100));
  96. mu_assert_int_eq(pubsub_value, notify_value_0);
  97. uint32_t* ptr = acquire_mutex(&managed.value, 100);
  98. mu_assert_pointers_not_eq(ptr, NULL);
  99. *ptr = notify_value_1;
  100. mu_check(commit_managed(&managed, ptr));
  101. mu_assert_int_eq(pubsub_value, notify_value_1);
  102. mu_check(delete_managed(&managed));
  103. }