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)
|
||||
{
|
||||
materialLoader->queueAsset(filePath);
|
||||
materialLoader->importAsset(filePath);
|
||||
}
|
||||
|
||||
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);
|
||||
result->load();
|
||||
graphics->getShaderCompiler()->registerMaterial(result);
|
||||
AssetRegistry::get().registerMaterial(result);
|
||||
// TODO: There is actually no real reason to import a standalone material,
|
||||
// maybe in the future there could be a substance loader or something
|
||||
return result;
|
||||
std::filesystem::path assetPath = name.filename();
|
||||
assetPath.replace_extension("asset");
|
||||
PMaterialAsset asset = new MaterialAsset(assetPath.generic_string());
|
||||
asset->setStatus(Asset::Status::Loading);
|
||||
AssetRegistry::get().registerMaterial(asset);
|
||||
import(name, asset);
|
||||
}
|
||||
|
||||
Job MaterialLoader::import(std::filesystem::path, PMaterialAsset asset)
|
||||
{
|
||||
asset->load();
|
||||
graphics->getShaderCompiler()->registerMaterial(asset);
|
||||
AssetRegistry::get().registerMaterial(asset);
|
||||
co_return;
|
||||
}
|
||||
|
||||
PMaterialAsset MaterialLoader::getPlaceHolderMaterial()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Containers/List.h"
|
||||
#include "ThreadPool.h"
|
||||
#include <thread>
|
||||
#include <future>
|
||||
#include <filesystem>
|
||||
@@ -14,9 +15,10 @@ class MaterialLoader
|
||||
public:
|
||||
MaterialLoader(Gfx::PGraphics graphic);
|
||||
~MaterialLoader();
|
||||
PMaterialAsset queueAsset(const std::filesystem::path& filePath);
|
||||
void importAsset(const std::filesystem::path& name);
|
||||
PMaterialAsset getPlaceHolderMaterial();
|
||||
private:
|
||||
Job import(std::filesystem::path filePath, PMaterialAsset asset);
|
||||
Gfx::PGraphics graphics;
|
||||
List<std::future<void>> futures;
|
||||
PMaterialAsset placeholderMaterial;
|
||||
|
||||
@@ -30,9 +30,10 @@ void MeshLoader::importAsset(const std::filesystem::path &path)
|
||||
{
|
||||
std::filesystem::path assetPath = path.filename();
|
||||
assetPath.replace_extension("asset");
|
||||
PMeshAsset meshAsset = new MeshAsset(assetPath.generic_string());
|
||||
AssetRegistry::get().registerMesh(meshAsset);
|
||||
futures.add(std::async(std::launch::async, &MeshLoader::import, this, meshAsset, path));
|
||||
PMeshAsset asset = new MeshAsset(assetPath.generic_string());
|
||||
asset->setStatus(Asset::Status::Loading);
|
||||
AssetRegistry::get().registerMesh(asset);
|
||||
import(path, asset);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
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;
|
||||
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->save();
|
||||
std::cout << "Finished loading " << path << std::endl;
|
||||
co_return;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Containers/List.h"
|
||||
#include "ThreadPool.h"
|
||||
#include <thread>
|
||||
#include <future>
|
||||
#include <filesystem>
|
||||
@@ -25,7 +26,7 @@ private:
|
||||
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 import(PMeshAsset meshAsset, const std::filesystem::path& path);
|
||||
Job import(std::filesystem::path path, PMeshAsset meshAsset);
|
||||
List<std::future<void>> futures;
|
||||
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;
|
||||
PTextureAsset asset = new TextureAsset(assetFileName.replace_extension("asset").filename().generic_string());
|
||||
std::filesystem::path assetPath = path.filename();
|
||||
assetPath.replace_extension("asset");
|
||||
PTextureAsset asset = new TextureAsset(assetPath.generic_string());
|
||||
asset->setStatus(Asset::Status::Loading);
|
||||
asset->setTexture(placeholderAsset->getTexture());
|
||||
AssetRegistry::get().registerTexture(asset);
|
||||
futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable {
|
||||
using namespace std::chrono_literals;
|
||||
//std::this_thread::sleep_for(5s);
|
||||
import(filePath, asset);
|
||||
asset->load();
|
||||
asset->setStatus(Asset::Status::Ready);
|
||||
}));
|
||||
import(path, asset);
|
||||
}
|
||||
|
||||
PTextureAsset TextureLoader::getPlaceholderTexture()
|
||||
@@ -43,7 +38,7 @@ PTextureAsset TextureLoader::getPlaceholderTexture()
|
||||
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;
|
||||
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_Destroy(ktxTexture(kTexture));
|
||||
|
||||
textureAsset->load();
|
||||
textureAsset->setStatus(Asset::Status::Ready);
|
||||
co_return;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Containers/List.h"
|
||||
#include "ThreadPool.h"
|
||||
#include <thread>
|
||||
#include <future>
|
||||
#include <filesystem>
|
||||
@@ -18,7 +19,7 @@ public:
|
||||
void importAsset(const std::filesystem::path& filePath);
|
||||
PTextureAsset getPlaceholderTexture();
|
||||
private:
|
||||
void import(const std::filesystem::path& path, PTextureAsset asset);
|
||||
Job import(std::filesystem::path path, PTextureAsset asset);
|
||||
Gfx::PGraphics graphics;
|
||||
List<std::future<void>> futures;
|
||||
PTextureAsset placeholderAsset;
|
||||
|
||||
@@ -246,6 +246,20 @@ public:
|
||||
_size++;
|
||||
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>
|
||||
constexpr reference emplace(args... arguments)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include <utility>
|
||||
#include "List.h"
|
||||
#include "Array.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
@@ -51,7 +51,7 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags u
|
||||
memRequirements.pNext = &dedicatedRequirements;
|
||||
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;
|
||||
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);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "Containers/Map.h"
|
||||
#include "EngineTypes.h"
|
||||
#include "Math/Math.h"
|
||||
//#include "ThreadPool.h"
|
||||
|
||||
#define DEFINE_REF(x) \
|
||||
typedef RefPtr<x> P##x; \
|
||||
@@ -80,23 +79,19 @@ public:
|
||||
}
|
||||
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;
|
||||
}
|
||||
inline bool operator<(const RefObject &other) const
|
||||
{
|
||||
return handle < other.handle;
|
||||
return handle <=> rhs.handle;
|
||||
}
|
||||
void addRef()
|
||||
{
|
||||
refCount++;
|
||||
}
|
||||
inline void removeRef()
|
||||
void removeRef()
|
||||
{
|
||||
refCount--;
|
||||
if (refCount == 0)
|
||||
@@ -235,17 +230,13 @@ public:
|
||||
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;
|
||||
}
|
||||
bool operator<(const RefPtr &other) const
|
||||
{
|
||||
return object < other.object;
|
||||
return object <=> rhs.object;
|
||||
}
|
||||
inline T *operator->()
|
||||
{
|
||||
|
||||
@@ -14,12 +14,10 @@ Actor::~Actor()
|
||||
}
|
||||
void Actor::tick(float deltaTime)
|
||||
{
|
||||
addWorldRotation(glm::vec3(0, 1 * deltaTime, 0));
|
||||
}
|
||||
void Actor::notifySceneAttach(PScene scene)
|
||||
{
|
||||
owningScene = scene;
|
||||
scene->getSceneUpdater()->registerActorUpdate(this);
|
||||
rootComponent->notifySceneAttach(scene);
|
||||
for(auto child : children)
|
||||
{
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
target_sources(SeeleEngine
|
||||
PRIVATE
|
||||
Scene.cpp
|
||||
Scene.h
|
||||
SceneUpdater.h
|
||||
SceneUpdater.cpp)
|
||||
Scene.h)
|
||||
|
||||
add_subdirectory(Actor/)
|
||||
add_subdirectory(Components/)
|
||||
@@ -36,7 +36,6 @@ PActor Component::getOwner()
|
||||
void Component::notifySceneAttach(PScene scene)
|
||||
{
|
||||
owningScene = scene;
|
||||
scene->getSceneUpdater()->registerComponentUpdate(this);
|
||||
for (auto child : children)
|
||||
{
|
||||
child->notifySceneAttach(scene);
|
||||
|
||||
@@ -13,7 +13,6 @@ inline float frand()
|
||||
|
||||
Scene::Scene(Gfx::PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
, updater(new SceneUpdater())
|
||||
{
|
||||
lightEnv.directionalLights[0].color = Vector4(1, 1, 1, 1);
|
||||
lightEnv.directionalLights[0].direction = Vector4(1, 1, 0, 1);
|
||||
@@ -36,7 +35,6 @@ Scene::~Scene()
|
||||
|
||||
void Scene::tick(double deltaTime)
|
||||
{
|
||||
updater->runUpdates(static_cast<float>(deltaTime));
|
||||
for(auto &&meshBatch : staticMeshes)
|
||||
{
|
||||
meshBatch.material->updateDescriptorData();
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Components/PrimitiveComponent.h"
|
||||
#include "Graphics/MeshBatch.h"
|
||||
#include "SceneUpdater.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -46,13 +45,11 @@ public:
|
||||
const Array<PPrimitiveComponent>& getPrimitives() const { return primitives; }
|
||||
const Array<StaticMeshBatch>& getStaticMeshes() const { return staticMeshes; }
|
||||
const LightEnv& getLightBuffer() const { return lightEnv; }
|
||||
UPSceneUpdater& getSceneUpdater() { return updater; }
|
||||
private:
|
||||
Array<StaticMeshBatch> staticMeshes;
|
||||
Array<PActor> rootActors;
|
||||
Array<PPrimitiveComponent> primitives;
|
||||
LightEnv lightEnv;
|
||||
Gfx::PGraphics graphics;
|
||||
UPSceneUpdater updater;
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "MinimalEngine.h"
|
||||
#include "Containers/List.h"
|
||||
#include <semaphore>
|
||||
|
||||
//DEPRECATED
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(Component);
|
||||
|
||||
+34
-10
@@ -46,42 +46,53 @@ ThreadPool::~ThreadPool()
|
||||
void ThreadPool::addJob(Job&& job)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
//std::cout << job << " waiting for event " << event->name << std::endl;
|
||||
std::unique_lock lock(waitingLock);
|
||||
waitingJobs[event].add(std::move(job));
|
||||
waitingJobs[*event].add(std::move(job));
|
||||
}
|
||||
void ThreadPool::enqueueWaiting(Event* event, MainJob&& job)
|
||||
{
|
||||
//std::cout << job << " main waiting for event " << event->name << std::endl;
|
||||
std::unique_lock lock(waitingMainLock);
|
||||
waitingMainJobs[event].add(std::move(job));
|
||||
waitingMainJobs[*event].add(std::move(job));
|
||||
}
|
||||
void ThreadPool::notify(Event* event)
|
||||
{
|
||||
{
|
||||
std::unique_lock lock(jobQueueLock);
|
||||
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 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();
|
||||
}
|
||||
@@ -95,9 +106,22 @@ void ThreadPool::threadLoop(const bool mainThread)
|
||||
if(!mainJobs.empty())
|
||||
{
|
||||
MainJob&& job = mainJobs.retrieve();
|
||||
lock.unlock();
|
||||
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:
|
||||
using promise_type = JobPromiseBase<MainJob>;
|
||||
|
||||
explicit JobBase()
|
||||
{}
|
||||
explicit JobBase(std::coroutine_handle<promise_type> 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()
|
||||
{
|
||||
if(handle)
|
||||
{
|
||||
std::cout << "Destroying job " << handle.address() << std::endl;
|
||||
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()
|
||||
{
|
||||
handle.resume();
|
||||
@@ -56,6 +89,15 @@ struct Event
|
||||
public:
|
||||
Event();
|
||||
Event(const std::string& name);
|
||||
auto operator<=>(const Event& other) const
|
||||
{
|
||||
return name <=> other.name;
|
||||
}
|
||||
Event operator co_await()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
void raise();
|
||||
void reset();
|
||||
bool await_ready();
|
||||
@@ -65,6 +107,7 @@ public:
|
||||
private:
|
||||
std::string name;
|
||||
RefPtr<std::atomic_bool> flag;
|
||||
friend class ThreadPool;
|
||||
};
|
||||
|
||||
class ThreadPool
|
||||
@@ -84,14 +127,16 @@ private:
|
||||
|
||||
List<MainJob> mainJobs;
|
||||
std::mutex mainJobLock;
|
||||
std::condition_variable mainJobCV;
|
||||
|
||||
List<Job> jobQueue;
|
||||
std::mutex jobQueueLock;
|
||||
std::condition_variable jobQueueCV;
|
||||
|
||||
Map<Event*, List<Job>> waitingJobs;
|
||||
Map<Event, List<Job>> waitingJobs;
|
||||
std::mutex waitingLock;
|
||||
|
||||
Map<Event*, List<MainJob>> waitingMainJobs;
|
||||
Map<Event, List<MainJob>> waitingMainJobs;
|
||||
std::mutex waitingMainLock;
|
||||
|
||||
void threadLoop(const bool isMainThread);
|
||||
@@ -100,7 +145,7 @@ private:
|
||||
|
||||
template<bool MainJob>
|
||||
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>
|
||||
@@ -111,7 +156,7 @@ inline auto JobPromiseBase<MainJob>::initial_suspend() const noexcept
|
||||
constexpr bool await_ready() { return false; }
|
||||
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() {}
|
||||
};
|
||||
@@ -121,7 +166,7 @@ inline auto JobPromiseBase<MainJob>::initial_suspend() const noexcept
|
||||
template<bool MainJob>
|
||||
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
|
||||
|
||||
@@ -18,8 +18,10 @@ void Window::addView(PView view)
|
||||
{
|
||||
WindowView* windowView = new WindowView();
|
||||
windowView->view = view;
|
||||
windowView->updateFinished = Event("test");
|
||||
//windowView->worker = std::thread(&Window::viewWorker, this, windowView);
|
||||
views.add(windowView);
|
||||
views.add(windowView);
|
||||
viewWorker(views.size() - 1);
|
||||
}
|
||||
|
||||
MainJob Window::render()
|
||||
@@ -27,8 +29,8 @@ MainJob Window::render()
|
||||
gfxHandle->beginFrame();
|
||||
for(auto& windowView : views)
|
||||
{
|
||||
viewWorker(windowView);
|
||||
co_await windowView->updateFinished;
|
||||
std::cout << "view update finished" << std::endl;
|
||||
{
|
||||
std::unique_lock lock(windowView->workerMutex);
|
||||
windowView->view->prepareRender();
|
||||
@@ -36,6 +38,8 @@ MainJob Window::render()
|
||||
windowView->view->render();
|
||||
}
|
||||
gfxHandle->endFrame();
|
||||
//Enqueue a new render main job
|
||||
render();
|
||||
}
|
||||
|
||||
Gfx::PWindow Window::getGfxHandle()
|
||||
@@ -60,17 +64,18 @@ void Window::setFocused(PView view)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Job Window::viewWorker(WindowView* windowView)
|
||||
Job Window::viewWorker(size_t viewIndex)
|
||||
{
|
||||
while(true)
|
||||
WindowView* windowView = views[viewIndex];
|
||||
windowView->view->beginUpdate();
|
||||
windowView->view->update();
|
||||
{
|
||||
windowView->view->beginUpdate();
|
||||
windowView->view->update();
|
||||
{
|
||||
std::unique_lock lock(windowView->workerMutex);
|
||||
windowView->view->commitUpdate();
|
||||
}
|
||||
windowView->updateFinished.raise();
|
||||
std::unique_lock lock(windowView->workerMutex);
|
||||
windowView->view->commitUpdate();
|
||||
}
|
||||
std::cout << "Update completed" << std::endl;
|
||||
windowView->updateFinished.raise();
|
||||
// enqueue next frame update
|
||||
viewWorker(viewIndex);
|
||||
co_return;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ protected:
|
||||
Array<WindowView*> views;
|
||||
Gfx::PWindow gfxHandle;
|
||||
|
||||
Job viewWorker(WindowView* view);
|
||||
Job viewWorker(size_t viewIndex);
|
||||
};
|
||||
DEFINE_REF(Window)
|
||||
} // namespace Seele
|
||||
@@ -39,4 +39,9 @@ PWindow WindowManager::addWindow(const WindowCreateInfo &createInfo)
|
||||
void WindowManager::notifyWindowClosed(PWindow window)
|
||||
{
|
||||
windows.remove(windows.find(window));
|
||||
if(windows.empty())
|
||||
{
|
||||
std::unique_lock lock(windowsLock);
|
||||
windowsCV.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ class WindowManager
|
||||
public:
|
||||
WindowManager();
|
||||
~WindowManager();
|
||||
Job init();
|
||||
PWindow addWindow(const WindowCreateInfo &createInfo);
|
||||
void notifyWindowClosed(PWindow window);
|
||||
static Gfx::PGraphics getGraphics()
|
||||
@@ -21,9 +22,16 @@ public:
|
||||
{
|
||||
return windows.size();
|
||||
}
|
||||
void waitForCompletion()
|
||||
{
|
||||
std::unique_lock lock(windowsLock);
|
||||
windowsCV.wait(lock);
|
||||
}
|
||||
|
||||
private:
|
||||
Array<PWindow> windows;
|
||||
std::mutex windowsLock;
|
||||
std::condition_variable windowsCV;
|
||||
static Gfx::PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(WindowManager)
|
||||
|
||||
+2
-4
@@ -34,9 +34,7 @@ int main()
|
||||
PInspectorView inspectorView = new InspectorView(windowManager->getGraphics(), window, inspectorViewInfo);
|
||||
window->addView(inspectorView);
|
||||
sceneView->setFocused();
|
||||
while(windowManager->isActive())
|
||||
{
|
||||
window->render();
|
||||
}
|
||||
window->render();
|
||||
windowManager->waitForCompletion();
|
||||
return 0;
|
||||
}
|
||||
@@ -40,4 +40,22 @@ BOOST_AUTO_TEST_CASE(basic_remove)
|
||||
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()
|
||||
Reference in New Issue
Block a user