pubsub.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include "pubsub.h"
  2. #include <furi.h>
  3. bool init_pubsub(PubSub* pubsub) {
  4. // mutex without name,
  5. // no attributes (unfortunatly robust mutex is not supported by FreeRTOS),
  6. // with dynamic memory allocation
  7. pubsub->mutex = osMutexNew(NULL);
  8. if(pubsub->mutex == NULL) return false;
  9. // construct list
  10. list_pubsub_cb_init(pubsub->items);
  11. return true;
  12. }
  13. bool delete_pubsub(PubSub* pubsub) {
  14. if(osMutexAcquire(pubsub->mutex, osWaitForever) == osOK) {
  15. bool result = osMutexDelete(pubsub->mutex) == osOK;
  16. list_pubsub_cb_clear(pubsub->items);
  17. return result;
  18. } else {
  19. return false;
  20. }
  21. }
  22. PubSubItem* subscribe_pubsub(PubSub* pubsub, PubSubCallback cb, void* ctx) {
  23. if(osMutexAcquire(pubsub->mutex, osWaitForever) == osOK) {
  24. // put uninitialized item to the list
  25. PubSubItem* item = list_pubsub_cb_push_raw(pubsub->items);
  26. // initialize item
  27. item->cb = cb;
  28. item->ctx = ctx;
  29. item->self = pubsub;
  30. // TODO unsubscribe pubsub on app exit
  31. //flapp_on_exit(unsubscribe_pubsub, item);
  32. osMutexRelease(pubsub->mutex);
  33. return item;
  34. } else {
  35. return NULL;
  36. }
  37. }
  38. bool unsubscribe_pubsub(PubSubItem* pubsub_id) {
  39. if(osMutexAcquire(pubsub_id->self->mutex, osWaitForever) == osOK) {
  40. bool result = false;
  41. // iterate over items
  42. list_pubsub_cb_it_t it;
  43. for(list_pubsub_cb_it(it, pubsub_id->self->items); !list_pubsub_cb_end_p(it);
  44. list_pubsub_cb_next(it)) {
  45. const PubSubItem* item = list_pubsub_cb_cref(it);
  46. // if the iterator is equal to our element
  47. if(item == pubsub_id) {
  48. list_pubsub_cb_remove(pubsub_id->self->items, it);
  49. result = true;
  50. break;
  51. }
  52. }
  53. osMutexRelease(pubsub_id->self->mutex);
  54. return result;
  55. } else {
  56. return false;
  57. }
  58. }
  59. bool notify_pubsub(PubSub* pubsub, void* arg) {
  60. if(osMutexAcquire(pubsub->mutex, osWaitForever) == osOK) {
  61. // iterate over subscribers
  62. list_pubsub_cb_it_t it;
  63. for(list_pubsub_cb_it(it, pubsub->items); !list_pubsub_cb_end_p(it);
  64. list_pubsub_cb_next(it)) {
  65. const PubSubItem* item = list_pubsub_cb_cref(it);
  66. item->cb(arg, item->ctx);
  67. }
  68. osMutexRelease(pubsub->mutex);
  69. return true;
  70. } else {
  71. return false;
  72. }
  73. }