value-expanders.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include "value-expanders.h"
  2. bool init_composer(ValueComposer* composer, void* value) {
  3. if(!init_mutex(&composer->value, value, 0)) return false;
  4. for(size_t i = 0; i < sizeof(composer->layers) / sizeof(composer->layers[0]); i++) {
  5. list_composer_cb_init(composer->layers[i]);
  6. }
  7. // mutex without name,
  8. // no attributes (unfortunatly robust mutex is not supported by FreeRTOS),
  9. // with dynamic memory allocation
  10. const osMutexAttr_t value_mutex_attr = {
  11. .name = NULL, .attr_bits = 0, .cb_mem = NULL, .cb_size = 0U};
  12. composer->mutex = osMutexNew(&value_mutex_attr);
  13. if(composer->mutex == NULL) return false;
  14. if(!init_event(&composer->request)) return false;
  15. return true;
  16. }
  17. bool delete_composer(ValueComposer* composer) {
  18. if(osMutexAcquire(composer->mutex, osWaitForever) == osOK) {
  19. bool result = true;
  20. result &= delete_mutex(&composer->value);
  21. for(size_t i = 0; i < sizeof(composer->layers) / sizeof(composer->layers[0]); i++) {
  22. list_composer_cb_clear(composer->layers[i]);
  23. }
  24. result &= osMutexDelete(composer->mutex) == osOK;
  25. return result;
  26. } else {
  27. return false;
  28. }
  29. }
  30. ValueComposerHandle*
  31. add_compose_layer(ValueComposer* composer, ValueComposerCallback cb, void* ctx, UiLayer layer) {
  32. if(osMutexAcquire(composer->mutex, osWaitForever) == osOK) {
  33. // put uninitialized item to the list
  34. ValueComposerHandle* handle = list_composer_cb_push_raw(composer->layers[layer]);
  35. handle->cb = cb;
  36. handle->ctx = ctx;
  37. handle->layer = layer;
  38. handle->composer = composer;
  39. // TODO unregister handle on app exit
  40. //flapp_on_exit(remove_compose_layer, handle);
  41. osMutexRelease(composer->mutex);
  42. // Layers changed, request composition
  43. signal_event(&composer->request);
  44. return handle;
  45. } else {
  46. return NULL;
  47. }
  48. }
  49. bool remove_compose_layer(ValueComposerHandle* handle) {
  50. ValueComposer* composer = handle->composer;
  51. if(osMutexAcquire(composer->mutex, osWaitForever) == osOK) {
  52. bool result = false;
  53. // iterate over items
  54. list_composer_cb_it_t it;
  55. for(list_composer_cb_it(it, composer->layers[handle->layer]); !list_composer_cb_end_p(it);
  56. list_composer_cb_next(it)) {
  57. const ValueComposerHandle* item = list_composer_cb_cref(it);
  58. // if the iterator is equal to our element
  59. if(item == handle) {
  60. list_composer_cb_remove(composer->layers[handle->layer], it);
  61. result = true;
  62. break;
  63. }
  64. }
  65. osMutexRelease(composer->mutex);
  66. // Layers changed, request composition
  67. signal_event(&composer->request);
  68. return result;
  69. } else {
  70. return false;
  71. }
  72. }
  73. void request_compose(ValueComposerHandle* handle) {
  74. ValueComposer* composer = handle->composer;
  75. signal_event(&composer->request);
  76. }
  77. void perform_compose(
  78. ValueComposer* composer,
  79. ValueComposerCallback start_cb,
  80. ValueComposerCallback end_cb,
  81. void* ctx) {
  82. if(!wait_event_with_timeout(&composer->request, 0)) return;
  83. void* state = acquire_mutex(&composer->value, 0);
  84. if(state == NULL) return;
  85. if(start_cb != NULL) start_cb(ctx, state);
  86. perform_compose_internal(composer, state);
  87. if(end_cb != NULL) end_cb(ctx, state);
  88. release_mutex(&composer->value, state);
  89. }
  90. void perform_compose_internal(ValueComposer* composer, void* state) {
  91. if(osMutexAcquire(composer->mutex, osWaitForever) == osOK) {
  92. // Compose all levels for now
  93. for(size_t i = 0; i < sizeof(composer->layers) / sizeof(composer->layers[0]); i++) {
  94. // iterate over items
  95. list_composer_cb_it_t it;
  96. for(list_composer_cb_it(it, composer->layers[i]); !list_composer_cb_end_p(it);
  97. list_composer_cb_next(it)) {
  98. const ValueComposerHandle* h = list_composer_cb_cref(it);
  99. h->cb(h->ctx, state);
  100. }
  101. }
  102. osMutexRelease(composer->mutex);
  103. }
  104. }
  105. void COPY_COMPOSE(void* ctx, void* state) {
  106. read_mutex((ValueMutex*)ctx, state, 0, osWaitForever);
  107. }
  108. bool init_managed(ValueManager* managed, void* value, size_t size) {
  109. if(!init_pubsub(&managed->pubsub)) return false;
  110. if(!init_mutex(&managed->value, value, size)) {
  111. delete_pubsub(&managed->pubsub);
  112. return false;
  113. }
  114. return true;
  115. }
  116. bool delete_managed(ValueManager* managed) {
  117. bool result = true;
  118. result &= delete_mutex(&managed->value);
  119. result &= delete_pubsub(&managed->pubsub);
  120. return result;
  121. }
  122. bool write_managed(ValueManager* managed, void* data, size_t len, uint32_t timeout) {
  123. void* value = acquire_mutex(&managed->value, timeout);
  124. if(value == NULL) return false;
  125. memcpy(value, data, len);
  126. notify_pubsub(&managed->pubsub, value);
  127. if(!release_mutex(&managed->value, value)) return false;
  128. return true;
  129. }
  130. bool commit_managed(ValueManager* managed, void* value) {
  131. if(value != managed->value.value) return false;
  132. notify_pubsub(&managed->pubsub, value);
  133. if(!release_mutex(&managed->value, value)) return false;
  134. return true;
  135. }