#pragma once #include #include #include #include #include #include namespace sophia { /** * Every live SceneView. The application renders all enabled views each frame, * in ascending priority order, before the UI. */ class SceneViewRegistry { public: SceneViewRegistry(const SceneViewRegistry&) = delete; SceneViewRegistry& operator=(const SceneViewRegistry&) = delete; SceneViewRegistry() = default; ~SceneViewRegistry() = default; SceneViewHandle create(const SceneView& view = {}) { isRenderQueueDirty = true; return pool.create(view); } const SceneView& get(SceneViewHandle handle) const { return pool.get(handle); } SceneView& get(SceneViewHandle handle) { isRenderQueueDirty = true; return pool.get(handle); } void release(SceneViewHandle handle) { isRenderQueueDirty = true; pool.release(handle); } bool isAlive(SceneViewHandle handle) const { return pool.isAlive(handle); } u32 size() const { return pool.size(); } template void forEach(Fn&& fn) { isRenderQueueDirty = true; pool.forEach(std::forward(fn)); } template void forEach(Fn&& fn) const { pool.forEach(std::forward(fn)); } const std::vector& GetRenderQueue() const { if (isRenderQueueDirty) { rebuildRenderQueue(); } return renderQueue; } private: void rebuildRenderQueue() const { renderQueue.clear(); pool.forEachWithHandle([&](SceneViewHandle handle, const SceneView& view) { if (view.enabled) { renderQueue.push_back(handle); } }); std::ranges::stable_sort(renderQueue, {}, [this](SceneViewHandle handle) { return pool.get(handle).priority; }); isRenderQueueDirty = false; } Pool pool{"SceneView"}; mutable std::vector renderQueue; mutable bool isRenderQueueDirty = true; }; } // namespace sophia