Вынес рендер в отдельный модуль. Сделал систему вызовов для модулй к ядру. Исправил баг в SaveMap. Убрал поддержку linux, так как трудно поддерживать обе платформы. Убрал тесты для linux.
This commit is contained in:
@@ -1,42 +0,0 @@
|
|||||||
name: Ubuntu test
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "main" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "main" ]
|
|
||||||
|
|
||||||
env:
|
|
||||||
BUILD_TYPE: Release
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository with submodules
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
fetch-depth: 1
|
|
||||||
|
|
||||||
- name: Проверка содержимого glfw
|
|
||||||
run: ls -la glfw
|
|
||||||
|
|
||||||
- name: Install dependencies (Wayland, X11, Vulkan, OpenGL)
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y \
|
|
||||||
wayland-protocols libwayland-dev libxkbcommon-dev \
|
|
||||||
libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev \
|
|
||||||
libvulkan-dev mesa-common-dev
|
|
||||||
|
|
||||||
- name: Configure CMake
|
|
||||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
|
||||||
|
|
||||||
#- name: Test
|
|
||||||
# working-directory: ${{github.workspace}}/build
|
|
||||||
# run: ctest -C ${{env.BUILD_TYPE}}
|
|
||||||
@@ -20,5 +20,6 @@ add_subdirectory(FastRTTI)
|
|||||||
add_subdirectory(glfw)
|
add_subdirectory(glfw)
|
||||||
add_subdirectory(Core)
|
add_subdirectory(Core)
|
||||||
add_subdirectory(ModuleLib)
|
add_subdirectory(ModuleLib)
|
||||||
|
add_subdirectory(RenderModule)
|
||||||
add_subdirectory(TestGame)
|
add_subdirectory(TestGame)
|
||||||
add_subdirectory(ProjectGenerator)
|
add_subdirectory(ProjectGenerator)
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct CoreCallBacks
|
||||||
|
{
|
||||||
|
void (*Quit)();
|
||||||
|
};
|
||||||
@@ -1,12 +1,17 @@
|
|||||||
#include "CoreInstance.h"
|
#include "CoreInstance.h"
|
||||||
|
|
||||||
#include "SystemCalls.h"
|
#include "SystemCalls.h"
|
||||||
|
#include "GLFW/glfw3.h"
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "Log/Log.h"
|
||||||
|
|
||||||
|
CoreInstance* CoreInstance::self = nullptr;
|
||||||
|
|
||||||
std::shared_ptr<SaveMap> CoreInstance::MainConfig::save()
|
std::shared_ptr<SaveMap> CoreInstance::MainConfig::save()
|
||||||
{
|
{
|
||||||
return std::make_shared<SaveMap>("MainConfig");
|
return std::make_shared<SaveMap>("MainConfig");
|
||||||
@@ -17,27 +22,45 @@ void CoreInstance::MainConfig::load(std::shared_ptr<SaveMap> save)
|
|||||||
game_name = save->GetString("game_name");
|
game_name = save->GetString("game_name");
|
||||||
base_world = save->GetString("base_world");
|
base_world = save->GetString("base_world");
|
||||||
modules_names = save->GetVectorString("modules_names");
|
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()
|
CoreInstance::CoreInstance()
|
||||||
{
|
{
|
||||||
|
self = this;
|
||||||
|
|
||||||
|
callbacks_.Quit = &Quit_callback;
|
||||||
|
|
||||||
countCPU = System::getCountCPU();
|
countCPU = System::getCountCPU();
|
||||||
memorySize = System::getMemorySize();
|
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);
|
std::ifstream main_config_file(main_config_name);
|
||||||
if (main_config_file.fail())
|
if (main_config_file.fail())
|
||||||
throw std::runtime_error("Fail open main config file");
|
throw std::runtime_error("Fail open main config file");
|
||||||
|
|
||||||
std::string payload;
|
std::string payload;
|
||||||
std::getline(main_config_file, 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()
|
CoreInstance::~CoreInstance()
|
||||||
{
|
{
|
||||||
if (game != nullptr)
|
|
||||||
delete game;
|
delete game;
|
||||||
|
|
||||||
for (auto& module : modules)
|
for (auto& module : modules)
|
||||||
@@ -53,7 +76,7 @@ void CoreInstance::start()
|
|||||||
{
|
{
|
||||||
try
|
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});
|
modules.push_back(Module {name.c_str(), handler});
|
||||||
} catch (const std::exception& e)
|
} catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
@@ -96,7 +119,7 @@ void* CoreInstance::enableModule(const char* name)
|
|||||||
throw std::runtime_error("Module already enabled");
|
throw std::runtime_error("Module already enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
void* module = System::InitModule(name, *this);
|
void* module = System::InitModule(name, &callbacks_);
|
||||||
modules.push_back({ name, module });
|
modules.push_back({ name, module });
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-12
@@ -5,8 +5,10 @@
|
|||||||
|
|
||||||
#include "Game/GameInstance.h"
|
#include "Game/GameInstance.h"
|
||||||
#include "Game/SaveMap/SaveMap.h"
|
#include "Game/SaveMap/SaveMap.h"
|
||||||
|
#include "Core/CoreCallBacks.h"
|
||||||
|
|
||||||
class CoreInstance {
|
class CoreInstance {
|
||||||
|
static CoreInstance* self;
|
||||||
struct Module {
|
struct Module {
|
||||||
const char* name;
|
const char* name;
|
||||||
void* handler;
|
void* handler;
|
||||||
@@ -18,36 +20,40 @@ class CoreInstance {
|
|||||||
std::string base_world;
|
std::string base_world;
|
||||||
std::vector<std::string> modules_names;
|
std::vector<std::string> modules_names;
|
||||||
|
|
||||||
|
double min_memory_size = -1;
|
||||||
|
int min_CPU_count = -1;
|
||||||
|
|
||||||
std::shared_ptr<SaveMap> save() override;
|
std::shared_ptr<SaveMap> save() override;
|
||||||
void load(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";
|
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;
|
MainConfig main_config;
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
int countCPU;
|
int countCPU;
|
||||||
unsigned long long memorySize;
|
// Memory in MB
|
||||||
|
double memorySize;
|
||||||
std::list<Module> modules;
|
std::list<Module> modules;
|
||||||
|
|
||||||
GameInstance* game = nullptr;
|
GameInstance* game = nullptr;
|
||||||
|
CoreCallBacks callbacks_;
|
||||||
|
|
||||||
|
#pragma region Callbacks
|
||||||
|
static void Quit_callback();
|
||||||
|
#pragma endregion
|
||||||
public:
|
public:
|
||||||
CoreInstance();
|
CoreInstance();
|
||||||
~CoreInstance();
|
~CoreInstance();
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method quit game
|
||||||
|
* Async
|
||||||
|
*/
|
||||||
|
|
||||||
int getCountCPU() const { return countCPU; }
|
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
|
* @throws std::runtime_error if module isn't enabled
|
||||||
|
|||||||
+2
-11
@@ -18,12 +18,12 @@ int System::getCountCPU()
|
|||||||
return num_cores;
|
return num_cores;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long long System::getMemorySize()
|
double System::getMemorySize()
|
||||||
{
|
{
|
||||||
struct sysinfo info{};
|
struct sysinfo info{};
|
||||||
if(sysinfo(&info) == -1)
|
if(sysinfo(&info) == -1)
|
||||||
std::runtime_error("Fail get system info");
|
std::runtime_error("Fail get system info");
|
||||||
return info.totalram;
|
return info.totalram / 1024 / 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* System::InitModule(const char* ModuleName, CoreInstance& core)
|
void* System::InitModule(const char* ModuleName, CoreInstance& core)
|
||||||
@@ -52,15 +52,6 @@ void System::StartModule(void* handler)
|
|||||||
start();
|
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 System::QuitModule(void* handler)
|
||||||
{
|
{
|
||||||
void(*quit)() = reinterpret_cast<void(*)()>(dlsym(handler, "QuitModule"));
|
void(*quit)() = reinterpret_cast<void(*)()>(dlsym(handler, "QuitModule"));
|
||||||
|
|||||||
@@ -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,20 +2,26 @@
|
|||||||
|
|
||||||
class CoreInstance;
|
class CoreInstance;
|
||||||
|
|
||||||
|
struct CoreCallBacks;
|
||||||
|
|
||||||
namespace System {
|
namespace System {
|
||||||
/**
|
/**
|
||||||
* @throws std::exception if the operation finished with failed
|
* @throws std::exception if the operation finished with failed
|
||||||
* @return count CPU
|
* @return count CPU
|
||||||
*/
|
*/
|
||||||
int getCountCPU();
|
int getCountCPU();
|
||||||
unsigned long long getMemorySize();
|
/*
|
||||||
|
* @throws std::runtime_error
|
||||||
|
* @return memory size in MB
|
||||||
|
*/
|
||||||
|
double getMemorySize();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load module and init handler
|
* Load module and init handler
|
||||||
* @throws std::runtime_error if module not found
|
* @throws std::runtime_error if module not found
|
||||||
* @return module handler
|
* @return module handler
|
||||||
*/
|
*/
|
||||||
void* InitModule(const char* ModuleName, CoreInstance& core);
|
void* InitModule(const char* ModuleName, CoreCallBacks* callbacks);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start module
|
* Start module
|
||||||
@@ -23,12 +29,6 @@ namespace System {
|
|||||||
*/
|
*/
|
||||||
void StartModule(void* handler) noexcept(false);
|
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
|
* Call stop module
|
||||||
* @throws std::runtime_error if module not contains QuitModule function
|
* @throws std::runtime_error if module not contains QuitModule function
|
||||||
|
|||||||
+5
-14
@@ -33,15 +33,15 @@ int System::getCountCPU() {
|
|||||||
return physicalCoreCount;
|
return physicalCoreCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long long System::getMemorySize() {
|
double System::getMemorySize() {
|
||||||
MEMORYSTATUSEX memStatus{};
|
MEMORYSTATUSEX memStatus{};
|
||||||
memStatus.dwLength = sizeof(memStatus);
|
memStatus.dwLength = sizeof(memStatus);
|
||||||
|
|
||||||
GlobalMemoryStatusEx(&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;
|
std::string fileName = ModuleName;
|
||||||
fileName += ".dll";
|
fileName += ".dll";
|
||||||
|
|
||||||
@@ -49,11 +49,11 @@ void* System::InitModule(const char* ModuleName, CoreInstance& core) {
|
|||||||
if(hModule == nullptr)
|
if(hModule == nullptr)
|
||||||
throw std::runtime_error(std::to_string(GetLastError()).c_str());
|
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) {
|
if(load == nullptr) {
|
||||||
throw std::runtime_error(std::to_string(GetLastError()).c_str());
|
throw std::runtime_error(std::to_string(GetLastError()).c_str());
|
||||||
}
|
}
|
||||||
load(core);
|
load(callbacks);
|
||||||
|
|
||||||
return hModule;
|
return hModule;
|
||||||
}
|
}
|
||||||
@@ -66,15 +66,6 @@ void System::StartModule(void* handler) {
|
|||||||
start();
|
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 System::QuitModule(void* handler) {
|
||||||
void(*quit)() = reinterpret_cast<void(*)()>(GetProcAddress(static_cast<HMODULE>(handler), "QuitModule"));
|
void(*quit)() = reinterpret_cast<void(*)()>(GetProcAddress(static_cast<HMODULE>(handler), "QuitModule"));
|
||||||
if(quit == nullptr) {
|
if(quit == nullptr) {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "Core/CoreInstance.h"
|
#include "Core/CoreInstance.h"
|
||||||
#include "Core/RenderEngine.h"
|
|
||||||
#include "Game/WorldFactory.h"
|
#include "Game/WorldFactory.h"
|
||||||
#include "SaveMap/SaveMap.h"
|
#include "SaveMap/SaveMap.h"
|
||||||
#include "Game/World/World.h"
|
#include "Game/World/World.h"
|
||||||
@@ -15,8 +14,6 @@ extern std::vector<WorldFactory> world_factories;
|
|||||||
|
|
||||||
GameInstance::GameInstance(CoreInstance& core) : core(core)
|
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();
|
const std::string& base_world = core.getBaseWorldName();
|
||||||
|
|
||||||
// Init directories
|
// Init directories
|
||||||
@@ -51,7 +48,6 @@ GameInstance::~GameInstance()
|
|||||||
|
|
||||||
void GameInstance::start()
|
void GameInstance::start()
|
||||||
{
|
{
|
||||||
render_engine_->start();
|
|
||||||
world->BeginPlay();
|
world->BeginPlay();
|
||||||
|
|
||||||
auto first = std::chrono::steady_clock::now();
|
auto first = std::chrono::steady_clock::now();
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
class CoreInstance;
|
class CoreInstance;
|
||||||
class World;
|
class World;
|
||||||
class RenderEngine;
|
|
||||||
|
|
||||||
#define GENERATE_FACTORY_GAME_INSTANCE(Class) \
|
#define GENERATE_FACTORY_GAME_INSTANCE(Class) \
|
||||||
GameInstance* GameFactory(CoreInstance& core) { return new Class(core); }
|
GameInstance* GameFactory(CoreInstance& core) { return new Class(core); }
|
||||||
@@ -14,7 +13,6 @@ class GameInstance
|
|||||||
{
|
{
|
||||||
CoreInstance& core;
|
CoreInstance& core;
|
||||||
World* world = nullptr;
|
World* world = nullptr;
|
||||||
std::unique_ptr<RenderEngine> render_engine_;
|
|
||||||
|
|
||||||
std::atomic<bool> is_running = true;
|
std::atomic<bool> is_running = true;
|
||||||
|
|
||||||
|
|||||||
@@ -49,17 +49,17 @@ SaveMap::SaveMap(const std::string& json_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (name[0] == 'i') {
|
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);
|
size_t end = i = json_data.find_first_of(",}", i);
|
||||||
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);
|
save_long[name.c_str() + 1] = std::stoll(value);
|
||||||
} else if (name[0] == 'd')
|
} 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);
|
size_t end = i = json_data.find_first_of(",}", i);
|
||||||
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);
|
save_double[name.c_str() + 1] = std::stod(value);
|
||||||
} else if (name[0] == 's')
|
} else if (name[0] == 's')
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,14 +3,18 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
ModuleInstance::ModuleInstance(CoreInstance& core) : core_(core)
|
#include "Core/CoreCallBacks.h"
|
||||||
{
|
|
||||||
// Init instance
|
extern ModuleInstance* Factory();
|
||||||
}
|
|
||||||
|
static std::mutex mModuleInstance;
|
||||||
|
static ModuleInstance* module = nullptr;
|
||||||
|
static std::thread* moduleThread;
|
||||||
|
// Don't free. It's memory free in core
|
||||||
|
static CoreCallBacks* callbacks_;
|
||||||
|
|
||||||
void ModuleInstance::start()
|
void ModuleInstance::start()
|
||||||
{
|
{
|
||||||
// Create thread
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleInstance::stop()
|
void ModuleInstance::stop()
|
||||||
@@ -18,51 +22,36 @@ void ModuleInstance::stop()
|
|||||||
onStop.Call();
|
onStop.Call();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModuleInstance::QuitGame()
|
||||||
extern ModuleInstance* Factory(CoreInstance&);
|
|
||||||
|
|
||||||
static std::mutex mModuleInstance;
|
|
||||||
static ModuleInstance* module = nullptr;
|
|
||||||
static std::thread* moduleThread;
|
|
||||||
|
|
||||||
void InitModule(CoreInstance& core)
|
|
||||||
{
|
{
|
||||||
mModuleInstance.lock();
|
callbacks_->Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitModule(CoreCallBacks* callbacks)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mModuleInstance);
|
||||||
|
callbacks_ = callbacks;
|
||||||
if(module == nullptr)
|
if(module == nullptr)
|
||||||
module = Factory(core);
|
module = Factory();
|
||||||
mModuleInstance.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartModule()
|
void StartModule()
|
||||||
{
|
{
|
||||||
mModuleInstance.lock();
|
std::lock_guard<std::mutex> lock(mModuleInstance);
|
||||||
if (module != nullptr)
|
if (module != nullptr)
|
||||||
moduleThread = new std::thread([&] {module->start(); });
|
moduleThread = new std::thread(&ModuleInstance::start, module);
|
||||||
mModuleInstance.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StopModule()
|
|
||||||
{
|
|
||||||
mModuleInstance.lock();
|
|
||||||
if(module != nullptr)
|
|
||||||
{
|
|
||||||
delete module;
|
|
||||||
module = nullptr;
|
|
||||||
moduleThread->detach();
|
|
||||||
delete moduleThread;
|
|
||||||
}
|
|
||||||
mModuleInstance.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuitModule()
|
void QuitModule()
|
||||||
{
|
{
|
||||||
mModuleInstance.lock();
|
std::lock_guard<std::mutex> lock(mModuleInstance);
|
||||||
if(module != nullptr)
|
if(module != nullptr)
|
||||||
{
|
{
|
||||||
module->stop();
|
module->stop();
|
||||||
moduleThread->join();
|
moduleThread->join();
|
||||||
delete module;
|
delete module;
|
||||||
module = nullptr;
|
module = nullptr;
|
||||||
|
delete moduleThread;
|
||||||
|
moduleThread = nullptr;
|
||||||
}
|
}
|
||||||
mModuleInstance.unlock();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,39 +17,31 @@
|
|||||||
extern "C" {\
|
extern "C" {\
|
||||||
EXPORT void* protect_init() {return reinterpret_cast<void*>(&InitModule);} \
|
EXPORT void* protect_init() {return reinterpret_cast<void*>(&InitModule);} \
|
||||||
EXPORT void* protect_start() {return reinterpret_cast<void*>(&StartModule);} \
|
EXPORT void* protect_start() {return reinterpret_cast<void*>(&StartModule);} \
|
||||||
EXPORT void* protect_stop() {return reinterpret_cast<void*>(&StopModule);} \
|
|
||||||
EXPORT void* protect_quit() {return reinterpret_cast<void*>(&QuitModule);} \
|
EXPORT void* protect_quit() {return reinterpret_cast<void*>(&QuitModule);} \
|
||||||
}\
|
}\
|
||||||
ModuleInstance* Factory(CoreInstance& core) { return static_cast<ModuleInstance*>(new Class(core)); }
|
ModuleInstance* Factory() { return static_cast<ModuleInstance*>(new Class()); }
|
||||||
|
|
||||||
|
struct CoreCallBacks;
|
||||||
class CoreInstance;
|
|
||||||
|
|
||||||
class ModuleInstance {
|
class ModuleInstance {
|
||||||
CoreInstance& core_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Delegate<void> onStop;
|
Delegate<void> onStop;
|
||||||
|
|
||||||
ModuleInstance(CoreInstance& core);
|
|
||||||
virtual ~ModuleInstance() = default;
|
virtual ~ModuleInstance() = default;
|
||||||
|
|
||||||
CoreInstance& getCore() const { return core_; }
|
|
||||||
|
|
||||||
virtual void start();
|
virtual void start();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
void QuitGame();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// Create module instance
|
// Create module instance
|
||||||
EXPORT void InitModule(CoreInstance& core);
|
EXPORT void InitModule(CoreCallBacks* callbacks);
|
||||||
|
|
||||||
// Start module instance
|
// Start module instance
|
||||||
EXPORT void StartModule();
|
EXPORT void StartModule();
|
||||||
|
|
||||||
// Destroy module instance when core unloads there
|
|
||||||
EXPORT void StopModule();
|
|
||||||
|
|
||||||
// Stop module when core calls this
|
// Stop module when core calls this
|
||||||
EXPORT void QuitModule();
|
EXPORT void QuitModule();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
find_package(Vulkan REQUIRED)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE SRC "*.cpp" "*.c" "*.h" "*.hpp")
|
||||||
|
add_library(RenderModule SHARED ${SRC})
|
||||||
|
|
||||||
|
target_compile_features(RenderModule PRIVATE cxx_std_17)
|
||||||
|
|
||||||
|
target_include_directories(RenderModule
|
||||||
|
PRIVATE
|
||||||
|
${PROJECT_SOURCE_DIR}/ModuleLib
|
||||||
|
${PROJECT_SOURCE_DIR}/Core
|
||||||
|
${PROJECT_SOURCE_DIR}/FastRTTI
|
||||||
|
${PROJECT_SOURCE_DIR}/Delegate
|
||||||
|
${PROJECT_SOURCE_DIR}/glfw/Include
|
||||||
|
${Vulkan_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(RenderModule PRIVATE
|
||||||
|
ModuleLib
|
||||||
|
FastRTTI
|
||||||
|
glfw
|
||||||
|
Vulkan::Vulkan
|
||||||
|
)
|
||||||
@@ -2,9 +2,14 @@
|
|||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Core/CoreInstance.h"
|
||||||
|
|
||||||
|
PROTECTION_FROM_GB(RenderEngine)
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#include "Log/Log.h"
|
//#include "Log/Log.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#define VK_CHECK(res) assert(res == VK_SUCCESS)
|
#define VK_CHECK(res) assert(res == VK_SUCCESS)
|
||||||
|
|
||||||
@@ -16,7 +21,7 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
|
|||||||
|
|
||||||
std::string msg = "validation layer: ";
|
std::string msg = "validation layer: ";
|
||||||
msg += pCallbackData->pMessage;
|
msg += pCallbackData->pMessage;
|
||||||
Log(msg);
|
//Log(msg);
|
||||||
|
|
||||||
return VK_FALSE;
|
return VK_FALSE;
|
||||||
}
|
}
|
||||||
@@ -42,32 +47,15 @@ std::vector<const char*> RenderEngine::get_required_extensions()
|
|||||||
return extensions;
|
return extensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderEngine::render_thread_func()
|
RenderEngine::RenderEngine() : window(nullptr)
|
||||||
{
|
|
||||||
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
|
#ifdef _DEBUG
|
||||||
, debug_messenger_(nullptr)
|
, debug_messenger_(nullptr)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (!glfwInit())
|
onStop.bind(this, &RenderEngine::stop_render);
|
||||||
throw std::runtime_error("Fail initialize GLFW");
|
|
||||||
|
if (glfwInit() == GLFW_FALSE)
|
||||||
|
throw std::runtime_error("Fail init glfw");
|
||||||
|
|
||||||
{
|
{
|
||||||
std::vector<const char*> extensions = get_required_extensions();
|
std::vector<const char*> extensions = get_required_extensions();
|
||||||
@@ -80,10 +68,10 @@ RenderEngine::RenderEngine(const std::string& app_name,
|
|||||||
VkApplicationInfo app_info{};
|
VkApplicationInfo app_info{};
|
||||||
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||||
app_info.apiVersion = VK_API_VERSION_1_0;
|
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.applicationVersion = VK_MAKE_VERSION(0, 0, 0);
|
||||||
app_info.pApplicationName = app_name.c_str();
|
app_info.pApplicationName = "UwU Engine";
|
||||||
app_info.pEngineName = "UwU Engine";
|
app_info.pEngineName = "UwU Engine";
|
||||||
app_info.engineVersion = VK_MAKE_VERSION(major_engine_version, minor_engine_version, patch_engine_version);
|
app_info.engineVersion = VK_MAKE_VERSION(0, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
VkInstanceCreateInfo instance_create_info{};
|
VkInstanceCreateInfo instance_create_info{};
|
||||||
@@ -123,15 +111,6 @@ RenderEngine::RenderEngine(const std::string& app_name,
|
|||||||
|
|
||||||
RenderEngine::~RenderEngine()
|
RenderEngine::~RenderEngine()
|
||||||
{
|
{
|
||||||
if (window != nullptr && !glfwWindowShouldClose(window))
|
|
||||||
glfwSetWindowShouldClose(window, true);
|
|
||||||
|
|
||||||
if (render_thread != nullptr)
|
|
||||||
{
|
|
||||||
render_thread->join();
|
|
||||||
delete render_thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (debug_messenger_ != nullptr && instance_ != nullptr) {
|
if (debug_messenger_ != nullptr && instance_ != nullptr) {
|
||||||
PFN_vkDestroyDebugUtilsMessengerEXT destroyer_messenger = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT>(vkGetInstanceProcAddr(instance_, "vkDestroyDebugUtilsMessengerEXT"));
|
PFN_vkDestroyDebugUtilsMessengerEXT destroyer_messenger = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT>(vkGetInstanceProcAddr(instance_, "vkDestroyDebugUtilsMessengerEXT"));
|
||||||
@@ -149,5 +128,23 @@ RenderEngine::~RenderEngine()
|
|||||||
|
|
||||||
void RenderEngine::start()
|
void RenderEngine::start()
|
||||||
{
|
{
|
||||||
render_thread = new std::thread(&RenderEngine::render_thread_func, this);
|
window = glfwCreateWindow(640, 480, "UwU Engine", nullptr, nullptr);
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
glfwTerminate();
|
||||||
|
throw std::runtime_error("Fail create window");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!glfwWindowShouldClose(window))
|
||||||
|
{
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
QuitGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderEngine::stop_render()
|
||||||
|
{
|
||||||
|
if (window != nullptr && !glfwWindowShouldClose(window))
|
||||||
|
glfwSetWindowShouldClose(window, true);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define GLFW_INCLUDE_VULKAN
|
||||||
|
#include "GLFW/glfw3.h"
|
||||||
|
|
||||||
|
#include "ModuleInstance.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class Delegate;
|
||||||
|
|
||||||
|
class RenderEngine : public ModuleInstance
|
||||||
|
{
|
||||||
|
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 stop_render();
|
||||||
|
public:
|
||||||
|
RenderEngine();
|
||||||
|
~RenderEngine() override;
|
||||||
|
|
||||||
|
void start() override;
|
||||||
|
};
|
||||||
@@ -1 +1 @@
|
|||||||
{"Class name":"MainConfig","sgame_name":"Test Game","sbase_world":"TestWorld","vsmodules_names":[]}
|
{"Class name":"MainConfig","dmin_memory_size":"4096.0","imin_CPU_count":"1","sgame_name":"Test Game","sbase_world":"TestWorld","vsmodules_names":["RenderModule"]}
|
||||||
Reference in New Issue
Block a user