Last active
March 23, 2022 18:54
-
-
Save nullxx/8cef5ee2ea5473e04ad1674277904cea to your computer and use it in GitHub Desktop.
Pub-sub simple implementation in c. Notification events are triggered sequentially :(
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// pubsub.c | |
// mpp-cpu | |
// | |
// Created by https://github.com/nullxx on 22/3/22. | |
// | |
#include "pubsub.h" | |
#include <stdio.h> | |
#include <stdlib.h> | |
PubSubSubscription **subscriptions = NULL; | |
unsigned int subscription_count = 0; | |
PubSubSubscription *subscribe_to(PubSubTopic topic, on_message on_message_fn) { | |
PubSubSubscription *subscription = malloc(sizeof(PubSubSubscription)); | |
if (subscription == NULL) { | |
return NULL; | |
} | |
subscription->id = subscription_count++; // id is also the index inside subscriptions | |
subscription->topic = topic; | |
subscription->on_message_fn = on_message_fn; | |
// allocate for n subscriptions | |
subscriptions = realloc(subscriptions, sizeof(PubSubSubscription) * subscription_count); | |
subscriptions[subscription->id] = subscription; | |
return subscription; | |
} | |
bool unsubscribe_for(PubSubSubscription *sub) { | |
if (sub == NULL) return false; | |
if (sub->id >= subscription_count) { | |
return false; | |
} | |
free(sub); | |
sub = NULL; | |
subscriptions[sub_id] = NULL; | |
return true; | |
} | |
int publish_message_to(PubSubTopic topic, void *value) { | |
PubSubMessage message = { | |
.topic = topic, | |
.value = value | |
}; | |
int sent = 0; | |
// find the subs subscribed to this topic | |
for (int i = 0; i < subscription_count; i++) { | |
PubSubSubscription *sub = subscriptions[i]; | |
if (sub == NULL || sub->topic != topic) continue; | |
sub->on_message_fn(message); | |
sent++; | |
} | |
return sent; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// pubsub.h | |
// mpp-cpu | |
// | |
// Created by https://github.com/nullxx on 22/3/22. | |
// | |
#ifndef pubsub_h | |
#define pubsub_h | |
#include <stdbool.h> | |
typedef enum { | |
NONE_PUBSUB_TOPIC = 0, | |
DATA_BUS_TOPIC | |
} PubSubTopic; | |
typedef struct { | |
PubSubTopic topic; | |
void *value; | |
} PubSubMessage; | |
typedef void (*on_message)(PubSubMessage); | |
typedef struct { | |
unsigned int id; | |
PubSubTopic topic; | |
on_message on_message_fn; | |
} PubSubSubscription; | |
PubSubSubscription *subscribe_to(PubSubTopic topic, on_message on_message_fn); | |
bool unsubscribe_for(PubSubSubscription *sub); | |
int publish_message_to(PubSubTopic topic, void *value); | |
#endif /* pubsub_h */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// pubsubtest.c | |
// mpp-cpu | |
// | |
// Created by https://github.com/nullxx on 22/3/22. | |
// | |
#include <stdio.h> | |
#include "pubsub.h" | |
void on_message_fn(PubSubMessage message) { | |
printf("Message Topic: %d\n", message.topic); | |
printf("Message Value: %s\n", (char*)message.value); | |
} | |
int main(void) { | |
PubSubSubscription *sub = subscribe_to(DATA_BUS_TOPIC, &on_message_fn); | |
if (sub == NULL) { | |
printf("Error subscribing\n"); | |
exit(-1); | |
} | |
// publish a message | |
int published_to1 = publish_message_to(DATA_BUS_TOPIC, (void*) "Message"); | |
// unsubscribe from a topic | |
unsubscribe_for(sub); | |
// publishing a message again | |
int published_to2 = publish_message_to(DATA_BUS_TOPIC, (void*) "Message2"); | |
// ... and again | |
int published_to3 = publish_message_to(DATA_BUS_TOPIC, (void*) "Message3"); | |
printf("published_to1 %d\n", published_to1); // 1, received by on_message_fn | |
printf("published_to2 %d\n", published_to2); // 0, after unsubscribing, NOT received by on_message_fn | |
printf("published_to3 %d\n", published_to3); // ... same! | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment