#pragma once #include "cmsis_os.h" #include "m-list.h" #ifdef __cplusplus extern "C" { #endif /** == PubSub == * PubSub allows users to subscribe on notifies and notify subscribers. * Notifier side can pass `void*` arg to subscriber callback, * and also subscriber can set `void*` context pointer that pass into * callback (you can see callback signature below). */ typedef void (*PubSubCallback)(const void*, void*); typedef struct PubSubType PubSub; typedef struct { PubSubCallback cb; void* ctx; PubSub* self; } PubSubItem; LIST_DEF(list_pubsub_cb, PubSubItem, M_POD_OPLIST); struct PubSubType { list_pubsub_cb_t items; osMutexId_t mutex; }; /** * To create PubSub you should create PubSub instance and call `init_pubsub`. */ bool init_pubsub(PubSub* pubsub); /** * Since we use dynamic memory - we must explicity delete pubsub */ bool delete_pubsub(PubSub* pubsub); /** * Use `subscribe_pubsub` to register your callback. */ PubSubItem* subscribe_pubsub(PubSub* pubsub, PubSubCallback cb, void* ctx); /** * Use `unsubscribe_pubsub` to unregister callback. */ bool unsubscribe_pubsub(PubSubItem* pubsub_id); /** * Use `notify_pubsub` to notify subscribers. */ bool notify_pubsub(PubSub* pubsub, void* arg); #ifdef __cplusplus } #endif /* ```C // MANIFEST // name="test" // stack=128 void example_pubsub_handler(void* arg, void* ctx) { printf("get %d from %s\n", *(uint32_t*)arg, (const char*)ctx); } void pubsub_test() { const char* app_name = "test app"; PubSub example_pubsub; init_pubsub(&example_pubsub); if(!subscribe_pubsub(&example_pubsub, example_pubsub_handler, (void*)app_name)) { printf("critical error\n"); flapp_exit(NULL); } uint32_t counter = 0; while(1) { notify_pubsub(&example_pubsub, (void*)&counter); counter++; osDelay(100); } } ``` */