summaryrefslogtreecommitdiff
path: root/src/port/hooks/impl/EventSystem.h
blob: 8bf6573288f9e0131219ddad28f56f715ddde9df (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
#pragma once

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

typedef uint32_t EventID;
typedef uint32_t ListenerID;

typedef enum {
    EVENT_PRIORITY_LOW,
    EVENT_PRIORITY_NORMAL,
    EVENT_PRIORITY_HIGH,
} EventPriority;

typedef struct {
    bool cancelled;
} IEvent;

typedef void (*EventCallback)(IEvent*);

typedef struct {
    EventPriority priority;
    EventCallback function;
} EventListener;

#ifdef INIT_EVENT_IDS
#define DECLARE_EVENT(eventName) \
    uint32_t eventName##ID = -1;
#else
#define DECLARE_EVENT(eventName) \
    extern uint32_t eventName##ID;
#endif

#define DEFINE_EVENT(eventName, ...) \
    typedef struct { \
        IEvent event; \
        __VA_ARGS__ \
    } eventName; \
    \
    DECLARE_EVENT(eventName)

#define CALL_EVENT(eventType, ...) \
    eventType eventType##_ = { {false}, __VA_ARGS__ }; \
    EventSystem_CallEvent(eventType##ID, &eventType##_);

#define CALL_CANCELLABLE_EVENT(eventType, ...) \
    eventType eventType##_ = { {false}, __VA_ARGS__ }; \
    EventSystem_CallEvent(eventType##ID, &eventType##_); \
    if (!eventType##_.event.cancelled)

#define REGISTER_EVENT(eventType) \
    eventType##ID = EventSystem_RegisterEvent();

#define REGISTER_LISTENER(eventType, callback, priority) \
    EventSystem_RegisterListener(eventType##ID, callback, priority);

#ifdef __cplusplus
#include <array>
#include <vector>
#include <unordered_map>

class EventSystem {
public:
    static EventSystem* Instance;
    EventID RegisterEvent();
    ListenerID RegisterListener(EventID id, EventCallback callback, EventPriority priority = EVENT_PRIORITY_NORMAL);
    void UnregisterListener(EventID ev, ListenerID id);
    void CallEvent(EventID id, IEvent* event);
private:
    std::unordered_map<EventID, std::vector<EventListener>> mEventListeners;
    EventID mInternalEventID = 0;
};
#else
extern EventID EventSystem_RegisterEvent();
extern ListenerID EventSystem_RegisterListener(EventID id, EventCallback callback, EventPriority priority);
extern void EventSystem_UnregisterListener(EventID ev, ListenerID id);
extern void EventSystem_CallEvent(EventID id, void* event);
#endif