Quick and dirty task pool for scheduling back to main thread

This commit is contained in:
Georg Hagen
2024-12-10 23:43:58 +01:00
parent b961eb47fe
commit 6ca7329f7a
5 changed files with 132 additions and 0 deletions

View File

@@ -194,6 +194,7 @@ namespace OpenVulkano
{
auto start = clock::now();
inputManager->Tick();
mainThreadTaskPool.Tick();
app->Tick();
if (CURRENT_FRAME.needsRedraw)
{

View File

@@ -12,6 +12,7 @@
#include "Base/UI/IWindow.hpp"
#include "Base/PlatformEnums.hpp"
#include "Base/Timer.hpp"
#include "Threading/TaskPool.hpp"
#include <string>
#include <memory>
@@ -43,6 +44,7 @@ namespace OpenVulkano
std::string windowTitleFormat;
Input::InputManager* inputManager;
EngineConfiguration* engineConfig;
MainThreadTaskPool mainThreadTaskPool;
private:
void OnCappedFPS(const auto& frameStartTime);

View File

@@ -0,0 +1,30 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <functional>
namespace OpenVulkano
{
class Task
{
public:
virtual ~Task() = default;
virtual void Execute() {}
};
class FunctionalTask final : public Task
{
std::function<void()> function;
public:
FunctionalTask(const std::function<void()>& function) : function(function) {}
FunctionalTask(std::function<void()>&& function) : function(std::move(function)) {}
~FunctionalTask() override = default;
void Execute() override { function(); }
};
}

View File

@@ -0,0 +1,12 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "TaskPool.hpp"
namespace OpenVulkano
{
MainThreadTaskPool* MainThreadTaskPool::INSTANCE;
}

View File

@@ -0,0 +1,87 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "Task.hpp"
#include "Base/Logger.hpp"
#include "Base/Wrapper.hpp"
#include <concurrentqueue.h>
namespace OpenVulkano
{
class ITaskPool
{
protected:
void ExecuteTask(const Ptr<Task>& task)
{
try
{
task->Execute();
}
catch(const std::exception& e)
{
Logger::MANAGER->error("Failed to execute task! With exception: {}", e.what());
}
catch(...)
{
Logger::MANAGER->error("Failed to execute task! With unknown throwable");
}
}
public:
/*template<class T, typename... Args>
void EmplaceTask(Args&&... args)
{
m_tasks.enqueue(std::make_shared<T>((std::forward<Args>(args)...)));
}*/
virtual void Enqueue(const Ptr<Task>& task) = 0;
void Enqueue(const std::function<void()>& taskFunction)
{
Enqueue(std::make_shared<FunctionalTask>(taskFunction));
}
void operator +=(const std::function<void()>& taskFunction)
{
Enqueue(taskFunction);
}
};
class MainThreadTaskPool final : public ITaskPool
{
static MainThreadTaskPool* INSTANCE;
moodycamel::ConcurrentQueue<Ptr<Task>> m_tasks;
public:
MainThreadTaskPool()
{
if (!INSTANCE) INSTANCE = this;
}
~MainThreadTaskPool()
{
if (INSTANCE == this) INSTANCE = nullptr;
}
static MainThreadTaskPool& GetInstance() { return *INSTANCE; }
void Tick()
{
Ptr<Task> task;
while (m_tasks.try_dequeue(task))
{
ExecuteTask(task);
}
}
void Enqueue(const Ptr<Task>& task) override
{
m_tasks.enqueue(task);
}
};
}