Skip to content

Commit 66a4f6b

Browse files
committed
Add ability to subscribe to service events
Each service can subscribe to one or more events from other services, the only knowledge needed is the service name and event name which can be taken fron service documentation Serice manager distributes the events between services. Infinite service event loop is possible, so care must be taken when designing service event path
1 parent 98c8ab6 commit 66a4f6b

File tree

4 files changed

+35
-12
lines changed

4 files changed

+35
-12
lines changed

libZaeUtil/service.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,30 @@ typedef struct service_method_t
2222
variant_t* (*eval_callback)(struct service_method_t*, va_list);
2323
} service_method_t;
2424

25+
typedef struct event_subscription_t
26+
{
27+
char* source;
28+
void (*on_event)(const char*, event_t*);
29+
} event_subscription_t;
30+
2531
typedef struct service_t
2632
{
2733
int service_id;
2834
char* service_name;
2935
char* description;
3036
char** (*get_config_callback)(void);
31-
void (*on_event)(const char*, event_t*);
37+
//void (*on_event)(const char*, event_t*);
3238
variant_stack_t* service_methods;
39+
variant_stack_t* event_subscriptions;
3340
} service_t;
3441

3542
#define SERVICE_INIT(_name, _desc) \
3643
*service = (service_t*)calloc(1, sizeof(service_t)); \
3744
(*service)->service_name = strdup(#_name); \
3845
(*service)->description = strdup(_desc); \
3946
(*service)->service_id = service_id; \
40-
(*service)->service_methods = stack_create();
47+
(*service)->service_methods = stack_create(); \
48+
(*service)->event_subscriptions = stack_create();
4149

4250
#define SERVICE_ADD_METHOD(_method_name, _method, _nargs, _help) \
4351
service_method_t* _method_name = (service_method_t*)malloc(sizeof(service_method_t)); \
@@ -47,8 +55,16 @@ service_method_t* _method_name = (service_method_t*)malloc(sizeof(service_method
4755
_method_name->eval_callback = &_method; \
4856
stack_push_back((*service)->service_methods, variant_create_ptr(service_id, _method_name, NULL)); \
4957

50-
#define SERVICE_ADD_EVENT_HANDLER(_handler) \
51-
(*service)->on_event = _handler
58+
//#define SERVICE_ADD_EVENT_HANDLER(_handler) \
59+
// (*service)->on_event = _handler
60+
61+
#define SERVICE_SUBSCRIBE_TO_EVENT_SOURCE(_source_, _handler_) \
62+
{ \
63+
event_subscription_t* es = (event_subscription_t*)malloc(sizeof(event_subscription_t)); \
64+
es->source = strdup(_source_); \
65+
es->on_event = _handler_; \
66+
stack_push_back((*service)->event_subscriptions, variant_create_ptr(DT_PTR, es, variant_delete_none)); \
67+
}
5268

5369
void service_create(service_t** service, int service_id);
5470
void service_cli_create(cli_node_t* parent_node);

libZaeUtil/variant.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ typedef struct variant_t
4343
int (*compare_cb)(const struct variant_t* v, const struct variant_t* other);
4444
} variant_t;
4545

46+
#define VARIANT_GET_PTR(_type_, _var_) \
47+
(_type_*)variant_get_ptr(_var_)
48+
4649
variant_t* variant_create(VariantDataType type, void* data);
4750
void variant_delete_default(void* ptr);
4851
void variant_delete_variant(void* ptr);

service_manager.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,18 @@ void service_manager_on_event(event_t* event)
191191
{
192192
service_t* service = (service_t*)variant_get_ptr(service_variant);
193193

194-
if(NULL != service->on_event)
194+
//if(NULL != service->on_event)
195+
service_t* calling_service = service_manager_get_class_by_id(event->source_id);
196+
if(NULL != calling_service )
195197
{
196-
service_t* calling_service = service_manager_get_class_by_id(event->source_id);
197-
198-
if(NULL != calling_service)
198+
stack_for_each(service->event_subscriptions, event_subscription_variant)
199199
{
200-
LOG_DEBUG(ServiceManager, "Forward event from: %s to service: %s", calling_service->service_name, service->service_name);
201-
service->on_event(calling_service->service_name, event);
200+
event_subscription_t* es = VARIANT_GET_PTR(event_subscription_t, event_subscription_variant);
201+
if(strcmp(es->source, calling_service->service_name) == 0)
202+
{
203+
LOG_DEBUG(ServiceManager, "Forward event from: %s to service: %s", calling_service->service_name, service->service_name);
204+
es->on_event(calling_service->service_name, event);
205+
}
202206
}
203207
}
204208
}

services/Cron/Cron.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ void timer_tick_event(const char* name, event_t* pevent);
1313
void service_create(service_t** service, int service_id)
1414
{
1515
SERVICE_INIT(Cron, "Provides cron-like ability to execute scenes or commands at pre defined times");
16-
SERVICE_ADD_EVENT_HANDLER(timer_tick_event);
1716

1817
DT_CRON = service_id;
1918

2019
(*service)->get_config_callback = cron_cli_get_config;
20+
SERVICE_SUBSCRIBE_TO_EVENT_SOURCE("Timer", timer_tick_event);
2121

2222
// Test
2323
/*crontab_time_t ee;
@@ -115,7 +115,7 @@ void service_cli_create(cli_node_t* parent_node)
115115
*/
116116
void timer_tick_event(const char* name, event_t* pevent)
117117
{
118-
if(++timer_tick_counter > 60)
118+
if(++timer_tick_counter > 60 && strcmp(variant_get_string(pevent->data), "tick") == 0)
119119
{
120120
timer_tick_counter = 0;
121121
LOG_DEBUG(DT_CRON, "Event %s tick", name);

0 commit comments

Comments
 (0)