Files
sophia/engine/include/sophia/scene_view_registry.hpp
T
2026-09-25 20:23:12 -07:00

87 lines
2.0 KiB
C++

#pragma once
#include <algorithm>
#include <sophia/handles.hpp>
#include <sophia/scene_view.hpp>
#include <sophia/util/pool.hpp>
#include <utility>
#include <vector>
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 <typename Fn>
void forEach(Fn&& fn) {
isRenderQueueDirty = true;
pool.forEach(std::forward<Fn>(fn));
}
template <typename Fn>
void forEach(Fn&& fn) const {
pool.forEach(std::forward<Fn>(fn));
}
const std::vector<SceneViewHandle>& 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<SceneView> pool{"SceneView"};
mutable std::vector<SceneViewHandle> renderQueue;
mutable bool isRenderQueueDirty = true;
};
} // namespace sophia