From 6a00886804c53883d919f008f6ec47a574d86607 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Mon, 24 Jul 2017 19:52:24 +0500 Subject: 2017-07-24 --- src/core/AssetManager.cpp | 2 +- src/core/AssetManager.hpp | 75 ++++++++++++++++++++++++++++++++++++ src/core/Core.cpp | 4 +- src/core/Core.hpp | 95 ++++++++++++++++++++++++++++++++++++++++++++++ src/core/Event.cpp | 76 +++++++++++++++++++++++++++++++++++++ src/core/Event.hpp | 96 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 345 insertions(+), 3 deletions(-) create mode 100644 src/core/AssetManager.hpp create mode 100644 src/core/Core.hpp create mode 100644 src/core/Event.cpp create mode 100644 src/core/Event.hpp (limited to 'src/core') diff --git a/src/core/AssetManager.cpp b/src/core/AssetManager.cpp index d263c4a..14ea677 100644 --- a/src/core/AssetManager.cpp +++ b/src/core/AssetManager.cpp @@ -1,4 +1,4 @@ -#include +#include namespace fs = std::experimental::filesystem; diff --git a/src/core/AssetManager.hpp b/src/core/AssetManager.hpp new file mode 100644 index 0000000..26c7eca --- /dev/null +++ b/src/core/AssetManager.hpp @@ -0,0 +1,75 @@ +#pragma once + +#include +#include + +#include +#include +#include + +#include +#include + +struct TextureCoordinates { + TextureCoordinates(float x = -1, float y = -1, float w = -1, float h = -1) : x(x), y(y), w(w), h(h) {} + + bool operator==(const TextureCoordinates &rhs) const { + return x == rhs.x && + y == rhs.y && + w == rhs.w && + h == rhs.h; + } + + explicit operator bool() const { + return !(*this == TextureCoordinates(-1, -1, -1, -1)); + } + + float x, y, w, h; +}; + +struct BlockTextureId { + //Block sides: 0 - bottom, 1 - top, 2 - north, 3 - south, 4 - west, 5 - east 6 - every side + BlockTextureId(int id = 0, int state = 0, int side = 6) : id(id), state(state), side(side) {} + + int id:9; + int state:4; + int side:3; + + + bool operator<(const BlockTextureId &rhs) const { + if (id < rhs.id) + return true; + if (rhs.id < id) + return false; + if (state < rhs.state) + return true; + if (rhs.state < state) + return false; + return side < rhs.side; + } +}; + +class AssetManager { + Texture *textureAtlas; + std::map assetIds; + std::map assetTextures; + std::map textureAtlasIndexes; +public: + AssetManager(); + + ~AssetManager(); + + void LoadTextureResources(); + + TextureCoordinates GetTextureByAssetName(std::string AssetName); + + std::string GetTextureAssetNameByBlockId(BlockTextureId block); + + GLuint GetTextureAtlas(); + + const std::map &GetTextureAtlasIndexes(); + + void LoadIds(); + + TextureCoordinates GetTextureByBlock(BlockTextureId block); +}; diff --git a/src/core/Core.cpp b/src/core/Core.cpp index 44e2648..e98d204 100644 --- a/src/core/Core.cpp +++ b/src/core/Core.cpp @@ -44,7 +44,7 @@ void Core::Exec() { UpdateChunksToRender(); } - /*std::ostringstream toWindow; + std::ostringstream toWindow; auto camPos = gameState->Position(); auto velPos = glm::vec3(gameState->g_PlayerVelocityX, gameState->g_PlayerVelocityY, gameState->g_PlayerVelocityZ); @@ -57,7 +57,7 @@ void Core::Exec() { toWindow << " (" << deltaTime * 1000 << "ms); "; toWindow << "Tickrate: " << tickRate << " (" << (1.0 / tickRate * 1000) << "ms); "; toWindow << "Sections: " << sectionRate << " (" << (1.0 / sectionRate * 1000) << "ms); "; - window->setTitle(toWindow.str());*/ + window->setTitle(toWindow.str()); HandleEvents(); if (isMouseCaptured) HandleMouseCapture(); diff --git a/src/core/Core.hpp b/src/core/Core.hpp new file mode 100644 index 0000000..fdbb377 --- /dev/null +++ b/src/core/Core.hpp @@ -0,0 +1,95 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +struct MyMutex { + std::mutex mtx; + std::string str; + MyMutex(std::string name); + void lock(); + void unlock(); +}; + +class Core { + GameState *gameState; + NetworkClient *client; + sf::Window *window; + AssetManager *assetManager; + bool isMouseCaptured = false; + bool isRunning = true; + enum { + MainMenu, + Loading, + Playing, + PauseMenu, + } currentState = Playing; + float mouseXDelta, mouseYDelta; + float deltaTime; + float absTime; + + void RenderWorld(); + + void HandleMouseCapture(); + + void HandleEvents(); + + void InitSfml(unsigned int WinWidth, unsigned int WinHeight, std::string WinTitle); + + void InitGlew(); + + void SetMouseCapture(bool IsCaptured); + + void PrepareToRendering(); + + void RenderFrame(); + + unsigned int width(); + + unsigned int height(); + + void UpdateChunksToRender(); + + void UpdateGameState(); + + void UpdateSections(); + + std::thread gameStateLoopThread; + std::thread sectionUpdateLoopThread; + + Shader *shader; + //Cube verticies, Cube VAO, Cube UVs, TextureIndexes UboTextureIndexes, TextureData UboTextureIndexes, TextureData2 UboTextureIndexes, Blocks VBO, Models VBO, Line VAO, Lines VBO + bool isRendersShouldBeCreated=false; + std::condition_variable waitRendersCreated; + std::vector renders; + std::mutex toRenderMutex; + std::vector toRender; + std::map availableChunks; + std::mutex availableChunksMutex; + + int ChunkDistance = 3; + + RenderState renderState; + + double tickRate = 0; + double sectionRate = 0; + +public: + Core(); + + ~Core(); + + void Exec(); +}; diff --git a/src/core/Event.cpp b/src/core/Event.cpp new file mode 100644 index 0000000..10b2eaa --- /dev/null +++ b/src/core/Event.cpp @@ -0,0 +1,76 @@ +#include +#include + +std::queue EventAgregator::eventsToHandle; +std::mutex EventAgregator::queueMutex; +bool EventAgregator::isStarted = false; +std::vector EventAgregator::listeners; +std::mutex EventAgregator::listenersMutex; + +void EventAgregator::EventHandlingLoop() { + while (true) { + queueMutex.lock(); + if (!eventsToHandle.empty()) { + auto queue = eventsToHandle; + while (!eventsToHandle.empty()) + eventsToHandle.pop(); + queueMutex.unlock(); + + while (!queue.empty()) { + auto event = queue.front(); + listenersMutex.lock(); + for (auto& listener : listeners) { + LOG(INFO)<<"Listener notified about event"; + listener->PushEvent(event); + } + listenersMutex.unlock(); + queue.pop(); + } + + queueMutex.lock(); + } + queueMutex.unlock(); + } +} + +void EventAgregator::RegisterListener(EventListener &listener) { + listenersMutex.lock(); + LOG(INFO)<<"Registered handler "<<&listener; + listeners.push_back(&listener); + listenersMutex.unlock(); +} + +void EventAgregator::UnregisterListener(EventListener &listener) { + listenersMutex.lock(); + LOG(INFO)<<"Unregistered handler "<<&listener; + listeners.erase(std::find(listeners.begin(), listeners.end(), &listener)); + listenersMutex.unlock(); +} + + + +EventListener::EventListener() { + EventAgregator::RegisterListener(*this); +} + +EventListener::~EventListener() { + EventAgregator::UnregisterListener(*this); +} + +void EventListener::PushEvent(Event event) { + eventsMutex.lock(); + LOG(INFO)<<"Pushed event to queue"; + events.push(event); + eventsMutex.unlock(); +} + +/*void EventListener::RegisterHandler(EventType type, std::function handler) { + handlers[type] = handler; +}*/ + +bool EventListener::IsEventsQueueIsNotEmpty() { + eventsMutex.lock(); + bool value = !events.empty(); + eventsMutex.unlock(); + return value; +} \ No newline at end of file diff --git a/src/core/Event.hpp b/src/core/Event.hpp new file mode 100644 index 0000000..cfa990a --- /dev/null +++ b/src/core/Event.hpp @@ -0,0 +1,96 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +enum class EventType { + Echo, + ChunkChanged, +}; + +struct EchoData { + std::chrono::time_point time; +}; + +struct ChunkChangedData { + Vector chunkPosition; +}; + +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 eventsMutex; + + std::queue events; + + void PushEvent(Event event); + +public: + EventListener(); + ~EventListener(); + bool IsEventsQueueIsNotEmpty(); + + void RegisterHandler(EventType type, HandlerFunc handler) { + handlers[type] = handler; + } + + void HandleEvent() { + eventsMutex.lock(); + if (events.empty()) { + eventsMutex.unlock(); + return; + } + Event event = events.front(); + events.pop(); + eventsMutex.unlock(); + auto function = handlers[event.type]; + function(event.data); + } +}; + +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) { + if (!isStarted) { + isStarted = true; + std::thread(&EventAgregator::EventHandlingLoop).detach(); + } + Event event; + event.type = type; + event.data = data; + eventsToHandle.push(event); + } +}; \ No newline at end of file -- cgit v1.2.3