summaryrefslogtreecommitdiff
path: root/pkev.h
blob: 5f183b61444dbffdc99a1c43e0637f1f997e3719 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#ifndef PK_EV_H
#define PK_EV_H

#include <stdint.h>

struct pk_ev_mgr;
typedef uint64_t pk_ev_id_T;

struct pk_ev_mgr *pk_ev_create();
void pk_ev_destroy(struct pk_ev_mgr *evmgr);

typedef void (pk_ev_cb)();

bool pk_ev_register_ev(struct pk_ev_mgr *evmgr, pk_ev_id_T evid);
bool pk_ev_register_cb(struct pk_ev_mgr *evmgr, pk_ev_id_T evid, pk_ev_cb *cb);
void pk_ev_emit(struct pk_ev_mgr *evmgr, pk_ev_id_T evid);

#endif /* PK_EV_H */

#ifdef PK_IMPL_EV

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#ifndef PK_EV_MAX_COUNT
# define PK_EV_MAX_COUNT 16
#endif

#ifndef PK_EV_MAX_CB_COUNT
# define PK_EV_MAX_CB_COUNT 8
#endif

struct pk_ev {
	pk_ev_id_T evid;
	pk_ev_cb *cb[PK_EV_MAX_CB_COUNT];
	uint8_t n_cb;
};

struct pk_ev_mgr {
	struct pk_ev ev[PK_EV_MAX_COUNT];
	uint8_t n_ev;
};

inline struct pk_ev_mgr*
pk_ev_create()
{
	struct pk_ev_mgr *mgr = (struct pk_ev_mgr*)malloc(sizeof(struct pk_ev_mgr));
	if (mgr == NULL) return NULL;
	memset(mgr, 0, sizeof(struct pk_ev_mgr));
	return mgr;
}

inline void
pk_ev_destroy(struct pk_ev_mgr *evmgr)
{
	assert(evmgr != NULL);
	memset(evmgr, 0, sizeof(struct pk_ev_mgr));
	free(evmgr);
}

inline bool
pk_ev_register_ev(struct pk_ev_mgr *evmgr, pk_ev_id_T evid)
{
	assert(evmgr != NULL);
	int i;
	for (i = 0; i < evmgr->n_ev; ++i) {
		if (evmgr->ev[i].evid == evid) {
			return false;
		}
	}
	evmgr->ev[evmgr->n_ev].evid = evid;
	evmgr->n_ev++;
	return true;
}

inline bool
pk_ev_register_cb(struct pk_ev_mgr *evmgr, pk_ev_id_T evid, pk_ev_cb *cb)
{
	assert(evmgr != NULL);
	struct pk_ev *ev = {0};
	int i;
	for (i = 0; i < evmgr->n_ev; ++i) {
		if (evmgr->ev[i].evid == evid) {
			ev = &evmgr->ev[i];
		}
	}
	if (ev == NULL) return false;
	ev->cb[ev->n_cb] = cb;
	ev->n_cb++;
	return true;
}

inline void
pk_ev_emit(struct pk_ev_mgr *evmgr, pk_ev_id_T evid)
{
	assert(evmgr != NULL);
	uint8_t i;
	struct pk_ev *ev = {0};
	for (i = 0; i < evmgr->n_ev; ++i) {
		if (evmgr->ev[i].evid == evid) {
			ev = &evmgr->ev[i];
			break;
		}
	}
	if (ev == NULL) return;
	for (i = 0; i < ev->n_cb; ++i) {
		(*ev->cb[i])();
	}
}

#endif