diff --git a/openVulkanoCpp/Host/GraphicsAppManager.cpp b/openVulkanoCpp/Host/GraphicsAppManager.cpp index 8457e07..9044561 100644 --- a/openVulkanoCpp/Host/GraphicsAppManager.cpp +++ b/openVulkanoCpp/Host/GraphicsAppManager.cpp @@ -194,6 +194,7 @@ namespace OpenVulkano { auto start = clock::now(); inputManager->Tick(); + mainThreadTaskPool.Tick(); app->Tick(); if (CURRENT_FRAME.needsRedraw) { diff --git a/openVulkanoCpp/Host/GraphicsAppManager.hpp b/openVulkanoCpp/Host/GraphicsAppManager.hpp index d48704a..2e7b77f 100644 --- a/openVulkanoCpp/Host/GraphicsAppManager.hpp +++ b/openVulkanoCpp/Host/GraphicsAppManager.hpp @@ -12,6 +12,7 @@ #include "Base/UI/IWindow.hpp" #include "Base/PlatformEnums.hpp" #include "Base/Timer.hpp" +#include "Threading/TaskPool.hpp" #include #include @@ -43,6 +44,7 @@ namespace OpenVulkano std::string windowTitleFormat; Input::InputManager* inputManager; EngineConfiguration* engineConfig; + MainThreadTaskPool mainThreadTaskPool; private: void OnCappedFPS(const auto& frameStartTime); diff --git a/openVulkanoCpp/Threading/Task.hpp b/openVulkanoCpp/Threading/Task.hpp new file mode 100644 index 0000000..e0effe4 --- /dev/null +++ b/openVulkanoCpp/Threading/Task.hpp @@ -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 + +namespace OpenVulkano +{ + class Task + { + public: + virtual ~Task() = default; + virtual void Execute() {} + }; + + class FunctionalTask final : public Task + { + std::function function; + + public: + FunctionalTask(const std::function& function) : function(function) {} + FunctionalTask(std::function&& function) : function(std::move(function)) {} + ~FunctionalTask() override = default; + void Execute() override { function(); } + }; +} diff --git a/openVulkanoCpp/Threading/TaskPool.cpp b/openVulkanoCpp/Threading/TaskPool.cpp new file mode 100644 index 0000000..4ead90c --- /dev/null +++ b/openVulkanoCpp/Threading/TaskPool.cpp @@ -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; +} \ No newline at end of file diff --git a/openVulkanoCpp/Threading/TaskPool.hpp b/openVulkanoCpp/Threading/TaskPool.hpp new file mode 100644 index 0000000..20ceec9 --- /dev/null +++ b/openVulkanoCpp/Threading/TaskPool.hpp @@ -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 + +namespace OpenVulkano +{ + class ITaskPool + { + protected: + void ExecuteTask(const Ptr& 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 + void EmplaceTask(Args&&... args) + { + m_tasks.enqueue(std::make_shared((std::forward(args)...))); + }*/ + + virtual void Enqueue(const Ptr& task) = 0; + + void Enqueue(const std::function& taskFunction) + { + Enqueue(std::make_shared(taskFunction)); + } + + void operator +=(const std::function& taskFunction) + { + Enqueue(taskFunction); + } + }; + + class MainThreadTaskPool final : public ITaskPool + { + static MainThreadTaskPool* INSTANCE; + moodycamel::ConcurrentQueue> m_tasks; + + public: + MainThreadTaskPool() + { + if (!INSTANCE) INSTANCE = this; + } + + ~MainThreadTaskPool() + { + if (INSTANCE == this) INSTANCE = nullptr; + } + + static MainThreadTaskPool& GetInstance() { return *INSTANCE; } + + void Tick() + { + Ptr task; + while (m_tasks.try_dequeue(task)) + { + ExecuteTask(task); + } + } + + void Enqueue(const Ptr& task) override + { + m_tasks.enqueue(task); + } + }; +}