coroutines truly are cursed
This commit is contained in:
@@ -104,7 +104,7 @@ void AssetRegistry::importTexture(const std::filesystem::path &filePath)
|
|||||||
|
|
||||||
void AssetRegistry::importMaterial(const std::filesystem::path &filePath)
|
void AssetRegistry::importMaterial(const std::filesystem::path &filePath)
|
||||||
{
|
{
|
||||||
materialLoader->queueAsset(filePath);
|
materialLoader->importAsset(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetRegistry::registerMesh(PMeshAsset mesh)
|
void AssetRegistry::registerMesh(PMeshAsset mesh)
|
||||||
|
|||||||
@@ -17,15 +17,22 @@ MaterialLoader::~MaterialLoader()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PMaterialAsset MaterialLoader::queueAsset(const std::filesystem::path& filePath)
|
void MaterialLoader::importAsset(const std::filesystem::path& name)
|
||||||
{
|
{
|
||||||
PMaterialAsset result = new MaterialAsset(filePath);
|
std::filesystem::path assetPath = name.filename();
|
||||||
result->load();
|
assetPath.replace_extension("asset");
|
||||||
graphics->getShaderCompiler()->registerMaterial(result);
|
PMaterialAsset asset = new MaterialAsset(assetPath.generic_string());
|
||||||
AssetRegistry::get().registerMaterial(result);
|
asset->setStatus(Asset::Status::Loading);
|
||||||
// TODO: There is actually no real reason to import a standalone material,
|
AssetRegistry::get().registerMaterial(asset);
|
||||||
// maybe in the future there could be a substance loader or something
|
import(name, asset);
|
||||||
return result;
|
}
|
||||||
|
|
||||||
|
Job MaterialLoader::import(std::filesystem::path, PMaterialAsset asset)
|
||||||
|
{
|
||||||
|
asset->load();
|
||||||
|
graphics->getShaderCompiler()->registerMaterial(asset);
|
||||||
|
AssetRegistry::get().registerMaterial(asset);
|
||||||
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PMaterialAsset MaterialLoader::getPlaceHolderMaterial()
|
PMaterialAsset MaterialLoader::getPlaceHolderMaterial()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
#include "Containers/List.h"
|
#include "Containers/List.h"
|
||||||
|
#include "ThreadPool.h"
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
@@ -14,9 +15,10 @@ class MaterialLoader
|
|||||||
public:
|
public:
|
||||||
MaterialLoader(Gfx::PGraphics graphic);
|
MaterialLoader(Gfx::PGraphics graphic);
|
||||||
~MaterialLoader();
|
~MaterialLoader();
|
||||||
PMaterialAsset queueAsset(const std::filesystem::path& filePath);
|
void importAsset(const std::filesystem::path& name);
|
||||||
PMaterialAsset getPlaceHolderMaterial();
|
PMaterialAsset getPlaceHolderMaterial();
|
||||||
private:
|
private:
|
||||||
|
Job import(std::filesystem::path filePath, PMaterialAsset asset);
|
||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
List<std::future<void>> futures;
|
List<std::future<void>> futures;
|
||||||
PMaterialAsset placeholderMaterial;
|
PMaterialAsset placeholderMaterial;
|
||||||
|
|||||||
@@ -30,9 +30,10 @@ void MeshLoader::importAsset(const std::filesystem::path &path)
|
|||||||
{
|
{
|
||||||
std::filesystem::path assetPath = path.filename();
|
std::filesystem::path assetPath = path.filename();
|
||||||
assetPath.replace_extension("asset");
|
assetPath.replace_extension("asset");
|
||||||
PMeshAsset meshAsset = new MeshAsset(assetPath.generic_string());
|
PMeshAsset asset = new MeshAsset(assetPath.generic_string());
|
||||||
AssetRegistry::get().registerMesh(meshAsset);
|
asset->setStatus(Asset::Status::Loading);
|
||||||
futures.add(std::async(std::launch::async, &MeshLoader::import, this, meshAsset, path));
|
AssetRegistry::get().registerMesh(asset);
|
||||||
|
import(path, asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials, Gfx::PGraphics graphics)
|
void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials, Gfx::PGraphics graphics)
|
||||||
@@ -228,7 +229,7 @@ void MeshLoader::loadTextures(const aiScene* scene, const std::filesystem::path&
|
|||||||
AssetRegistry::importFile(texPngPath.string());
|
AssetRegistry::importFile(texPngPath.string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void MeshLoader::import(PMeshAsset meshAsset, const std::filesystem::path &path)
|
Job MeshLoader::import(std::filesystem::path path, PMeshAsset meshAsset)
|
||||||
{
|
{
|
||||||
std::cout << "Starting to import "<<path << std::endl;
|
std::cout << "Starting to import "<<path << std::endl;
|
||||||
meshAsset->setStatus(Asset::Status::Loading);
|
meshAsset->setStatus(Asset::Status::Loading);
|
||||||
@@ -263,4 +264,5 @@ void MeshLoader::import(PMeshAsset meshAsset, const std::filesystem::path &path)
|
|||||||
meshAsset->setStatus(Asset::Status::Ready);
|
meshAsset->setStatus(Asset::Status::Ready);
|
||||||
meshAsset->save();
|
meshAsset->save();
|
||||||
std::cout << "Finished loading " << path << std::endl;
|
std::cout << "Finished loading " << path << std::endl;
|
||||||
|
co_return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
#include "Containers/List.h"
|
#include "Containers/List.h"
|
||||||
|
#include "ThreadPool.h"
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
@@ -25,7 +26,7 @@ private:
|
|||||||
void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials, Gfx::PGraphics graphics);
|
void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials, Gfx::PGraphics graphics);
|
||||||
void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels);
|
void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels);
|
||||||
|
|
||||||
void import(PMeshAsset meshAsset, const std::filesystem::path& path);
|
Job import(std::filesystem::path path, PMeshAsset meshAsset);
|
||||||
List<std::future<void>> futures;
|
List<std::future<void>> futures;
|
||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,20 +22,15 @@ TextureLoader::~TextureLoader()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureLoader::importAsset(const std::filesystem::path& filePath)
|
void TextureLoader::importAsset(const std::filesystem::path& path)
|
||||||
{
|
{
|
||||||
auto assetFileName = filePath;
|
std::filesystem::path assetPath = path.filename();
|
||||||
PTextureAsset asset = new TextureAsset(assetFileName.replace_extension("asset").filename().generic_string());
|
assetPath.replace_extension("asset");
|
||||||
|
PTextureAsset asset = new TextureAsset(assetPath.generic_string());
|
||||||
asset->setStatus(Asset::Status::Loading);
|
asset->setStatus(Asset::Status::Loading);
|
||||||
asset->setTexture(placeholderAsset->getTexture());
|
asset->setTexture(placeholderAsset->getTexture());
|
||||||
AssetRegistry::get().registerTexture(asset);
|
AssetRegistry::get().registerTexture(asset);
|
||||||
futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable {
|
import(path, asset);
|
||||||
using namespace std::chrono_literals;
|
|
||||||
//std::this_thread::sleep_for(5s);
|
|
||||||
import(filePath, asset);
|
|
||||||
asset->load();
|
|
||||||
asset->setStatus(Asset::Status::Ready);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PTextureAsset TextureLoader::getPlaceholderTexture()
|
PTextureAsset TextureLoader::getPlaceholderTexture()
|
||||||
@@ -43,7 +38,7 @@ PTextureAsset TextureLoader::getPlaceholderTexture()
|
|||||||
return placeholderAsset;
|
return placeholderAsset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureLoader::import(const std::filesystem::path& path, PTextureAsset textureAsset)
|
Job TextureLoader::import(std::filesystem::path path, PTextureAsset textureAsset)
|
||||||
{
|
{
|
||||||
int x, y, n;
|
int x, y, n;
|
||||||
unsigned char* data = stbi_load(path.string().c_str(), &x, &y, &n, 4);
|
unsigned char* data = stbi_load(path.string().c_str(), &x, &y, &n, 4);
|
||||||
@@ -72,4 +67,8 @@ void TextureLoader::import(const std::filesystem::path& path, PTextureAsset text
|
|||||||
|
|
||||||
ktxTexture_WriteToNamedFile(ktxTexture(kTexture), textureAsset->getFullPath().c_str());
|
ktxTexture_WriteToNamedFile(ktxTexture(kTexture), textureAsset->getFullPath().c_str());
|
||||||
ktxTexture_Destroy(ktxTexture(kTexture));
|
ktxTexture_Destroy(ktxTexture(kTexture));
|
||||||
|
|
||||||
|
textureAsset->load();
|
||||||
|
textureAsset->setStatus(Asset::Status::Ready);
|
||||||
|
co_return;
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
#include "Containers/List.h"
|
#include "Containers/List.h"
|
||||||
|
#include "ThreadPool.h"
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
@@ -18,7 +19,7 @@ public:
|
|||||||
void importAsset(const std::filesystem::path& filePath);
|
void importAsset(const std::filesystem::path& filePath);
|
||||||
PTextureAsset getPlaceholderTexture();
|
PTextureAsset getPlaceholderTexture();
|
||||||
private:
|
private:
|
||||||
void import(const std::filesystem::path& path, PTextureAsset asset);
|
Job import(std::filesystem::path path, PTextureAsset asset);
|
||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
List<std::future<void>> futures;
|
List<std::future<void>> futures;
|
||||||
PTextureAsset placeholderAsset;
|
PTextureAsset placeholderAsset;
|
||||||
|
|||||||
@@ -246,6 +246,20 @@ public:
|
|||||||
_size++;
|
_size++;
|
||||||
return insertedElement;
|
return insertedElement;
|
||||||
}
|
}
|
||||||
|
// takes all elements from other and move-inserts them into
|
||||||
|
// this, clearing other in the process
|
||||||
|
void moveElements(List& other){
|
||||||
|
tail->prev->next = other.root;
|
||||||
|
other.root->prev = tail->prev;
|
||||||
|
_size += other._size;
|
||||||
|
deallocateNode(tail);
|
||||||
|
tail = other.tail;
|
||||||
|
other._size = 0;
|
||||||
|
other.root = nullptr;
|
||||||
|
other.tail = nullptr;
|
||||||
|
markIteratorDirty();
|
||||||
|
other.markIteratorDirty();
|
||||||
|
}
|
||||||
template<typename... args>
|
template<typename... args>
|
||||||
constexpr reference emplace(args... arguments)
|
constexpr reference emplace(args... arguments)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "List.h"
|
#include "Array.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags u
|
|||||||
memRequirements.pNext = &dedicatedRequirements;
|
memRequirements.pNext = &dedicatedRequirements;
|
||||||
for (uint32 i = 0; i < numBuffers; ++i)
|
for (uint32 i = 0; i < numBuffers; ++i)
|
||||||
{
|
{
|
||||||
vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer);
|
VK_CHECK(vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer));
|
||||||
bufferReqInfo.buffer = buffers[i].buffer;
|
bufferReqInfo.buffer = buffers[i].buffer;
|
||||||
vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferReqInfo, &memRequirements);
|
vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferReqInfo, &memRequirements);
|
||||||
auto temp = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer);
|
auto temp = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer);
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#include "Containers/Map.h"
|
#include "Containers/Map.h"
|
||||||
#include "EngineTypes.h"
|
#include "EngineTypes.h"
|
||||||
#include "Math/Math.h"
|
#include "Math/Math.h"
|
||||||
//#include "ThreadPool.h"
|
|
||||||
|
|
||||||
#define DEFINE_REF(x) \
|
#define DEFINE_REF(x) \
|
||||||
typedef RefPtr<x> P##x; \
|
typedef RefPtr<x> P##x; \
|
||||||
@@ -80,23 +79,19 @@ public:
|
|||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline bool operator==(const RefObject &other) const
|
bool operator==(const RefObject &rhs) const
|
||||||
{
|
{
|
||||||
return handle == other.handle;
|
return handle == rhs.handle;
|
||||||
}
|
}
|
||||||
inline bool operator!=(const RefObject &other) const
|
auto operator<=>(const RefObject& rhs) const
|
||||||
{
|
{
|
||||||
return handle != other.handle;
|
return handle <=> rhs.handle;
|
||||||
}
|
|
||||||
inline bool operator<(const RefObject &other) const
|
|
||||||
{
|
|
||||||
return handle < other.handle;
|
|
||||||
}
|
}
|
||||||
void addRef()
|
void addRef()
|
||||||
{
|
{
|
||||||
refCount++;
|
refCount++;
|
||||||
}
|
}
|
||||||
inline void removeRef()
|
void removeRef()
|
||||||
{
|
{
|
||||||
refCount--;
|
refCount--;
|
||||||
if (refCount == 0)
|
if (refCount == 0)
|
||||||
@@ -235,17 +230,13 @@ public:
|
|||||||
object->removeRef();
|
object->removeRef();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline bool operator==(const RefPtr &other) const
|
bool operator==(const RefPtr& rhs) const
|
||||||
{
|
{
|
||||||
return object == other.object;
|
return object == rhs.object;
|
||||||
}
|
}
|
||||||
inline bool operator!=(const RefPtr &other) const
|
auto operator<=>(const RefPtr &rhs) const
|
||||||
{
|
{
|
||||||
return object != other.object;
|
return object <=> rhs.object;
|
||||||
}
|
|
||||||
bool operator<(const RefPtr &other) const
|
|
||||||
{
|
|
||||||
return object < other.object;
|
|
||||||
}
|
}
|
||||||
inline T *operator->()
|
inline T *operator->()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,12 +14,10 @@ Actor::~Actor()
|
|||||||
}
|
}
|
||||||
void Actor::tick(float deltaTime)
|
void Actor::tick(float deltaTime)
|
||||||
{
|
{
|
||||||
addWorldRotation(glm::vec3(0, 1 * deltaTime, 0));
|
|
||||||
}
|
}
|
||||||
void Actor::notifySceneAttach(PScene scene)
|
void Actor::notifySceneAttach(PScene scene)
|
||||||
{
|
{
|
||||||
owningScene = scene;
|
owningScene = scene;
|
||||||
scene->getSceneUpdater()->registerActorUpdate(this);
|
|
||||||
rootComponent->notifySceneAttach(scene);
|
rootComponent->notifySceneAttach(scene);
|
||||||
for(auto child : children)
|
for(auto child : children)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
target_sources(SeeleEngine
|
target_sources(SeeleEngine
|
||||||
PRIVATE
|
PRIVATE
|
||||||
Scene.cpp
|
Scene.cpp
|
||||||
Scene.h
|
Scene.h)
|
||||||
SceneUpdater.h
|
|
||||||
SceneUpdater.cpp)
|
|
||||||
|
|
||||||
add_subdirectory(Actor/)
|
add_subdirectory(Actor/)
|
||||||
add_subdirectory(Components/)
|
add_subdirectory(Components/)
|
||||||
@@ -36,7 +36,6 @@ PActor Component::getOwner()
|
|||||||
void Component::notifySceneAttach(PScene scene)
|
void Component::notifySceneAttach(PScene scene)
|
||||||
{
|
{
|
||||||
owningScene = scene;
|
owningScene = scene;
|
||||||
scene->getSceneUpdater()->registerComponentUpdate(this);
|
|
||||||
for (auto child : children)
|
for (auto child : children)
|
||||||
{
|
{
|
||||||
child->notifySceneAttach(scene);
|
child->notifySceneAttach(scene);
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ inline float frand()
|
|||||||
|
|
||||||
Scene::Scene(Gfx::PGraphics graphics)
|
Scene::Scene(Gfx::PGraphics graphics)
|
||||||
: graphics(graphics)
|
: graphics(graphics)
|
||||||
, updater(new SceneUpdater())
|
|
||||||
{
|
{
|
||||||
lightEnv.directionalLights[0].color = Vector4(1, 1, 1, 1);
|
lightEnv.directionalLights[0].color = Vector4(1, 1, 1, 1);
|
||||||
lightEnv.directionalLights[0].direction = Vector4(1, 1, 0, 1);
|
lightEnv.directionalLights[0].direction = Vector4(1, 1, 0, 1);
|
||||||
@@ -36,7 +35,6 @@ Scene::~Scene()
|
|||||||
|
|
||||||
void Scene::tick(double deltaTime)
|
void Scene::tick(double deltaTime)
|
||||||
{
|
{
|
||||||
updater->runUpdates(static_cast<float>(deltaTime));
|
|
||||||
for(auto &&meshBatch : staticMeshes)
|
for(auto &&meshBatch : staticMeshes)
|
||||||
{
|
{
|
||||||
meshBatch.material->updateDescriptorData();
|
meshBatch.material->updateDescriptorData();
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include "Graphics/GraphicsResources.h"
|
#include "Graphics/GraphicsResources.h"
|
||||||
#include "Components/PrimitiveComponent.h"
|
#include "Components/PrimitiveComponent.h"
|
||||||
#include "Graphics/MeshBatch.h"
|
#include "Graphics/MeshBatch.h"
|
||||||
#include "SceneUpdater.h"
|
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
@@ -46,13 +45,11 @@ public:
|
|||||||
const Array<PPrimitiveComponent>& getPrimitives() const { return primitives; }
|
const Array<PPrimitiveComponent>& getPrimitives() const { return primitives; }
|
||||||
const Array<StaticMeshBatch>& getStaticMeshes() const { return staticMeshes; }
|
const Array<StaticMeshBatch>& getStaticMeshes() const { return staticMeshes; }
|
||||||
const LightEnv& getLightBuffer() const { return lightEnv; }
|
const LightEnv& getLightBuffer() const { return lightEnv; }
|
||||||
UPSceneUpdater& getSceneUpdater() { return updater; }
|
|
||||||
private:
|
private:
|
||||||
Array<StaticMeshBatch> staticMeshes;
|
Array<StaticMeshBatch> staticMeshes;
|
||||||
Array<PActor> rootActors;
|
Array<PActor> rootActors;
|
||||||
Array<PPrimitiveComponent> primitives;
|
Array<PPrimitiveComponent> primitives;
|
||||||
LightEnv lightEnv;
|
LightEnv lightEnv;
|
||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
UPSceneUpdater updater;
|
|
||||||
};
|
};
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
#include "Containers/List.h"
|
#include "Containers/List.h"
|
||||||
#include <semaphore>
|
#include <semaphore>
|
||||||
|
//DEPRECATED
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
DECLARE_REF(Component);
|
DECLARE_REF(Component);
|
||||||
|
|||||||
+34
-10
@@ -46,42 +46,53 @@ ThreadPool::~ThreadPool()
|
|||||||
void ThreadPool::addJob(Job&& job)
|
void ThreadPool::addJob(Job&& job)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(jobQueueLock);
|
std::unique_lock lock(jobQueueLock);
|
||||||
jobQueue.add(job);
|
//std::cout << "Adding job " << job << std::endl;
|
||||||
|
jobQueue.add(std::move(job));
|
||||||
|
jobQueueCV.notify_one();
|
||||||
}
|
}
|
||||||
void ThreadPool::addJob(MainJob&& job)
|
void ThreadPool::addJob(MainJob&& job)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(mainJobLock);
|
std::unique_lock lock(mainJobLock);
|
||||||
mainJobs.add(job);
|
//std::cout << "Adding main job " << job << std::endl;
|
||||||
|
mainJobs.add(std::move(job));
|
||||||
|
mainJobCV.notify_one();
|
||||||
}
|
}
|
||||||
void ThreadPool::enqueueWaiting(Event* event, Job&& job)
|
void ThreadPool::enqueueWaiting(Event* event, Job&& job)
|
||||||
{
|
{
|
||||||
|
//std::cout << job << " waiting for event " << event->name << std::endl;
|
||||||
std::unique_lock lock(waitingLock);
|
std::unique_lock lock(waitingLock);
|
||||||
waitingJobs[event].add(std::move(job));
|
waitingJobs[*event].add(std::move(job));
|
||||||
}
|
}
|
||||||
void ThreadPool::enqueueWaiting(Event* event, MainJob&& job)
|
void ThreadPool::enqueueWaiting(Event* event, MainJob&& job)
|
||||||
{
|
{
|
||||||
|
//std::cout << job << " main waiting for event " << event->name << std::endl;
|
||||||
std::unique_lock lock(waitingMainLock);
|
std::unique_lock lock(waitingMainLock);
|
||||||
waitingMainJobs[event].add(std::move(job));
|
waitingMainJobs[*event].add(std::move(job));
|
||||||
}
|
}
|
||||||
void ThreadPool::notify(Event* event)
|
void ThreadPool::notify(Event* event)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::unique_lock lock(jobQueueLock);
|
std::unique_lock lock(jobQueueLock);
|
||||||
std::unique_lock lock2(waitingLock);
|
std::unique_lock lock2(waitingLock);
|
||||||
for(auto&& job : waitingJobs[event])
|
for(Job& job : waitingJobs[*event])
|
||||||
{
|
{
|
||||||
jobQueue.add(job);
|
//std::cout << "Waking up job " << job << std::endl;
|
||||||
|
jobQueue.add(std::move(job));
|
||||||
|
jobQueueCV.notify_one();
|
||||||
}
|
}
|
||||||
waitingJobs[event].clear();
|
waitingJobs[*event].clear();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::unique_lock lock(mainJobLock);
|
std::unique_lock lock(mainJobLock);
|
||||||
std::unique_lock lock2(waitingMainLock);
|
std::unique_lock lock2(waitingMainLock);
|
||||||
for(auto&& job : waitingMainJobs[event])
|
auto&& jobsToQueue = std::move(waitingMainJobs[*event]);
|
||||||
|
waitingMainJobs.erase(*event);
|
||||||
|
for(MainJob& job : jobsToQueue)
|
||||||
{
|
{
|
||||||
mainJobs.add(job);
|
//std::cout << "Waking up main job " << job << std::endl;
|
||||||
|
mainJobs.add(std::move(job));
|
||||||
|
mainJobCV.notify_one();
|
||||||
}
|
}
|
||||||
waitingMainJobs[event].clear();
|
|
||||||
}
|
}
|
||||||
event->reset();
|
event->reset();
|
||||||
}
|
}
|
||||||
@@ -95,9 +106,22 @@ void ThreadPool::threadLoop(const bool mainThread)
|
|||||||
if(!mainJobs.empty())
|
if(!mainJobs.empty())
|
||||||
{
|
{
|
||||||
MainJob&& job = mainJobs.retrieve();
|
MainJob&& job = mainJobs.retrieve();
|
||||||
|
lock.unlock();
|
||||||
job.resume();
|
job.resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::unique_lock lock(jobQueueLock);
|
||||||
|
if(jobQueue.empty())
|
||||||
|
{
|
||||||
|
jobQueueCV.wait(lock);
|
||||||
|
}
|
||||||
|
if(!jobQueue.empty())
|
||||||
|
{
|
||||||
|
Job&& job = jobQueue.retrieve();
|
||||||
|
lock.unlock();
|
||||||
|
//std::cout << "Starting job " << job << std::endl;
|
||||||
|
job.resume();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+51
-6
@@ -30,16 +30,49 @@ struct JobBase
|
|||||||
public:
|
public:
|
||||||
using promise_type = JobPromiseBase<MainJob>;
|
using promise_type = JobPromiseBase<MainJob>;
|
||||||
|
|
||||||
|
explicit JobBase()
|
||||||
|
{}
|
||||||
explicit JobBase(std::coroutine_handle<promise_type> handle)
|
explicit JobBase(std::coroutine_handle<promise_type> handle)
|
||||||
: handle(handle)
|
: handle(handle)
|
||||||
{}
|
{
|
||||||
|
std::cout << "Creating job " << handle.address() << std::endl;
|
||||||
|
}
|
||||||
|
JobBase(const JobBase & rhs) = delete;
|
||||||
|
JobBase(JobBase&& rhs)
|
||||||
|
: handle(std::move(rhs.handle))
|
||||||
|
{
|
||||||
|
rhs.handle = nullptr;
|
||||||
|
}
|
||||||
~JobBase()
|
~JobBase()
|
||||||
{
|
{
|
||||||
if(handle)
|
if(handle)
|
||||||
{
|
{
|
||||||
|
std::cout << "Destroying job " << handle.address() << std::endl;
|
||||||
handle.destroy();
|
handle.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
JobBase& operator=(const JobBase& rhs) = delete;
|
||||||
|
JobBase& operator=(JobBase&& rhs)
|
||||||
|
{
|
||||||
|
if(this != &rhs)
|
||||||
|
{
|
||||||
|
handle = std::move(rhs.handle);
|
||||||
|
rhs.handle = nullptr;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
friend std::basic_ostream<char>& operator<<(std::basic_ostream<char>& stream, const JobBase& obj)
|
||||||
|
{
|
||||||
|
if (obj.handle == nullptr)
|
||||||
|
{
|
||||||
|
stream << nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stream << obj.handle.address();
|
||||||
|
}
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
void resume()
|
void resume()
|
||||||
{
|
{
|
||||||
handle.resume();
|
handle.resume();
|
||||||
@@ -56,6 +89,15 @@ struct Event
|
|||||||
public:
|
public:
|
||||||
Event();
|
Event();
|
||||||
Event(const std::string& name);
|
Event(const std::string& name);
|
||||||
|
auto operator<=>(const Event& other) const
|
||||||
|
{
|
||||||
|
return name <=> other.name;
|
||||||
|
}
|
||||||
|
Event operator co_await()
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void raise();
|
void raise();
|
||||||
void reset();
|
void reset();
|
||||||
bool await_ready();
|
bool await_ready();
|
||||||
@@ -65,6 +107,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
std::string name;
|
std::string name;
|
||||||
RefPtr<std::atomic_bool> flag;
|
RefPtr<std::atomic_bool> flag;
|
||||||
|
friend class ThreadPool;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThreadPool
|
class ThreadPool
|
||||||
@@ -84,14 +127,16 @@ private:
|
|||||||
|
|
||||||
List<MainJob> mainJobs;
|
List<MainJob> mainJobs;
|
||||||
std::mutex mainJobLock;
|
std::mutex mainJobLock;
|
||||||
|
std::condition_variable mainJobCV;
|
||||||
|
|
||||||
List<Job> jobQueue;
|
List<Job> jobQueue;
|
||||||
std::mutex jobQueueLock;
|
std::mutex jobQueueLock;
|
||||||
|
std::condition_variable jobQueueCV;
|
||||||
|
|
||||||
Map<Event*, List<Job>> waitingJobs;
|
Map<Event, List<Job>> waitingJobs;
|
||||||
std::mutex waitingLock;
|
std::mutex waitingLock;
|
||||||
|
|
||||||
Map<Event*, List<MainJob>> waitingMainJobs;
|
Map<Event, List<MainJob>> waitingMainJobs;
|
||||||
std::mutex waitingMainLock;
|
std::mutex waitingMainLock;
|
||||||
|
|
||||||
void threadLoop(const bool isMainThread);
|
void threadLoop(const bool isMainThread);
|
||||||
@@ -100,7 +145,7 @@ private:
|
|||||||
|
|
||||||
template<bool MainJob>
|
template<bool MainJob>
|
||||||
inline JobBase<MainJob> JobPromiseBase<MainJob>::get_return_object() noexcept {
|
inline JobBase<MainJob> JobPromiseBase<MainJob>::get_return_object() noexcept {
|
||||||
return JobBase<MainJob> { std::coroutine_handle<JobPromiseBase<MainJob>>::from_promise(*this) };
|
return JobBase<MainJob>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool MainJob>
|
template<bool MainJob>
|
||||||
@@ -111,7 +156,7 @@ inline auto JobPromiseBase<MainJob>::initial_suspend() const noexcept
|
|||||||
constexpr bool await_ready() { return false; }
|
constexpr bool await_ready() { return false; }
|
||||||
constexpr void await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h)
|
constexpr void await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h)
|
||||||
{
|
{
|
||||||
getGlobalThreadPool().addJob(JobBase<MainJob>(h));
|
getGlobalThreadPool().addJob(std::move(JobBase<MainJob>(h)));
|
||||||
}
|
}
|
||||||
constexpr void await_resume() {}
|
constexpr void await_resume() {}
|
||||||
};
|
};
|
||||||
@@ -121,7 +166,7 @@ inline auto JobPromiseBase<MainJob>::initial_suspend() const noexcept
|
|||||||
template<bool MainJob>
|
template<bool MainJob>
|
||||||
inline constexpr void Event::await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h)
|
inline constexpr void Event::await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h)
|
||||||
{
|
{
|
||||||
getGlobalThreadPool().enqueueWaiting(this, JobBase<MainJob>(h));
|
getGlobalThreadPool().enqueueWaiting(this, std::move(JobBase<MainJob>(h)));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ void Window::addView(PView view)
|
|||||||
{
|
{
|
||||||
WindowView* windowView = new WindowView();
|
WindowView* windowView = new WindowView();
|
||||||
windowView->view = view;
|
windowView->view = view;
|
||||||
|
windowView->updateFinished = Event("test");
|
||||||
//windowView->worker = std::thread(&Window::viewWorker, this, windowView);
|
//windowView->worker = std::thread(&Window::viewWorker, this, windowView);
|
||||||
views.add(windowView);
|
views.add(windowView);
|
||||||
|
viewWorker(views.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainJob Window::render()
|
MainJob Window::render()
|
||||||
@@ -27,8 +29,8 @@ MainJob Window::render()
|
|||||||
gfxHandle->beginFrame();
|
gfxHandle->beginFrame();
|
||||||
for(auto& windowView : views)
|
for(auto& windowView : views)
|
||||||
{
|
{
|
||||||
viewWorker(windowView);
|
|
||||||
co_await windowView->updateFinished;
|
co_await windowView->updateFinished;
|
||||||
|
std::cout << "view update finished" << std::endl;
|
||||||
{
|
{
|
||||||
std::unique_lock lock(windowView->workerMutex);
|
std::unique_lock lock(windowView->workerMutex);
|
||||||
windowView->view->prepareRender();
|
windowView->view->prepareRender();
|
||||||
@@ -36,6 +38,8 @@ MainJob Window::render()
|
|||||||
windowView->view->render();
|
windowView->view->render();
|
||||||
}
|
}
|
||||||
gfxHandle->endFrame();
|
gfxHandle->endFrame();
|
||||||
|
//Enqueue a new render main job
|
||||||
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::PWindow Window::getGfxHandle()
|
Gfx::PWindow Window::getGfxHandle()
|
||||||
@@ -60,17 +64,18 @@ void Window::setFocused(PView view)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Job Window::viewWorker(size_t viewIndex)
|
||||||
Job Window::viewWorker(WindowView* windowView)
|
|
||||||
{
|
|
||||||
while(true)
|
|
||||||
{
|
{
|
||||||
|
WindowView* windowView = views[viewIndex];
|
||||||
windowView->view->beginUpdate();
|
windowView->view->beginUpdate();
|
||||||
windowView->view->update();
|
windowView->view->update();
|
||||||
{
|
{
|
||||||
std::unique_lock lock(windowView->workerMutex);
|
std::unique_lock lock(windowView->workerMutex);
|
||||||
windowView->view->commitUpdate();
|
windowView->view->commitUpdate();
|
||||||
}
|
}
|
||||||
|
std::cout << "Update completed" << std::endl;
|
||||||
windowView->updateFinished.raise();
|
windowView->updateFinished.raise();
|
||||||
}
|
// enqueue next frame update
|
||||||
|
viewWorker(viewIndex);
|
||||||
|
co_return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ protected:
|
|||||||
Array<WindowView*> views;
|
Array<WindowView*> views;
|
||||||
Gfx::PWindow gfxHandle;
|
Gfx::PWindow gfxHandle;
|
||||||
|
|
||||||
Job viewWorker(WindowView* view);
|
Job viewWorker(size_t viewIndex);
|
||||||
};
|
};
|
||||||
DEFINE_REF(Window)
|
DEFINE_REF(Window)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -39,4 +39,9 @@ PWindow WindowManager::addWindow(const WindowCreateInfo &createInfo)
|
|||||||
void WindowManager::notifyWindowClosed(PWindow window)
|
void WindowManager::notifyWindowClosed(PWindow window)
|
||||||
{
|
{
|
||||||
windows.remove(windows.find(window));
|
windows.remove(windows.find(window));
|
||||||
|
if(windows.empty())
|
||||||
|
{
|
||||||
|
std::unique_lock lock(windowsLock);
|
||||||
|
windowsCV.notify_all();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class WindowManager
|
|||||||
public:
|
public:
|
||||||
WindowManager();
|
WindowManager();
|
||||||
~WindowManager();
|
~WindowManager();
|
||||||
|
Job init();
|
||||||
PWindow addWindow(const WindowCreateInfo &createInfo);
|
PWindow addWindow(const WindowCreateInfo &createInfo);
|
||||||
void notifyWindowClosed(PWindow window);
|
void notifyWindowClosed(PWindow window);
|
||||||
static Gfx::PGraphics getGraphics()
|
static Gfx::PGraphics getGraphics()
|
||||||
@@ -21,9 +22,16 @@ public:
|
|||||||
{
|
{
|
||||||
return windows.size();
|
return windows.size();
|
||||||
}
|
}
|
||||||
|
void waitForCompletion()
|
||||||
|
{
|
||||||
|
std::unique_lock lock(windowsLock);
|
||||||
|
windowsCV.wait(lock);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Array<PWindow> windows;
|
Array<PWindow> windows;
|
||||||
|
std::mutex windowsLock;
|
||||||
|
std::condition_variable windowsCV;
|
||||||
static Gfx::PGraphics graphics;
|
static Gfx::PGraphics graphics;
|
||||||
};
|
};
|
||||||
DEFINE_REF(WindowManager)
|
DEFINE_REF(WindowManager)
|
||||||
|
|||||||
+1
-3
@@ -34,9 +34,7 @@ int main()
|
|||||||
PInspectorView inspectorView = new InspectorView(windowManager->getGraphics(), window, inspectorViewInfo);
|
PInspectorView inspectorView = new InspectorView(windowManager->getGraphics(), window, inspectorViewInfo);
|
||||||
window->addView(inspectorView);
|
window->addView(inspectorView);
|
||||||
sceneView->setFocused();
|
sceneView->setFocused();
|
||||||
while(windowManager->isActive())
|
|
||||||
{
|
|
||||||
window->render();
|
window->render();
|
||||||
}
|
windowManager->waitForCompletion();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -40,4 +40,22 @@ BOOST_AUTO_TEST_CASE(basic_remove)
|
|||||||
BOOST_REQUIRE_EQUAL(list.size(), 2);
|
BOOST_REQUIRE_EQUAL(list.size(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(list_join)
|
||||||
|
{
|
||||||
|
List<int> list1;
|
||||||
|
List<int> list2;
|
||||||
|
list1.add(2);
|
||||||
|
list1.add(1);
|
||||||
|
list1.add(3);
|
||||||
|
list1.add(4);
|
||||||
|
list2.add(5);
|
||||||
|
list2.add(7);
|
||||||
|
list2.add(8);
|
||||||
|
list2.add(6);
|
||||||
|
list2.add(9);
|
||||||
|
list1.moveElements(list2);
|
||||||
|
BOOST_REQUIRE_EQUAL(list1.size(), 9);
|
||||||
|
BOOST_REQUIRE_EQUAL(list2.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
Reference in New Issue
Block a user