value-expanders.c 5.0 KB

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