summaryrefslogtreecommitdiffstats
path: root/src/Event.hpp
blob: 2d830a4402c4a9a3e051bc9a6aa6fe5b71b5d50b (plain) (blame)
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
114
115
116
#pragma once

#include <queue>
#include <map>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <variant>
#include <functional>

#include "Vector.hpp"
#include "Packet.hpp"

enum class EventType {
	Echo,
	ChunkChanged,
	ConnectToServer,
	ConnectionSuccessfull,
	GlobalAppState,
	Disconnect,
	SendPacket,
	ReceivePacket,
};

struct EchoData {
	std::chrono::time_point<std::chrono::high_resolution_clock> time;
};

struct ChunkChangedData {
	Vector chunkPosition;
};

struct ConnectToServerData {
	std::string address;
	unsigned short port;
};

struct ConnectionSuccessfullData {

};

enum class GlobalState {
	InitialLoading,
	MainMenu,
	Loading,
	InGame,
	PauseMenu,
	Exiting,
};

struct GlobalAppStateData {
	GlobalState state;
};

struct DisconnectData {

};

struct SendPacketData {
	std::shared_ptr<Packet> packet;
};

struct ReceivePacketData {
	std::shared_ptr<Packet> packet;
};

using EventData = std::variant<EchoData, ChunkChangedData, ConnectToServerData, ConnectionSuccessfullData,
		GlobalAppStateData, DisconnectData, SendPacketData, ReceivePacketData>;

struct Event {
	EventType type;
	EventData data;
};

class EventListener {
	friend class EventAgregator;

	using HandlerFunc = std::function<void(EventData)>;

	std::map<EventType, HandlerFunc> handlers; //TODO: There must be more elegant solution than std::variant of all data

	std::mutex eventsMutex;

	std::queue<Event> events;

	void PushEvent(Event event);

public:
	EventListener();
	~EventListener();
	bool IsEventsQueueIsNotEmpty();

	void RegisterHandler(EventType type, HandlerFunc handler);

	void HandleEvent();
};

class EventAgregator {
	friend EventListener;

	EventAgregator() = default;
	static std::queue<Event> eventsToHandle;
	static std::mutex queueMutex;
	static bool isStarted;
	static std::vector<EventListener *> listeners;
	static std::mutex listenersMutex;

	static void EventHandlingLoop();

	static void RegisterListener(EventListener &listener);
	static void UnregisterListener(EventListener &listener);

public:
	static void PushEvent(EventType type, EventData data);
};