diff --git a/include/hyprgraphics/resource/AsyncResourceGatherer.hpp b/include/hyprgraphics/resource/AsyncResourceGatherer.hpp index 1d3655d..922aa93 100644 --- a/include/hyprgraphics/resource/AsyncResourceGatherer.hpp +++ b/include/hyprgraphics/resource/AsyncResourceGatherer.hpp @@ -17,6 +17,9 @@ namespace Hyprgraphics { void enqueue(Hyprutils::Memory::CAtomicSharedPointer resource); + // Synchronously await the resource being available + void await(Hyprutils::Memory::CAtomicSharedPointer resource); + private: std::thread m_gatherThread; diff --git a/include/hyprgraphics/resource/resources/AsyncResource.hpp b/include/hyprgraphics/resource/resources/AsyncResource.hpp index 1479612..c1aa04a 100644 --- a/include/hyprgraphics/resource/resources/AsyncResource.hpp +++ b/include/hyprgraphics/resource/resources/AsyncResource.hpp @@ -7,9 +7,11 @@ #include namespace Hyprgraphics { + struct SAsyncResourceImpl; + class IAsyncResource { public: - IAsyncResource() = default; + IAsyncResource(); virtual ~IAsyncResource() = default; virtual void render() = 0; @@ -29,5 +31,7 @@ namespace Hyprgraphics { Hyprutils::Memory::CSharedPointer cairoSurface; Hyprutils::Math::Vector2D pixelSize; } m_asset; + + Hyprutils::Memory::CUniquePointer m_impl; }; } diff --git a/src/resource/AsyncResourceGatherer.cpp b/src/resource/AsyncResourceGatherer.cpp index 7ea058f..7e3e7de 100644 --- a/src/resource/AsyncResourceGatherer.cpp +++ b/src/resource/AsyncResourceGatherer.cpp @@ -1,4 +1,5 @@ #include +#include "resources/AsyncResource.hpp" using namespace Hyprgraphics; @@ -28,6 +29,13 @@ void CAsyncResourceGatherer::enqueue(Hyprutils::Memory::CAtomicSharedPointer resource) { + resource->m_impl->awaitingCv = Hyprutils::Memory::makeUnique(); + std::unique_lock lk(resource->m_impl->awaitingMtx); + resource->m_impl->awaitingCv->wait(lk, [&resource] { return resource->m_impl->awaitingEvent; }); + resource->m_impl->awaitingCv.reset(); +} + void CAsyncResourceGatherer::asyncAssetSpinLock() { while (!m_asyncLoopState.exit) { @@ -56,6 +64,10 @@ void CAsyncResourceGatherer::asyncAssetSpinLock() { for (auto& r : requests) { r->render(); + if (r->m_impl->awaitingCv) { + r->m_impl->awaitingEvent = true; + r->m_impl->awaitingCv->notify_all(); + } r->m_ready = true; r->m_events.finished.emit(); } diff --git a/src/resource/resources/AsyncResource.cpp b/src/resource/resources/AsyncResource.cpp new file mode 100644 index 0000000..f867f83 --- /dev/null +++ b/src/resource/resources/AsyncResource.cpp @@ -0,0 +1,8 @@ +#include "AsyncResource.hpp" + +using namespace Hyprgraphics; +using namespace Hyprutils::Memory; + +IAsyncResource::IAsyncResource() : m_impl(makeUnique()) { + ; +} \ No newline at end of file diff --git a/src/resource/resources/AsyncResource.hpp b/src/resource/resources/AsyncResource.hpp new file mode 100644 index 0000000..8a0c61b --- /dev/null +++ b/src/resource/resources/AsyncResource.hpp @@ -0,0 +1,11 @@ +#include + +#include + +namespace Hyprgraphics { + struct SAsyncResourceImpl { + Hyprutils::Memory::CUniquePointer awaitingCv; + std::mutex awaitingMtx; + bool awaitingEvent = false; + }; +} \ No newline at end of file