summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/AssetManager.cpp2
-rw-r--r--src/core/AssetManager.hpp75
-rw-r--r--src/core/Core.cpp4
-rw-r--r--src/core/Core.hpp95
-rw-r--r--src/core/Event.cpp76
-rw-r--r--src/core/Event.hpp96
6 files changed, 345 insertions, 3 deletions
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 <AssetManager.hpp>
+#include <core/AssetManager.hpp>
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 <experimental/filesystem>
+#include <map>
+
+#include <GL/glew.h>
+#include <glm/vec4.hpp>
+#include <nlohmann/json.hpp>
+
+#include <world/Block.hpp>
+#include <graphics/Texture.hpp>
+
+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<std::string, Block> assetIds;
+ std::map<std::string, TextureCoordinates> assetTextures;
+ std::map<BlockTextureId,glm::vec4> textureAtlasIndexes;
+public:
+ AssetManager();
+
+ ~AssetManager();
+
+ void LoadTextureResources();
+
+ TextureCoordinates GetTextureByAssetName(std::string AssetName);
+
+ std::string GetTextureAssetNameByBlockId(BlockTextureId block);
+
+ GLuint GetTextureAtlas();
+
+ const std::map<BlockTextureId,glm::vec4> &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 <iomanip>
+#include <tuple>
+
+#include <easylogging++.h>
+#include <SFML/Window.hpp>
+#include <GL/glew.h>
+#include <glm/gtc/type_ptr.hpp>
+
+#include <world/GameState.hpp>
+#include <core/AssetManager.hpp>
+#include <graphics/Shader.hpp>
+#include <graphics/Gui.hpp>
+#include <graphics/RenderSection.hpp>
+#include <network/NetworkClient.hpp>
+
+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<Vector> renders;
+ std::mutex toRenderMutex;
+ std::vector<Vector> toRender;
+ std::map<Vector, RenderSection> 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 <core/Event.hpp>
+#include <easylogging++.h>
+
+std::queue <Event> EventAgregator::eventsToHandle;
+std::mutex EventAgregator::queueMutex;
+bool EventAgregator::isStarted = false;
+std::vector<EventListener*> 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<void(void*)> 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 <queue>
+#include <map>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <chrono>
+#include <variant>
+#include <functional>
+
+#include <Vector.hpp>
+
+enum class EventType {
+ Echo,
+ ChunkChanged,
+};
+
+struct EchoData {
+ std::chrono::time_point<std::chrono::high_resolution_clock> time;
+};
+
+struct ChunkChangedData {
+ Vector chunkPosition;
+};
+
+using EventData = std::variant<EchoData, ChunkChangedData>;
+
+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) {
+ 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<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) {
+ 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