this is a little theoretical question. Imagine a device full of sensors. Now, in case a sensor x detects something, something should happen. Meanwhile, in case something else is detected, like two sensors detects two different things, then, this device must behave differently.
From webdesign (so javascript) I learned about Events, for example (using jquery) $(".x").on("click", function(){})
or from angularjs $scope.watch("name_of_var", function())
.
Is there any possibility to replicate this behaviour in C, without using complex libraries?
Thanks.
A system I can think about is a subscriber-notifier model.
You may have something that handles your sensors (for example, a thread that polls on it to see if something happened). When it detects something, the task should raise a mechanism in order to let the outer world be aware : this is the notification process.
On the other side, only the people who are interested in your sensor should be notified, thus, a subscription method should be here to take care of this.
Now, the hard part comes in. When the sensor handler notifies the world, it must NOT spend too much time doing so otherwise it might miss other events. Thus, it is compulsory to have a task (or thread) dedicated to the notifying process. On the other hand, the subscribers wish to have some of their data updated when such a notified event is received. This is obviously an asynchronous process and thus the subscribers will have to supply the notifier thread with a callback.
Finally, you should mark your events with timestamps, this way the receivers will know if the event they get is outdated and wether or not they should discard it.
The final thing may look like the piece of code below :
/*
* Some data structures to begin with
*/
struct event;
struct notifier;
struct subscription;
struct notify_sched;
typedef int (*notify_cbck)(struct event *evt, void *private);
/*
*@type : a value to show the type of event
*@t : the timestamp of the event
*@value : a pointer towards the event data
*/
struct event {
int type;
struct timeval t; // the timestamp
void *value;
};
/*
* @type : the type in which the subscriber is interested
* @cb : the callback that should be run when an event occur
* @cb_data : the data to provide to the callback
* @next,prev : doubly-linked list
*/
struct subscription {
int type;
notify_cbck cb;
void *cb_data;
struct subscription *next, *prev;
};
/*
* This structure gathers the subscriptions of a given type.
* @type : the event type
* @subs : the subscription list
* @mutex : a mutex to protect the list while inserting/removing subscriptions
* @next,prev : link to other typed subscriptions
*/
struct typed_subscription {
int type;
struct subscription *subs;
mutex_t mutex;
struct typed_subscription *next, *prev;
};
/*
* @magic : the ID of the event producer
* @t_subs : the typed_subscription list
* @mutex : a mutex to protect data when (un)registering new types to the producer
* @next, prev : doubly-linked list ...
*/
struct notifier {
int magic;
struct typed_subscription *t_subs;
mutex_t mutex;
struct notifier *next, *prev;
};
/*
* @ntf : the notifiers list
* @mutex : a mutex to protect the ntf list
* @th : something to identify the task that hosts the scheduler
*/
struct notify_sched {
struct notifier *ntf;
mutex_t mutex;
pthread_t th; // I assume it's a classic pthread in this example.
};
I do not have the time to complete my answer right now, I will edit it later to give you the full example. But starting from the data structures, you should get some ideas. Hope this is a bit helpful anyhow.