forked from github/server
introducing new callback system
This commit is contained in:
parent
ee1d97df19
commit
162375842b
5 changed files with 124 additions and 0 deletions
|
@ -59,6 +59,7 @@ ENDIF()
|
||||||
|
|
||||||
set (ERESSEA_SRC
|
set (ERESSEA_SRC
|
||||||
eressea.c
|
eressea.c
|
||||||
|
callback.c
|
||||||
direction.c
|
direction.c
|
||||||
keyword.c
|
keyword.c
|
||||||
skill.c
|
skill.c
|
||||||
|
@ -146,6 +147,7 @@ set(TESTS_SRC
|
||||||
test_eressea.c
|
test_eressea.c
|
||||||
tests.c
|
tests.c
|
||||||
tests.test.c
|
tests.test.c
|
||||||
|
callback.test.c
|
||||||
direction.test.c
|
direction.test.c
|
||||||
keyword.test.c
|
keyword.test.c
|
||||||
skill.test.c
|
skill.test.c
|
||||||
|
|
54
src/callback.c
Normal file
54
src/callback.c
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#include "callback.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
16
src/callback.h
Normal file
16
src/callback.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef H_CALLBACK_H
|
||||||
|
#define H_CALLBACK_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
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
|
50
src/callback.test.c
Normal file
50
src/callback.test.c
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#include "callback.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <CuTest.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
#include <util/log.h>
|
#include <util/log.h>
|
||||||
|
|
||||||
CuSuite *get_tests_suite(void);
|
CuSuite *get_tests_suite(void);
|
||||||
|
CuSuite *get_callback_suite(void);
|
||||||
CuSuite *get_jsonconf_suite(void);
|
CuSuite *get_jsonconf_suite(void);
|
||||||
CuSuite *get_json_suite(void);
|
CuSuite *get_json_suite(void);
|
||||||
CuSuite *get_economy_suite(void);
|
CuSuite *get_economy_suite(void);
|
||||||
|
@ -41,6 +42,7 @@ int RunAllTests(void)
|
||||||
|
|
||||||
/* self-test */
|
/* self-test */
|
||||||
CuSuiteAddSuite(suite, get_tests_suite());
|
CuSuiteAddSuite(suite, get_tests_suite());
|
||||||
|
CuSuiteAddSuite(suite, get_callback_suite());
|
||||||
CuSuiteAddSuite(suite, get_json_suite());
|
CuSuiteAddSuite(suite, get_json_suite());
|
||||||
CuSuiteAddSuite(suite, get_jsonconf_suite());
|
CuSuiteAddSuite(suite, get_jsonconf_suite());
|
||||||
CuSuiteAddSuite(suite, get_direction_suite());
|
CuSuiteAddSuite(suite, get_direction_suite());
|
||||||
|
|
Loading…
Reference in a new issue