mirror of
https://github.com/ApfelTeeSaft/WV-Core.git
synced 2026-08-26 19:43:26 +00:00
Merge branch 'master' into master
This commit is contained in:
@@ -12,15 +12,25 @@ namespace WillowVox
|
||||
extern int appDefaultWindowX;
|
||||
extern int appDefaultWindowY;
|
||||
|
||||
// This is the base application class
|
||||
// The project must create a subclass of this
|
||||
class App
|
||||
{
|
||||
public:
|
||||
App() = default;
|
||||
virtual ~App() = default;
|
||||
|
||||
// To be used by the engine. Starts the application
|
||||
void Run();
|
||||
|
||||
// Runs at the start of the project
|
||||
virtual void Start() {}
|
||||
// Runs every frame
|
||||
virtual void Update(const InputState& input) {}
|
||||
// Runs at the end of every frame for custom rendering code
|
||||
virtual void Render() {}
|
||||
|
||||
// Delta time between frames
|
||||
static float m_deltaTime;
|
||||
|
||||
// Access to platform and graphics context
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
// Entry point for the application
|
||||
// This must be included in the main.cpp file of the project.
|
||||
// CreateApp must be defined in the project.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wv/app/App.h>
|
||||
|
||||
@@ -4,9 +4,12 @@
|
||||
|
||||
namespace WillowVox
|
||||
{
|
||||
// If you want to support loading a new asset type T,
|
||||
// you need to create a template specialization of this struct
|
||||
template<typename T>
|
||||
struct AssetLoader
|
||||
{
|
||||
// Load asset of type T from given name (e.g., file path)
|
||||
static std::shared_ptr<T> Load(const std::string& name);
|
||||
};
|
||||
}
|
||||
@@ -6,11 +6,16 @@
|
||||
|
||||
namespace WillowVox
|
||||
{
|
||||
// Manages loading and providing assets of various types
|
||||
class AssetManager
|
||||
{
|
||||
public:
|
||||
static AssetManager& GetInstance();
|
||||
|
||||
// Get asset of type T by name
|
||||
// Loads the asset if not already loaded
|
||||
// Uses AssetLoader<T> to load the asset if needed. If you want to support loading a new asset type T,
|
||||
// you need to create a template specialization of AssetLoader
|
||||
template<typename T>
|
||||
std::shared_ptr<T> GetAsset(const std::string& name)
|
||||
{
|
||||
@@ -30,6 +35,8 @@ namespace WillowVox
|
||||
return provider->GetAsset(name);
|
||||
}
|
||||
|
||||
// Manually add asset of type T by name
|
||||
// This is usually not needed unless you want to pre-load assets or load runtime-generated assets
|
||||
template<typename T>
|
||||
void AddAsset(const std::string& name, std::shared_ptr<T> asset)
|
||||
{
|
||||
|
||||
@@ -10,10 +10,13 @@ namespace WillowVox
|
||||
public:
|
||||
};
|
||||
|
||||
// Provides assets of type T, loading them on demand
|
||||
template<typename T>
|
||||
class AssetProvider : public IAssetProvider
|
||||
{
|
||||
public:
|
||||
// Get asset of type T by name
|
||||
// Loads the asset if not already loaded
|
||||
std::shared_ptr<T> GetAsset(const std::string& name)
|
||||
{
|
||||
auto it = m_assets.find(name);
|
||||
@@ -27,6 +30,8 @@ namespace WillowVox
|
||||
}
|
||||
}
|
||||
|
||||
// Add asset of type T by name
|
||||
// Used to manually add assets (e.g., pre-loaded or runtime-generated)
|
||||
void AddAsset(const std::string& name, std::shared_ptr<T> asset)
|
||||
{
|
||||
m_assets.emplace(name, asset);
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace WillowVox
|
||||
public:
|
||||
ElementBuffer();
|
||||
ElementBuffer(ElementBuffer&& other) noexcept;
|
||||
// Make sure destructor only runs on the main thread
|
||||
~ElementBuffer();
|
||||
|
||||
void Bind();
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace WillowVox
|
||||
static std::shared_ptr<Shader> FromSource(const char* vertexShaderCode, const char* fragmentShaderCode);
|
||||
|
||||
Shader(unsigned int programId) : _programId(programId) {}
|
||||
// Make sure destructor only runs on the main thread
|
||||
~Shader();
|
||||
|
||||
void Bind();
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace WillowVox
|
||||
{
|
||||
public:
|
||||
VertexArrayObject();
|
||||
// Make sure the destructor only runs on the main thread
|
||||
~VertexArrayObject();
|
||||
|
||||
void Bind();
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace WillowVox
|
||||
public:
|
||||
VertexBuffer();
|
||||
VertexBuffer(VertexBuffer&& other) noexcept;
|
||||
// Make sure destructor only runs on the main thread
|
||||
~VertexBuffer();
|
||||
|
||||
void Bind();
|
||||
|
||||
@@ -1,27 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <concurrentqueue.h>
|
||||
#include <blockingconcurrentqueue.h>
|
||||
#include <wv/wvpch.h>
|
||||
#include <atomic>
|
||||
#include <array>
|
||||
|
||||
namespace WillowVox
|
||||
{
|
||||
enum class Priority {
|
||||
High = 0,
|
||||
Medium = 1,
|
||||
Low = 2,
|
||||
Count = 3
|
||||
};
|
||||
|
||||
class ThreadPool
|
||||
{
|
||||
public:
|
||||
ThreadPool(int initialJobQueueCapacity);
|
||||
ThreadPool() = default;
|
||||
ThreadPool();
|
||||
~ThreadPool();
|
||||
void Start(int numThreads);
|
||||
void QueueJob(const std::function<void()>& job, bool highPriority = false);
|
||||
void Stop();
|
||||
void Enqueue(const std::function<void()>& job, Priority priority = Priority::Medium);
|
||||
|
||||
private:
|
||||
void ThreadLoop();
|
||||
|
||||
std::atomic<bool> m_shouldTerminate;
|
||||
std::condition_variable m_mutexCondition;
|
||||
// Queues for each priority
|
||||
std::array<moodycamel::ConcurrentQueue<std::function<void()>>, static_cast<int>(Priority::Count)> m_queues;
|
||||
// Queue to wake up threads when a job is queued
|
||||
moodycamel::BlockingConcurrentQueue<bool> m_signal;
|
||||
|
||||
std::vector<std::thread> m_threads;
|
||||
moodycamel::ConcurrentQueue<std::function<void()>> m_lowPriorityJobs;
|
||||
moodycamel::ConcurrentQueue<std::function<void()>> m_highPriorityJobs;
|
||||
std::atomic<bool> m_shouldTerminate;
|
||||
};
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
@@ -46,22 +46,22 @@ namespace WillowVox
|
||||
glVertexAttribPointer(index, attribSize, GL_HALF_FLOAT, normalized, vertexSize, (void*)offset);
|
||||
break;
|
||||
case VertexBufferAttribType::INT32:
|
||||
glVertexAttribPointer(index, attribSize, GL_INT, normalized, vertexSize, (void*)offset);
|
||||
glVertexAttribIPointer(index, attribSize, GL_INT, vertexSize, (void*)offset);
|
||||
break;
|
||||
case VertexBufferAttribType::UINT32:
|
||||
glVertexAttribPointer(index, attribSize, GL_UNSIGNED_INT, normalized, vertexSize, (void*)offset);
|
||||
glVertexAttribIPointer(index, attribSize, GL_UNSIGNED_INT, vertexSize, (void*)offset);
|
||||
break;
|
||||
case VertexBufferAttribType::INT16:
|
||||
glVertexAttribPointer(index, attribSize, GL_SHORT, normalized, vertexSize, (void*)offset);
|
||||
glVertexAttribIPointer(index, attribSize, GL_SHORT, vertexSize, (void*)offset);
|
||||
break;
|
||||
case VertexBufferAttribType::UINT16:
|
||||
glVertexAttribPointer(index, attribSize, GL_UNSIGNED_SHORT, normalized, vertexSize, (void*)offset);
|
||||
glVertexAttribIPointer(index, attribSize, GL_UNSIGNED_SHORT, vertexSize, (void*)offset);
|
||||
break;
|
||||
case VertexBufferAttribType::INT8:
|
||||
glVertexAttribPointer(index, attribSize, GL_BYTE, normalized, vertexSize, (void*)offset);
|
||||
glVertexAttribIPointer(index, attribSize, GL_BYTE, vertexSize, (void*)offset);
|
||||
break;
|
||||
case VertexBufferAttribType::UINT8:
|
||||
glVertexAttribPointer(index, attribSize, GL_UNSIGNED_BYTE, normalized, vertexSize, (void*)offset);
|
||||
glVertexAttribIPointer(index, attribSize, GL_UNSIGNED_BYTE, vertexSize, (void*)offset);
|
||||
break;
|
||||
}
|
||||
glEnableVertexAttribArray(index);
|
||||
|
||||
@@ -4,8 +4,23 @@
|
||||
|
||||
namespace WillowVox
|
||||
{
|
||||
ThreadPool::ThreadPool(int initialJobQueueCapacity = 0)
|
||||
: m_shouldTerminate(false), m_highPriorityJobs(initialJobQueueCapacity), m_lowPriorityJobs(initialJobQueueCapacity) {}
|
||||
ThreadPool::ThreadPool()
|
||||
: m_shouldTerminate(false) {}
|
||||
|
||||
ThreadPool::~ThreadPool()
|
||||
{
|
||||
m_shouldTerminate = true;
|
||||
|
||||
// Make sure all threads stop
|
||||
for (int i = 0; i < m_threads.size() * 2; i++)
|
||||
m_signal.enqueue(true);
|
||||
|
||||
// Join all threads
|
||||
for (std::thread& activeThread : m_threads)
|
||||
activeThread.join();
|
||||
|
||||
m_threads.clear();
|
||||
}
|
||||
|
||||
void ThreadPool::Start(int numThreads)
|
||||
{
|
||||
@@ -13,48 +28,41 @@ namespace WillowVox
|
||||
m_threads.emplace_back(std::thread(&ThreadPool::ThreadLoop, this));
|
||||
}
|
||||
|
||||
void ThreadPool::QueueJob(const std::function<void()>& job, bool highPriority)
|
||||
void ThreadPool::Enqueue(const std::function<void()>& job, Priority priority)
|
||||
{
|
||||
{
|
||||
if (highPriority)
|
||||
m_highPriorityJobs.enqueue(job);
|
||||
else
|
||||
m_lowPriorityJobs.enqueue(job);
|
||||
}
|
||||
//m_mutexCondition.notify_one();
|
||||
}
|
||||
|
||||
void ThreadPool::Stop()
|
||||
{
|
||||
m_shouldTerminate = true;
|
||||
|
||||
m_mutexCondition.notify_all();
|
||||
for (std::thread& activeThread : m_threads)
|
||||
activeThread.join();
|
||||
|
||||
m_threads.clear();
|
||||
// Enqueue the job
|
||||
m_queues[static_cast<int>(priority)].enqueue(job);
|
||||
// Wake up a worker thread to run the job
|
||||
m_signal.enqueue(true);
|
||||
}
|
||||
|
||||
void ThreadPool::ThreadLoop()
|
||||
{
|
||||
bool token;
|
||||
while (true)
|
||||
{
|
||||
std::function<void()> job;
|
||||
{
|
||||
/*m_mutexCondition.wait(lock, [this] {
|
||||
return !m_highPriorityJobs.() || !m_lowPriorityJobs.empty() || m_shouldTerminate;
|
||||
});*/
|
||||
// Wait for job to be enqueued
|
||||
m_signal.wait_dequeue(token);
|
||||
|
||||
// Stop early if necessary
|
||||
if (m_shouldTerminate)
|
||||
return;
|
||||
|
||||
bool jobFound = m_highPriorityJobs.try_dequeue(job);
|
||||
if (!jobFound)
|
||||
// Get job to run
|
||||
std::function<void()> job;
|
||||
bool found = false;
|
||||
|
||||
for (int i = 0; i < static_cast<int>(Priority::Count); i++)
|
||||
{
|
||||
jobFound = m_lowPriorityJobs.try_dequeue(job);
|
||||
if (!jobFound)
|
||||
continue;
|
||||
if (m_queues[i].try_dequeue(job))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Run job if found
|
||||
if (found && job)
|
||||
job();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user