Minor refactoring
This commit is contained in:
parent
4cc6971542
commit
dca38c986d
@ -109,6 +109,7 @@ namespace ZL
|
||||
, glContext(nullptr)
|
||||
, newTickCount(0)
|
||||
, lastTickCount(0)
|
||||
, planetObject(renderer, taskManager, mainThreadHandler)
|
||||
{
|
||||
projectiles.reserve(maxProjectiles);
|
||||
for (int i = 0; i < maxProjectiles; ++i) {
|
||||
@ -370,8 +371,6 @@ namespace ZL
|
||||
std::cout << "Init step 6 " << std::endl;
|
||||
planetObject.init();
|
||||
|
||||
planetObject.taskManager = &taskManager;
|
||||
|
||||
std::cout << "Init step 7 " << std::endl;
|
||||
//rockTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", CONST_ZIP_FILE));
|
||||
|
||||
@ -921,6 +920,7 @@ namespace ZL
|
||||
#endif
|
||||
}
|
||||
render();
|
||||
mainThreadHandler.processMainThreadTasks();
|
||||
}
|
||||
|
||||
void Game::handleDown(int mx, int my)
|
||||
|
||||
39
src/Game.h
39
src/Game.h
@ -12,7 +12,7 @@
|
||||
|
||||
namespace ZL {
|
||||
|
||||
|
||||
|
||||
struct BoxCoords
|
||||
{
|
||||
Vector3f pos;
|
||||
@ -29,9 +29,11 @@ namespace ZL {
|
||||
void update();
|
||||
void render();
|
||||
|
||||
|
||||
bool shouldExit() const { return Environment::exitGameLoop; }
|
||||
|
||||
Renderer renderer;
|
||||
TaskManager taskManager;
|
||||
MainThreadHandler mainThreadHandler;
|
||||
private:
|
||||
void processTickCount();
|
||||
void drawScene();
|
||||
@ -48,42 +50,16 @@ namespace ZL {
|
||||
|
||||
SDL_Window* window;
|
||||
SDL_GLContext glContext;
|
||||
Renderer renderer;
|
||||
|
||||
|
||||
|
||||
size_t newTickCount;
|
||||
size_t lastTickCount;
|
||||
|
||||
//std::shared_ptr<Texture> rockTexture;
|
||||
|
||||
|
||||
|
||||
std::vector<BoxCoords> boxCoordsArr;
|
||||
std::vector<VertexRenderStruct> boxRenderArr;
|
||||
|
||||
|
||||
//std::shared_ptr<Texture> buttonTexture;
|
||||
//VertexRenderStruct button;
|
||||
|
||||
//std::shared_ptr<Texture> musicVolumeBarTexture;
|
||||
//VertexRenderStruct musicVolumeBar;
|
||||
|
||||
//std::shared_ptr<Texture> musicVolumeBarButtonTexture;
|
||||
//VertexRenderStruct musicVolumeBarButton;
|
||||
|
||||
|
||||
//bool isDraggingVolume = false;
|
||||
/*
|
||||
float velocitySlider = 0.0f;
|
||||
float volumeBarMinX = 1190.0f;
|
||||
float volumeBarMaxX = 1200.0f;
|
||||
float volumeBarMinY = 100.0f;
|
||||
float volumeBarMaxY = 600.0f;*/
|
||||
//float musicVolumeBarButtonButtonCenterX = 1195.0f;
|
||||
//float musicVolumeBarButtonButtonRadius = 25.0f;
|
||||
//void UpdateVolumeFromMouse(int mouseX, int mouseY);
|
||||
//void UpdateVolumeKnob();
|
||||
|
||||
|
||||
static const size_t CONST_TIMER_INTERVAL = 10;
|
||||
static const size_t CONST_MAX_TIME_INTERVAL = 1000;
|
||||
|
||||
@ -111,8 +87,7 @@ namespace ZL {
|
||||
int maxProjectiles = 32;
|
||||
std::vector<Vector3f> shipLocalEmissionPoints;
|
||||
|
||||
TaskManager taskManager;
|
||||
|
||||
|
||||
bool shipAlive = true;
|
||||
bool gameOver = false;
|
||||
std::vector<bool> boxAlive;
|
||||
|
||||
@ -57,9 +57,11 @@ namespace ZL {
|
||||
return rot;
|
||||
}
|
||||
|
||||
PlanetObject::PlanetObject()
|
||||
PlanetObject::PlanetObject(Renderer& iRenderer, TaskManager& iTaskManager, MainThreadHandler& iMainThreadHandler)
|
||||
: renderer(iRenderer),
|
||||
taskManager(iTaskManager),
|
||||
mainThreadHandler(iMainThreadHandler)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PlanetObject::init() {
|
||||
@ -101,7 +103,7 @@ namespace ZL {
|
||||
float movementThreshold = 1.0f;
|
||||
if ((Environment::shipPosition - lastUpdatePos).squaredNorm() < movementThreshold * movementThreshold
|
||||
&& !triangleIndicesToDraw.empty()) {
|
||||
processMainThreadTasks(); // Все равно обрабатываем очередь OpenGL задач
|
||||
//processMainThreadTasks(); // Все равно обрабатываем очередь OpenGL задач
|
||||
return;
|
||||
}
|
||||
lastUpdatePos = Environment::shipPosition;
|
||||
@ -117,13 +119,13 @@ namespace ZL {
|
||||
planetStones.statuses[triIdx] = ChunkStatus::Generating;
|
||||
|
||||
// Отправляем тяжелую математику в TaskManager
|
||||
taskManager->EnqueueBackgroundTask([this, triIdx]() {
|
||||
taskManager.EnqueueBackgroundTask([this, triIdx]() {
|
||||
// Выполняется в фоновом потоке: только генерация геометрии в RAM
|
||||
float scaleModifier = 1.0f;
|
||||
VertexDataStruct generatedData = planetStones.inflateOneDataOnly(triIdx, scaleModifier);
|
||||
|
||||
// Передаем задачу на загрузку в GPU в очередь главного потока
|
||||
this->EnqueueMainThreadTask([this, triIdx, data = std::move(generatedData)]() mutable {
|
||||
this->mainThreadHandler.EnqueueMainThreadTask([this, triIdx, data = std::move(generatedData)]() mutable {
|
||||
// Проверяем актуальность: если треугольник всё еще в списке видимых
|
||||
auto it = std::find(triangleIndicesToDraw.begin(), triangleIndicesToDraw.end(), triIdx);
|
||||
if (it != triangleIndicesToDraw.end()) {
|
||||
@ -164,22 +166,7 @@ namespace ZL {
|
||||
triangleIndicesToDraw = std::move(newIndices);
|
||||
|
||||
// 5. Выполняем одну задачу из очереди OpenGL (RefreshVBO и т.д.)
|
||||
processMainThreadTasks();
|
||||
/*
|
||||
float movementThreshold = 1.0f;
|
||||
if ((Environment::shipPosition - lastUpdatePos).squaredNorm() < movementThreshold * movementThreshold && !triangleIndicesToDraw.empty()) {
|
||||
return;
|
||||
}
|
||||
lastUpdatePos = Environment::shipPosition;
|
||||
|
||||
auto newIndices = planetData.getTrianglesUnderCameraNew2(Environment::shipPosition);
|
||||
|
||||
// Сортировка важна для сравнения векторов
|
||||
std::sort(newIndices.begin(), newIndices.end());
|
||||
|
||||
if (newIndices != triangleIndicesToDraw) {
|
||||
triangleIndicesToDraw = std::move(newIndices);
|
||||
}*/
|
||||
//processMainThreadTasks();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
|
||||
namespace ZL {
|
||||
class TaskManager;
|
||||
class MainThreadHandler;
|
||||
|
||||
class PlanetObject {
|
||||
public:
|
||||
@ -42,10 +43,12 @@ namespace ZL {
|
||||
|
||||
Vector3f lastUpdatePos;
|
||||
|
||||
TaskManager* taskManager = nullptr;
|
||||
|
||||
// External items, set outside
|
||||
Renderer& renderer;
|
||||
TaskManager& taskManager;
|
||||
MainThreadHandler& mainThreadHandler;
|
||||
public:
|
||||
PlanetObject();
|
||||
PlanetObject(Renderer& iRenderer, TaskManager& iTaskManager, MainThreadHandler& iMainThreadHandler);
|
||||
|
||||
void init();
|
||||
void update(float deltaTimeMs);
|
||||
@ -56,32 +59,6 @@ namespace ZL {
|
||||
void drawAtmosphere(Renderer& renderer);
|
||||
|
||||
float distanceToPlanetSurface(const Vector3f& viewerPosition);
|
||||
|
||||
std::queue<std::function<void()>> mainThreadTasks;
|
||||
std::mutex mainThreadMutex;
|
||||
|
||||
void EnqueueMainThreadTask(std::function<void()> task) {
|
||||
std::lock_guard<std::mutex> lock(mainThreadMutex);
|
||||
mainThreadTasks.push(task);
|
||||
}
|
||||
|
||||
// Выполнение задач по одной (или пачкой) за кадр
|
||||
void processMainThreadTasks() {
|
||||
std::function<void()> task;
|
||||
|
||||
// Извлекаем только одну задачу, чтобы не блокировать update надолго
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mainThreadMutex);
|
||||
if (!mainThreadTasks.empty()) {
|
||||
task = std::move(mainThreadTasks.front());
|
||||
mainThreadTasks.pop();
|
||||
}
|
||||
}
|
||||
|
||||
if (task) {
|
||||
task(); // Здесь выполняется RefreshVBO или загрузка текстуры
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ZL
|
||||
@ -0,0 +1,50 @@
|
||||
#include "TaskManager.h"
|
||||
|
||||
|
||||
namespace ZL
|
||||
{
|
||||
|
||||
TaskManager::TaskManager(size_t threadCount) {
|
||||
workGuard = std::make_unique<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>>(ioContext.get_executor());
|
||||
|
||||
for (size_t i = 0; i < threadCount; ++i) {
|
||||
workers.emplace_back([this]() {
|
||||
ioContext.run();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void TaskManager::EnqueueBackgroundTask(std::function<void()> task) {
|
||||
boost::asio::post(ioContext, task);
|
||||
}
|
||||
|
||||
TaskManager::~TaskManager() {
|
||||
workGuard.reset(); // Ðàçðåøàåì ioContext.run() çàâåðøèòüñÿ, êîãäà çàäà÷ íå îñòàíåòñÿ
|
||||
ioContext.stop(); // Îïöèîíàëüíî: íåìåäëåííàÿ îñòàíîâêà
|
||||
for (auto& t : workers) {
|
||||
if (t.joinable()) t.join();
|
||||
}
|
||||
}
|
||||
|
||||
void MainThreadHandler::EnqueueMainThreadTask(std::function<void()> task) {
|
||||
std::lock_guard<std::mutex> lock(mainThreadMutex);
|
||||
mainThreadTasks.push(task);
|
||||
}
|
||||
|
||||
void MainThreadHandler::processMainThreadTasks() {
|
||||
std::function<void()> task;
|
||||
|
||||
// Èçâëåêàåì òîëüêî îäíó çàäà÷ó, ÷òîáû íå áëîêèðîâàòü update íàäîëãî
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mainThreadMutex);
|
||||
if (!mainThreadTasks.empty()) {
|
||||
task = std::move(mainThreadTasks.front());
|
||||
mainThreadTasks.pop();
|
||||
}
|
||||
}
|
||||
|
||||
if (task) {
|
||||
task(); // Çäåñü âûïîëíÿåòñÿ RefreshVBO èëè çàãðóçêà òåêñòóðû
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,8 @@
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
|
||||
|
||||
namespace ZL {
|
||||
|
||||
@ -14,30 +16,28 @@ namespace ZL {
|
||||
std::vector<std::thread> workers;
|
||||
|
||||
public:
|
||||
//TaskManager(size_t threadCount = std::thread::hardware_concurrency()) {
|
||||
TaskManager(size_t threadCount = 2) {
|
||||
workGuard = std::make_unique<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>>(ioContext.get_executor());
|
||||
|
||||
for (size_t i = 0; i < threadCount; ++i) {
|
||||
workers.emplace_back([this]() {
|
||||
ioContext.run();
|
||||
});
|
||||
}
|
||||
}
|
||||
//TaskManager(size_t threadCount = std::thread::hardware_concurrency());
|
||||
TaskManager(size_t threadCount = 2);
|
||||
|
||||
// Ìåòîä äëÿ äîáàâëåíèÿ ôîíîâîé çàäà÷è
|
||||
void EnqueueBackgroundTask(std::function<void()> task) {
|
||||
boost::asio::post(ioContext, task);
|
||||
}
|
||||
void EnqueueBackgroundTask(std::function<void()> task);
|
||||
|
||||
// Graceful shutdown
|
||||
~TaskManager() {
|
||||
workGuard.reset(); // Ðàçðåøàåì ioContext.run() çàâåðøèòüñÿ, êîãäà çàäà÷ íå îñòàíåòñÿ
|
||||
ioContext.stop(); // Îïöèîíàëüíî: íåìåäëåííàÿ îñòàíîâêà
|
||||
for (auto& t : workers) {
|
||||
if (t.joinable()) t.join();
|
||||
}
|
||||
}
|
||||
~TaskManager();
|
||||
};
|
||||
|
||||
|
||||
class MainThreadHandler
|
||||
{
|
||||
private:
|
||||
std::queue<std::function<void()>> mainThreadTasks;
|
||||
std::mutex mainThreadMutex;
|
||||
|
||||
public:
|
||||
void EnqueueMainThreadTask(std::function<void()> task);
|
||||
|
||||
// Âûïîëíåíèå çàäà÷ ïî îäíîé (èëè ïà÷êîé) çà êàäð
|
||||
void processMainThreadTasks();
|
||||
};
|
||||
|
||||
} // namespace ZL
|
||||
Loading…
Reference in New Issue
Block a user