pubsub.h 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #pragma once
  2. #include "cmsis_os.h"
  3. #include "m-list.h"
  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif
  7. /**
  8. == PubSub ==
  9. * PubSub allows users to subscribe on notifies and notify subscribers.
  10. * Notifier side can pass `void*` arg to subscriber callback,
  11. * and also subscriber can set `void*` context pointer that pass into
  12. * callback (you can see callback signature below).
  13. */
  14. typedef void (*PubSubCallback)(const void*, void*);
  15. typedef struct PubSubType PubSub;
  16. typedef struct {
  17. PubSubCallback cb;
  18. void* ctx;
  19. PubSub* self;
  20. } PubSubItem;
  21. LIST_DEF(list_pubsub_cb, PubSubItem, M_POD_OPLIST);
  22. struct PubSubType {
  23. list_pubsub_cb_t items;
  24. osMutexId_t mutex;
  25. };
  26. /**
  27. * To create PubSub you should create PubSub instance and call `init_pubsub`.
  28. */
  29. bool init_pubsub(PubSub* pubsub);
  30. /**
  31. * Since we use dynamic memory - we must explicity delete pubsub
  32. */
  33. bool delete_pubsub(PubSub* pubsub);
  34. /**
  35. * Use `subscribe_pubsub` to register your callback.
  36. */
  37. PubSubItem* subscribe_pubsub(PubSub* pubsub, PubSubCallback cb, void* ctx);
  38. /**
  39. * Use `unsubscribe_pubsub` to unregister callback.
  40. */
  41. bool unsubscribe_pubsub(PubSubItem* pubsub_id);
  42. /**
  43. * Use `notify_pubsub` to notify subscribers.
  44. */
  45. bool notify_pubsub(PubSub* pubsub, void* arg);
  46. #ifdef __cplusplus
  47. }
  48. #endif
  49. /*
  50. ```C
  51. // MANIFEST
  52. // name="test"
  53. // stack=128
  54. void example_pubsub_handler(void* arg, void* ctx) {
  55. printf("get %d from %s\n", *(uint32_t*)arg, (const char*)ctx);
  56. }
  57. void pubsub_test() {
  58. const char* app_name = "test app";
  59. PubSub example_pubsub;
  60. init_pubsub(&example_pubsub);
  61. if(!subscribe_pubsub(&example_pubsub, example_pubsub_handler, (void*)app_name)) {
  62. printf("critical error\n");
  63. flapp_exit(NULL);
  64. }
  65. uint32_t counter = 0;
  66. while(1) {
  67. notify_pubsub(&example_pubsub, (void*)&counter);
  68. counter++;
  69. osDelay(100);
  70. }
  71. }
  72. ```
  73. */