flipperzero-firmware/core/api-basic/pubsub.h
Vadim Kaushan bb68fca20b
Implement ValueManager and ValueComposer (#183)
* Fix ValueManager implementation
* Implement ValueComposer
* Add constructor for ValueManager
* Add value-expanders.h to flipper_v2.h set
* Move COPY_COMPOSE body into a .c file
* Add test for ValueManager
* Add destructors for ValueMutex, ValueManager and ValueComposer
* Use destructors in tests
* Move composition logic into perform_compose()
* Add docs for perform_compose()
* Add test for ValueComposer
* Replace atomic_bool with bool as g++ compiler doesn't support C11 atomics
* Add Event type
* Add semaphore support to the local target
* Add test for Event
* Update input records and relevant examples
* Rename Event to AppEvent in the cc1101-workaround example
* Rename Event to AppEvent in the irda example
* Use Event in ValueComposer to wait for update request
* Add perform_compose_internal() function
* fix Event/AppEvent

Co-authored-by: aanper <mail@s3f.ru>
2020-10-26 12:26:15 +03:00

87 lines
1.7 KiB
C

#pragma once
#include "cmsis_os.h"
#include "m-list.h"
/*
== 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)(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);
/*
```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);
}
}
```
*/