From 162375842bbeaa3e248f406aa03e242a9490b6ec Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 3 Jul 2014 05:10:53 -0700 Subject: [PATCH] introducing new callback system --- src/CMakeLists.txt | 2 ++ src/callback.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ src/callback.h | 16 ++++++++++++++ src/callback.test.c | 50 +++++++++++++++++++++++++++++++++++++++++ src/test_eressea.c | 2 ++ 5 files changed, 124 insertions(+) create mode 100644 src/callback.c create mode 100644 src/callback.h create mode 100644 src/callback.test.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f2faa2bc4..fb1ccc8ef 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -59,6 +59,7 @@ ENDIF() set (ERESSEA_SRC eressea.c + callback.c direction.c keyword.c skill.c @@ -146,6 +147,7 @@ set(TESTS_SRC test_eressea.c tests.c tests.test.c + callback.test.c direction.test.c keyword.test.c skill.test.c diff --git a/src/callback.c b/src/callback.c new file mode 100644 index 000000000..3813c6456 --- /dev/null +++ b/src/callback.c @@ -0,0 +1,54 @@ +#include "callback.h" +#include +#include + +static struct reg { + struct reg * next; + CALLBACK cb; + const char *name; +} *registry; + +CALLBACK create_callback(void (*cbv)(va_list va)) { + CALLBACK cb; + cb.cbv = cbv; + return cb; +} + +void reset_callbacks(void) { + registry = 0; +} + +CALLBACK register_callback(const char *name, void (*cbv)(va_list va)) +{ + struct reg * r = (struct reg *)malloc(sizeof(struct reg)); + r->next = registry; + r->name = name; + r->cb.cbv = cbv; + registry = r; + return r->cb; +} + +int find_callback(const char *name, CALLBACK *result) { + if (result && name) { + struct reg *r; + for (r=registry;r;r=r->next) { + if (strcmp(r->name, name)==0) { + *result = r->cb; + return 0; + } + } + } + return -1; +} + +int call_callback(CALLBACK cb, const char *name, ... ) { + va_list ap; + if (name) { + int err = find_callback(name, &cb); + if (err) return err; + } + va_start(ap, name); + cb.cbv(ap); + va_end(ap); + return 0; +} diff --git a/src/callback.h b/src/callback.h new file mode 100644 index 000000000..b7f592161 --- /dev/null +++ b/src/callback.h @@ -0,0 +1,16 @@ +#ifndef H_CALLBACK_H +#define H_CALLBACK_H + +#include + +typedef struct { + void (*cbv)(va_list va); +} CALLBACK; + +CALLBACK register_callback(const char *name, void (*cbv)(va_list va)); +CALLBACK create_callback(void (*cbv)(va_list va)); +int find_callback(const char *name, CALLBACK *result); +int call_callback(CALLBACK cb, const char *name, ...); +void reset_callbacks(void); + +#endif diff --git a/src/callback.test.c b/src/callback.test.c new file mode 100644 index 000000000..b5fcba34b --- /dev/null +++ b/src/callback.test.c @@ -0,0 +1,50 @@ +#include "callback.h" +#include +#include + +void callback(va_list ap) { + int i = (int)va_arg(ap, int); + int *p = va_arg(ap, int *); + *p += i; +} + +static void test_find_callback(CuTest *tc) { + CALLBACK cb; + reset_callbacks(); + CuAssertIntEquals(tc, -1, find_callback("test", &cb)); + cb = register_callback("test", callback); + CuAssertIntEquals(tc, 0, find_callback("test", &cb)); + reset_callbacks(); +} + +static void test_call_by_handle(CuTest *tc) { + CALLBACK cb; + int x = 0; + reset_callbacks(); + cb = create_callback(callback); + CuAssertIntEquals(tc, 0, call_callback(cb, 0, 42, &x)); + CuAssertIntEquals(tc, 42, x); + reset_callbacks(); +} + +static void test_call_by_name(CuTest *tc) { + CALLBACK cb, ca; + int x = 0; + reset_callbacks(); + CuAssertIntEquals(tc, -1, call_callback(cb, "test", 42, &x)); + cb = register_callback("test", callback); + CuAssertIntEquals(tc, 0, call_callback(cb, "test", 42, &x)); + CuAssertIntEquals(tc, 42, x); + CuAssertIntEquals(tc, 0, call_callback(ca, "test", 42, &x)); + CuAssertIntEquals(tc, 84, x); + reset_callbacks(); +} + +CuSuite *get_callback_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_find_callback); + SUITE_ADD_TEST(suite, test_call_by_name); + SUITE_ADD_TEST(suite, test_call_by_handle); + return suite; +} diff --git a/src/test_eressea.c b/src/test_eressea.c index 00508bb9c..2b0fbee53 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -3,6 +3,7 @@ #include CuSuite *get_tests_suite(void); +CuSuite *get_callback_suite(void); CuSuite *get_jsonconf_suite(void); CuSuite *get_json_suite(void); CuSuite *get_economy_suite(void); @@ -41,6 +42,7 @@ int RunAllTests(void) /* self-test */ CuSuiteAddSuite(suite, get_tests_suite()); + CuSuiteAddSuite(suite, get_callback_suite()); CuSuiteAddSuite(suite, get_json_suite()); CuSuiteAddSuite(suite, get_jsonconf_suite()); CuSuiteAddSuite(suite, get_direction_suite());