Вынес рендер в отдельный модуль. Сделал систему вызовов для модулй к ядру. Исправил баг в SaveMap. Убрал поддержку linux, так как трудно поддерживать обе платформы. Убрал тесты для linux.
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
struct CoreCallBacks
|
||||
{
|
||||
void (*Quit)();
|
||||
};
|
||||
@@ -1,12 +1,17 @@
|
||||
#include "CoreInstance.h"
|
||||
|
||||
#include "SystemCalls.h"
|
||||
#include "GLFW/glfw3.h"
|
||||
|
||||
#include <exception>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "Log/Log.h"
|
||||
|
||||
CoreInstance* CoreInstance::self = nullptr;
|
||||
|
||||
std::shared_ptr<SaveMap> CoreInstance::MainConfig::save()
|
||||
{
|
||||
return std::make_shared<SaveMap>("MainConfig");
|
||||
@@ -17,12 +22,31 @@ void CoreInstance::MainConfig::load(std::shared_ptr<SaveMap> save)
|
||||
game_name = save->GetString("game_name");
|
||||
base_world = save->GetString("base_world");
|
||||
modules_names = save->GetVectorString("modules_names");
|
||||
min_memory_size = save->GetDouble("min_memory_size");
|
||||
min_CPU_count = save->GetInteger("min_CPU_count");
|
||||
}
|
||||
|
||||
void CoreInstance::Quit_callback()
|
||||
{
|
||||
self->game->quit();
|
||||
}
|
||||
|
||||
CoreInstance::CoreInstance()
|
||||
{
|
||||
self = this;
|
||||
|
||||
callbacks_.Quit = &Quit_callback;
|
||||
|
||||
countCPU = System::getCountCPU();
|
||||
memorySize = System::getMemorySize();
|
||||
|
||||
if (!glfwInit())
|
||||
{
|
||||
std::string msg;
|
||||
const char* error;
|
||||
glfwGetError(&error);
|
||||
throw std::runtime_error("Fail initialize GLFW");
|
||||
}
|
||||
|
||||
std::ifstream main_config_file(main_config_name);
|
||||
if (main_config_file.fail())
|
||||
@@ -30,15 +54,14 @@ CoreInstance::CoreInstance()
|
||||
|
||||
std::string payload;
|
||||
std::getline(main_config_file, payload);
|
||||
std::shared_ptr<SaveMap> load_main_config = std::make_shared<SaveMap>(payload);
|
||||
SaveMap load_main_config(payload);
|
||||
|
||||
main_config.load(load_main_config);
|
||||
main_config.load(std::make_shared<SaveMap>(load_main_config));
|
||||
}
|
||||
|
||||
CoreInstance::~CoreInstance()
|
||||
{
|
||||
if (game != nullptr)
|
||||
delete game;
|
||||
delete game;
|
||||
|
||||
for (auto& module : modules)
|
||||
System::QuitModule(module.handler);
|
||||
@@ -53,7 +76,7 @@ void CoreInstance::start()
|
||||
{
|
||||
try
|
||||
{
|
||||
void* handler = System::InitModule(name.c_str(), *this);
|
||||
void* handler = System::InitModule(name.c_str(), &callbacks_);
|
||||
modules.push_back(Module {name.c_str(), handler});
|
||||
} catch (const std::exception& e)
|
||||
{
|
||||
@@ -96,7 +119,7 @@ void* CoreInstance::enableModule(const char* name)
|
||||
throw std::runtime_error("Module already enabled");
|
||||
}
|
||||
|
||||
void* module = System::InitModule(name, *this);
|
||||
void* module = System::InitModule(name, &callbacks_);
|
||||
modules.push_back({ name, module });
|
||||
return module;
|
||||
}
|
||||
|
||||
+19
-13
@@ -5,8 +5,10 @@
|
||||
|
||||
#include "Game/GameInstance.h"
|
||||
#include "Game/SaveMap/SaveMap.h"
|
||||
#include "Core/CoreCallBacks.h"
|
||||
|
||||
class CoreInstance {
|
||||
static CoreInstance* self;
|
||||
struct Module {
|
||||
const char* name;
|
||||
void* handler;
|
||||
@@ -17,37 +19,41 @@ class CoreInstance {
|
||||
std::string game_name;
|
||||
std::string base_world;
|
||||
std::vector<std::string> modules_names;
|
||||
|
||||
double min_memory_size = -1;
|
||||
int min_CPU_count = -1;
|
||||
|
||||
std::shared_ptr<SaveMap> save() override;
|
||||
void load(std::shared_ptr<SaveMap> save) override;
|
||||
};
|
||||
|
||||
#pragma region Key words for main config
|
||||
const char* key_base_world= "base_world";
|
||||
const char* key_modules = "modules";
|
||||
#pragma endregion
|
||||
|
||||
#pragma region config parameters
|
||||
|
||||
const char* main_config_name = "main_config.conf";
|
||||
// std::string base_world;
|
||||
// std::vector<std::string> modules_names;
|
||||
// std::string game_name;
|
||||
MainConfig main_config;
|
||||
#pragma endregion
|
||||
|
||||
int countCPU;
|
||||
unsigned long long memorySize;
|
||||
// Memory in MB
|
||||
double memorySize;
|
||||
std::list<Module> modules;
|
||||
|
||||
GameInstance* game = nullptr;
|
||||
CoreCallBacks callbacks_;
|
||||
|
||||
#pragma region Callbacks
|
||||
static void Quit_callback();
|
||||
#pragma endregion
|
||||
public:
|
||||
CoreInstance();
|
||||
~CoreInstance();
|
||||
|
||||
void start();
|
||||
|
||||
/**
|
||||
* This method quit game
|
||||
* Async
|
||||
*/
|
||||
|
||||
int getCountCPU() const { return countCPU; }
|
||||
unsigned long long getMemorySize() const { return memorySize; }
|
||||
double getMemorySize() const { return memorySize; }
|
||||
|
||||
/**
|
||||
* @throws std::runtime_error if module isn't enabled
|
||||
|
||||
+3
-12
@@ -18,12 +18,12 @@ int System::getCountCPU()
|
||||
return num_cores;
|
||||
}
|
||||
|
||||
unsigned long long System::getMemorySize()
|
||||
double System::getMemorySize()
|
||||
{
|
||||
struct sysinfo info{};
|
||||
if(sysinfo(&info) == -1)
|
||||
if(sysinfo(&info) == -1)
|
||||
std::runtime_error("Fail get system info");
|
||||
return info.totalram;
|
||||
return info.totalram / 1024 / 1024;
|
||||
}
|
||||
|
||||
void* System::InitModule(const char* ModuleName, CoreInstance& core)
|
||||
@@ -52,15 +52,6 @@ void System::StartModule(void* handler)
|
||||
start();
|
||||
}
|
||||
|
||||
void System::StopModule(void* handler)
|
||||
{
|
||||
void(*stop)() = reinterpret_cast<void(*)()>(dlsym(handler, "StopModule"));
|
||||
if(stop == nullptr)
|
||||
std::runtime_error("Module mot contins StopModule");
|
||||
stop();
|
||||
dlclose(handler);
|
||||
}
|
||||
|
||||
void System::QuitModule(void* handler)
|
||||
{
|
||||
void(*quit)() = reinterpret_cast<void(*)()>(dlsym(handler, "QuitModule"));
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
#include "RenderEngine.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include "Log/Log.h"
|
||||
#include <assert.h>
|
||||
#define VK_CHECK(res) assert(res == VK_SUCCESS)
|
||||
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* pUserData) {
|
||||
|
||||
std::string msg = "validation layer: ";
|
||||
msg += pCallbackData->pMessage;
|
||||
Log(msg);
|
||||
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
VkResult RenderEngine::enable_layer_validation(VkInstance instance, VkDebugUtilsMessengerCreateInfoEXT* create_info)
|
||||
{
|
||||
PFN_vkCreateDebugUtilsMessengerEXT debug_creator = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>(vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"));
|
||||
return debug_creator(instance, create_info, nullptr, &debug_messenger_);
|
||||
}
|
||||
#else
|
||||
#define VK_CHECK(res) if ((res) != VK_SUCCESS) throw std::runtime_error("Vulkan error: " + std::to_string(res))
|
||||
#endif
|
||||
|
||||
std::vector<const char*> RenderEngine::get_required_extensions()
|
||||
{
|
||||
uint32_t extensions_count = 0;
|
||||
const char** glfw_extension = glfwGetRequiredInstanceExtensions(&extensions_count);
|
||||
std::vector<const char*> extensions(glfw_extension, glfw_extension + extensions_count);
|
||||
|
||||
#ifdef _DEBUG
|
||||
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
#endif
|
||||
return extensions;
|
||||
}
|
||||
|
||||
void RenderEngine::render_thread_func()
|
||||
{
|
||||
window = glfwCreateWindow(640, 480, "UwU Engine", nullptr, nullptr);
|
||||
if (!window)
|
||||
{
|
||||
glfwTerminate();
|
||||
throw std::runtime_error("Fail create window");
|
||||
}
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
onCloseWindow.Call();
|
||||
}
|
||||
|
||||
RenderEngine::RenderEngine(const std::string& app_name,
|
||||
int major_app_version, int minor_app_version, int patch_app_version,
|
||||
int major_engine_version, int minor_engine_version, int patch_engine_version) :
|
||||
render_thread(nullptr), window(nullptr)
|
||||
#ifdef _DEBUG
|
||||
, debug_messenger_(nullptr)
|
||||
#endif
|
||||
{
|
||||
if (!glfwInit())
|
||||
throw std::runtime_error("Fail initialize GLFW");
|
||||
|
||||
{
|
||||
std::vector<const char*> extensions = get_required_extensions();
|
||||
std::vector<const char*> layers = {
|
||||
#ifdef _DEBUG
|
||||
"VK_LAYER_KHRONOS_validation"
|
||||
#endif
|
||||
};
|
||||
|
||||
VkApplicationInfo app_info{};
|
||||
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
app_info.apiVersion = VK_API_VERSION_1_0;
|
||||
app_info.applicationVersion = VK_MAKE_VERSION(major_app_version, minor_app_version, patch_app_version);
|
||||
app_info.pApplicationName = app_name.c_str();
|
||||
app_info.pEngineName = "UwU Engine";
|
||||
app_info.engineVersion = VK_MAKE_VERSION(major_engine_version, minor_engine_version, patch_engine_version);
|
||||
|
||||
|
||||
VkInstanceCreateInfo instance_create_info{};
|
||||
instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
instance_create_info.pApplicationInfo = &app_info;
|
||||
instance_create_info.enabledExtensionCount = extensions.size();
|
||||
instance_create_info.ppEnabledExtensionNames = extensions.data();
|
||||
instance_create_info.enabledLayerCount = layers.size();
|
||||
instance_create_info.ppEnabledLayerNames = layers.data();
|
||||
#ifdef _DEBUG
|
||||
VkDebugUtilsMessengerCreateInfoEXT debug_messenger_create_info{};
|
||||
debug_messenger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||
debug_messenger_create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
debug_messenger_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
debug_messenger_create_info.pfnUserCallback = &debugCallback;
|
||||
instance_create_info.pNext = &debug_messenger_create_info;
|
||||
#endif
|
||||
VK_CHECK(vkCreateInstance(&instance_create_info, nullptr, &instance_));
|
||||
#ifdef _DEBUG
|
||||
VK_CHECK(enable_layer_validation(instance_, &debug_messenger_create_info));
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t device_count = 0;
|
||||
std::vector<VkPhysicalDevice> devices;
|
||||
VK_CHECK(vkEnumeratePhysicalDevices(instance_, &device_count, nullptr));
|
||||
VK_CHECK(vkEnumeratePhysicalDevices(instance_, &device_count, devices.data()));
|
||||
|
||||
for (const auto& device : devices)
|
||||
{
|
||||
VkPhysicalDeviceProperties device_properties;
|
||||
vkGetPhysicalDeviceProperties(device, &device_properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderEngine::~RenderEngine()
|
||||
{
|
||||
if (window != nullptr && !glfwWindowShouldClose(window))
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
|
||||
if (render_thread != nullptr)
|
||||
{
|
||||
render_thread->join();
|
||||
delete render_thread;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (debug_messenger_ != nullptr && instance_ != nullptr) {
|
||||
PFN_vkDestroyDebugUtilsMessengerEXT destroyer_messenger = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT>(vkGetInstanceProcAddr(instance_, "vkDestroyDebugUtilsMessengerEXT"));
|
||||
destroyer_messenger(instance_, debug_messenger_, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (instance_ != nullptr)
|
||||
vkDestroyInstance(instance_, nullptr);
|
||||
|
||||
if (window != nullptr)
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
void RenderEngine::start()
|
||||
{
|
||||
render_thread = new std::thread(&RenderEngine::render_thread_func, this);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define GLFW_INCLUDE_VULKAN
|
||||
|
||||
#include "Delegate/Delegate.h"
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "GLFW/glfw3.h"
|
||||
|
||||
class RenderEngine
|
||||
{
|
||||
std::thread* render_thread;
|
||||
|
||||
GLFWwindow* window;
|
||||
VkInstance instance_;
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
VkResult enable_layer_validation(VkInstance instance, VkDebugUtilsMessengerCreateInfoEXT* create_info);
|
||||
VkDebugUtilsMessengerEXT debug_messenger_;
|
||||
#endif
|
||||
|
||||
static std::vector<const char*> get_required_extensions();
|
||||
void render_thread_func();
|
||||
public:
|
||||
Delegate<void> onCloseWindow;
|
||||
|
||||
RenderEngine(const std::string& app_name,
|
||||
int major_app_version, int minor_app_version, int patch_app_version,
|
||||
int major_engine_version, int minor_engine_version, int patch_engine_version);
|
||||
~RenderEngine();
|
||||
|
||||
void start();
|
||||
};
|
||||
@@ -2,32 +2,32 @@
|
||||
|
||||
class CoreInstance;
|
||||
|
||||
struct CoreCallBacks;
|
||||
|
||||
namespace System {
|
||||
/**
|
||||
* @throws std::exception if the operation finished with failed
|
||||
* @return count CPU
|
||||
*/
|
||||
int getCountCPU();
|
||||
unsigned long long getMemorySize();
|
||||
/*
|
||||
* @throws std::runtime_error
|
||||
* @return memory size in MB
|
||||
*/
|
||||
double getMemorySize();
|
||||
|
||||
/**
|
||||
* Load module and init handler
|
||||
* @throws std::runtime_error if module not found
|
||||
* @return module handler
|
||||
*/
|
||||
void* InitModule(const char* ModuleName, CoreInstance& core);
|
||||
void* InitModule(const char* ModuleName, CoreCallBacks* callbacks);
|
||||
|
||||
/**
|
||||
* Start module
|
||||
* @throws std::runtime_error if module not contains StartModule function
|
||||
*/
|
||||
void StartModule(void* handler) noexcept(false);
|
||||
|
||||
/**
|
||||
* Stop the module when unload there
|
||||
* @throws std::runtime_error if module not contains StopModule function
|
||||
*/
|
||||
void StopModule(void* handler) noexcept(false);
|
||||
|
||||
/**
|
||||
* Call stop module
|
||||
|
||||
+5
-14
@@ -33,15 +33,15 @@ int System::getCountCPU() {
|
||||
return physicalCoreCount;
|
||||
}
|
||||
|
||||
unsigned long long System::getMemorySize() {
|
||||
double System::getMemorySize() {
|
||||
MEMORYSTATUSEX memStatus{};
|
||||
memStatus.dwLength = sizeof(memStatus);
|
||||
|
||||
GlobalMemoryStatusEx(&memStatus);
|
||||
return memStatus.ullTotalPhys;
|
||||
return memStatus.ullTotalPhys / 1024 / 1024;
|
||||
}
|
||||
|
||||
void* System::InitModule(const char* ModuleName, CoreInstance& core) {
|
||||
void* System::InitModule(const char* ModuleName, CoreCallBacks* callbacks) {
|
||||
std::string fileName = ModuleName;
|
||||
fileName += ".dll";
|
||||
|
||||
@@ -49,11 +49,11 @@ void* System::InitModule(const char* ModuleName, CoreInstance& core) {
|
||||
if(hModule == nullptr)
|
||||
throw std::runtime_error(std::to_string(GetLastError()).c_str());
|
||||
|
||||
void(*load)(CoreInstance&) = reinterpret_cast<void(*)(CoreInstance&)>(GetProcAddress(hModule, "InitModule"));
|
||||
void(*load)(CoreCallBacks*) = reinterpret_cast<void(*)(CoreCallBacks*)>(GetProcAddress(hModule, "InitModule"));
|
||||
if(load == nullptr) {
|
||||
throw std::runtime_error(std::to_string(GetLastError()).c_str());
|
||||
}
|
||||
load(core);
|
||||
load(callbacks);
|
||||
|
||||
return hModule;
|
||||
}
|
||||
@@ -66,15 +66,6 @@ void System::StartModule(void* handler) {
|
||||
start();
|
||||
}
|
||||
|
||||
void System::StopModule(void* handler) {
|
||||
void(*stop)() = reinterpret_cast<void(*)()>(GetProcAddress(static_cast<HMODULE>(handler), "StopModule"));
|
||||
if(stop == nullptr) {
|
||||
throw std::runtime_error(std::to_string(GetLastError()).c_str());
|
||||
}
|
||||
stop();
|
||||
FreeLibrary(static_cast<HMODULE>(handler));
|
||||
}
|
||||
|
||||
void System::QuitModule(void* handler) {
|
||||
void(*quit)() = reinterpret_cast<void(*)()>(GetProcAddress(static_cast<HMODULE>(handler), "QuitModule"));
|
||||
if(quit == nullptr) {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <thread>
|
||||
|
||||
#include "Core/CoreInstance.h"
|
||||
#include "Core/RenderEngine.h"
|
||||
#include "Game/WorldFactory.h"
|
||||
#include "SaveMap/SaveMap.h"
|
||||
#include "Game/World/World.h"
|
||||
@@ -15,8 +14,6 @@ extern std::vector<WorldFactory> world_factories;
|
||||
|
||||
GameInstance::GameInstance(CoreInstance& core) : core(core)
|
||||
{
|
||||
render_engine_ = std::make_unique<RenderEngine>(core.getGameName(), 0, 0, 0, 0, 0, 0);
|
||||
render_engine_->onCloseWindow.bind(this, &GameInstance::quit);
|
||||
const std::string& base_world = core.getBaseWorldName();
|
||||
|
||||
// Init directories
|
||||
@@ -51,7 +48,6 @@ GameInstance::~GameInstance()
|
||||
|
||||
void GameInstance::start()
|
||||
{
|
||||
render_engine_->start();
|
||||
world->BeginPlay();
|
||||
|
||||
auto first = std::chrono::steady_clock::now();
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
class CoreInstance;
|
||||
class World;
|
||||
class RenderEngine;
|
||||
|
||||
#define GENERATE_FACTORY_GAME_INSTANCE(Class) \
|
||||
GameInstance* GameFactory(CoreInstance& core) { return new Class(core); }
|
||||
@@ -14,7 +13,6 @@ class GameInstance
|
||||
{
|
||||
CoreInstance& core;
|
||||
World* world = nullptr;
|
||||
std::unique_ptr<RenderEngine> render_engine_;
|
||||
|
||||
std::atomic<bool> is_running = true;
|
||||
|
||||
|
||||
@@ -49,17 +49,17 @@ SaveMap::SaveMap(const std::string& json_data)
|
||||
}
|
||||
|
||||
if (name[0] == 'i') {
|
||||
size_t begin = json_data.find(':', i) + 1;
|
||||
size_t begin = json_data.find(':', i) + 2;
|
||||
size_t end = i = json_data.find_first_of(",}", i);
|
||||
i++;
|
||||
std::string value = json_data.substr(begin, end - begin);
|
||||
std::string value = json_data.substr(begin, end - begin - 1);
|
||||
save_long[name.c_str() + 1] = std::stoll(value);
|
||||
} else if (name[0] == 'd')
|
||||
{
|
||||
size_t begin = json_data.find(':', i) + 1;
|
||||
size_t begin = json_data.find(':', i) + 2;
|
||||
size_t end = i = json_data.find_first_of(",}", i);
|
||||
i++;
|
||||
std::string value = json_data.substr(begin, end - begin);
|
||||
std::string value = json_data.substr(begin, end - begin - 1);
|
||||
save_double[name.c_str() + 1] = std::stod(value);
|
||||
} else if (name[0] == 's')
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user