#pragma once #include #include #include #include #include #include #include #include #include #include "Vector.hpp" #include "Packet.hpp" enum class EventType { Echo, ChunkChanged, ConnectToServer, ConnectionSuccessfull, Disconnect, RequestNetworkClient, RegisterNetworkClient, PlayerConnected, RemoveLoadingScreen, ConnectionFailed, Exit, Disconnected, Connecting, NetworkClientException, MouseMoved, KeyPressed, KeyReleased, InitalizeSectionRender, UpdateSectionsRender, CreateSectionRender, CreatedSectionRender, PlayerPosChanged, DeleteSectionRender, EntityChanged, NewRenderDataAvailable, BlockChange, RendererWorkerTask, ChunkDeleted, }; struct EchoData { std::chrono::time_point time; }; struct ChunkChangedData { Vector chunkPosition; }; struct ConnectToServerData { std::string address; unsigned short port; }; class NetworkClient; struct ConnectionSuccessfullData { std::shared_ptr ptr; }; struct DisconnectData { std::string reason; }; struct SendPacketData { std::shared_ptr packet; }; struct ReceivePacketData { std::shared_ptr packet; }; struct RequestNetworkClientData { }; struct RegisterNetworkClientData { NetworkClient *ptr; }; class GameState; struct PlayerConnectedData { std::shared_ptr ptr; }; struct RemoveLoadingScreenData { }; struct ConnectionFailedData { std::string reason; }; struct ExitData { }; struct DisconnectedData { std::string reason; }; struct ConnectingData { }; struct NetworkClientExceptionData { std::string what; }; struct MouseMovedData { double x, y; }; struct KeyPressedData { sf::Keyboard::Key key; }; struct KeyReleasedData { sf::Keyboard::Key key; }; struct InitalizeSectionRenderData { Vector pos; }; struct CreateSectionRenderData { Vector pos; }; struct CreatedSectionRenderData { Vector pos; }; struct PlayerPosChangedData { VectorF newPos; }; struct UpdateSectionsRenderData { }; struct DeleteSectionRenderData { Vector pos; }; struct EntityChangedData { unsigned int EntityId; }; struct NewRenderDataAvailableData { }; struct BlockChangeData { Vector SectionPos; }; struct RendererWorkerTaskData { size_t WorkerId; Vector Task; }; struct ChunkDeletedData { Vector pos; }; using EventData = std::variant; struct Event { EventType type; EventData data; }; class EventListener { friend class EventAgregator; using HandlerFunc = std::function; std::map handlers; //TODO: There must be more elegant solution than std::variant of all data std::mutex handlersMutex; std::queue events; std::mutex eventsMutex; void PushEvent(Event event); void DirectCall(Event event); public: EventListener(); ~EventListener(); bool IsEventsQueueIsNotEmpty(); void RegisterHandler(EventType type, HandlerFunc handler); void HandleEvent(); }; class EventAgregator { friend EventListener; EventAgregator() = default; static std::queue eventsToHandle; static std::mutex queueMutex; static bool isStarted; static std::vector 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); static void DirectEventCall(EventType, EventData data); };