mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
hwr: Store T in Slab directly
This commit is contained in:
parent
ccc10eadd0
commit
095aa635b0
3 changed files with 123 additions and 142 deletions
|
|
@ -11,9 +11,7 @@
|
|||
#include <glad/gl.h>
|
||||
|
||||
using namespace srb2;
|
||||
|
||||
using srb2::rhi::GlCorePlatform;
|
||||
using srb2::rhi::GlCoreRhi;
|
||||
using namespace rhi;
|
||||
|
||||
#if 1
|
||||
#define GL_ASSERT \
|
||||
|
|
@ -31,13 +29,6 @@ using srb2::rhi::GlCoreRhi;
|
|||
namespace
|
||||
{
|
||||
|
||||
template <typename D, typename B>
|
||||
std::unique_ptr<D, std::default_delete<D>> static_unique_ptr_cast(std::unique_ptr<B, std::default_delete<B>> ptr)
|
||||
{
|
||||
D* derived = static_cast<D*>(ptr.release());
|
||||
return std::unique_ptr<D, std::default_delete<D>>(derived, std::default_delete<D>());
|
||||
}
|
||||
|
||||
constexpr GLenum map_pixel_format(rhi::PixelFormat format)
|
||||
{
|
||||
switch (format)
|
||||
|
|
@ -399,69 +390,6 @@ constexpr GLenum map_uniform_format(rhi::UniformFormat format)
|
|||
}
|
||||
}
|
||||
|
||||
struct GlCoreTexture : public rhi::Texture
|
||||
{
|
||||
GLuint texture;
|
||||
rhi::TextureDesc desc;
|
||||
GlCoreTexture(GLuint texture, const rhi::TextureDesc& desc) noexcept : texture(texture), desc(desc) {}
|
||||
};
|
||||
|
||||
struct GlCoreBuffer : public rhi::Buffer
|
||||
{
|
||||
GLuint buffer;
|
||||
rhi::BufferDesc desc;
|
||||
GlCoreBuffer(GLuint buffer, const rhi::BufferDesc& desc) noexcept : buffer(buffer), desc(desc) {}
|
||||
};
|
||||
|
||||
struct GlCoreRenderPass : public rhi::RenderPass
|
||||
{
|
||||
rhi::RenderPassDesc desc;
|
||||
explicit GlCoreRenderPass(const rhi::RenderPassDesc& desc) noexcept : desc(desc) {}
|
||||
};
|
||||
|
||||
struct GlCoreRenderbuffer : public rhi::Renderbuffer
|
||||
{
|
||||
GLuint renderbuffer;
|
||||
|
||||
explicit GlCoreRenderbuffer(GLuint renderbuffer) noexcept : renderbuffer(renderbuffer) {}
|
||||
};
|
||||
|
||||
struct GlCoreUniformSet : public rhi::UniformSet
|
||||
{
|
||||
std::vector<rhi::UniformVariant> uniforms;
|
||||
};
|
||||
|
||||
struct GlCoreBindingSet : public rhi::BindingSet
|
||||
{
|
||||
GLuint vao;
|
||||
std::unordered_map<rhi::SamplerName, GLuint> textures {4};
|
||||
};
|
||||
|
||||
struct GlCorePipeline : public rhi::Pipeline
|
||||
{
|
||||
GLuint vertex_shader = 0;
|
||||
GLuint fragment_shader = 0;
|
||||
GLuint program = 0;
|
||||
std::unordered_map<rhi::VertexAttributeName, GLuint> attrib_locations {2};
|
||||
std::unordered_map<rhi::UniformName, GLuint> uniform_locations {2};
|
||||
std::unordered_map<rhi::SamplerName, GLuint> sampler_locations {2};
|
||||
rhi::PipelineDesc desc;
|
||||
};
|
||||
|
||||
struct GlCoreGraphicsContext : public rhi::GraphicsContext
|
||||
{
|
||||
};
|
||||
|
||||
struct GlCoreTransferContext : public rhi::TransferContext
|
||||
{
|
||||
};
|
||||
|
||||
struct GlCoreActiveUniform
|
||||
{
|
||||
GLenum type;
|
||||
GLuint location;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
GlCorePlatform::~GlCorePlatform() = default;
|
||||
|
|
@ -479,15 +407,16 @@ rhi::Handle<rhi::RenderPass> GlCoreRhi::create_render_pass(const rhi::RenderPass
|
|||
SRB2_ASSERT(graphics_context_active_ == false);
|
||||
|
||||
// GL has no formal render pass object
|
||||
return render_pass_slab_.insert(std::make_unique<GlCoreRenderPass>(desc));
|
||||
GlCoreRenderPass pass;
|
||||
pass.desc = desc;
|
||||
return render_pass_slab_.insert(std::move(pass));
|
||||
}
|
||||
|
||||
void GlCoreRhi::destroy_render_pass(rhi::Handle<rhi::RenderPass> handle)
|
||||
{
|
||||
SRB2_ASSERT(graphics_context_active_ == false);
|
||||
|
||||
std::unique_ptr<rhi::RenderPass> buffer = render_pass_slab_.remove(handle);
|
||||
std::unique_ptr<GlCoreRenderPass> casted(static_cast<GlCoreRenderPass*>(buffer.release()));
|
||||
render_pass_slab_.remove(handle);
|
||||
}
|
||||
|
||||
rhi::Handle<rhi::Texture> GlCoreRhi::create_texture(const rhi::TextureDesc& desc)
|
||||
|
|
@ -513,7 +442,10 @@ rhi::Handle<rhi::Texture> GlCoreRhi::create_texture(const rhi::TextureDesc& desc
|
|||
gl_->TexImage2D(GL_TEXTURE_2D, 0, internal_format, desc.width, desc.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
GL_ASSERT
|
||||
|
||||
return texture_slab_.insert(std::make_unique<GlCoreTexture>(name, desc));
|
||||
GlCoreTexture texture;
|
||||
texture.texture = name;
|
||||
texture.desc = desc;
|
||||
return texture_slab_.insert(std::move(texture));
|
||||
}
|
||||
|
||||
void GlCoreRhi::destroy_texture(rhi::Handle<rhi::Texture> handle)
|
||||
|
|
@ -521,8 +453,8 @@ void GlCoreRhi::destroy_texture(rhi::Handle<rhi::Texture> handle)
|
|||
SRB2_ASSERT(graphics_context_active_ == false);
|
||||
|
||||
SRB2_ASSERT(texture_slab_.is_valid(handle) == true);
|
||||
std::unique_ptr<GlCoreTexture> casted = static_unique_ptr_cast<GlCoreTexture>(texture_slab_.remove(handle));
|
||||
GLuint name = casted->texture;
|
||||
GlCoreTexture casted = texture_slab_.remove(handle);
|
||||
GLuint name = casted.texture;
|
||||
disposal_.push_back([this, name] { gl_->DeleteTextures(1, &name); });
|
||||
}
|
||||
|
||||
|
|
@ -544,7 +476,7 @@ void GlCoreRhi::update_texture(
|
|||
}
|
||||
|
||||
SRB2_ASSERT(texture_slab_.is_valid(texture) == true);
|
||||
auto& t = *static_cast<GlCoreTexture*>(&texture_slab_[texture]);
|
||||
auto& t = texture_slab_[texture];
|
||||
|
||||
GLenum format = GL_RGBA;
|
||||
GLenum type = GL_UNSIGNED_BYTE;
|
||||
|
|
@ -593,7 +525,10 @@ rhi::Handle<rhi::Buffer> GlCoreRhi::create_buffer(const rhi::BufferDesc& desc)
|
|||
gl_->BufferData(target, desc.size, nullptr, usage);
|
||||
GL_ASSERT
|
||||
|
||||
return buffer_slab_.insert(std::make_unique<GlCoreBuffer>(name, desc));
|
||||
GlCoreBuffer buffer;
|
||||
buffer.buffer = name;
|
||||
buffer.desc = desc;
|
||||
return buffer_slab_.insert(std::move(buffer));
|
||||
}
|
||||
|
||||
void GlCoreRhi::destroy_buffer(rhi::Handle<rhi::Buffer> handle)
|
||||
|
|
@ -602,8 +537,8 @@ void GlCoreRhi::destroy_buffer(rhi::Handle<rhi::Buffer> handle)
|
|||
|
||||
SRB2_ASSERT(buffer_slab_.is_valid(handle) == true);
|
||||
SRB2_ASSERT(graphics_context_active_ == false);
|
||||
std::unique_ptr<GlCoreBuffer> casted = static_unique_ptr_cast<GlCoreBuffer>(buffer_slab_.remove(handle));
|
||||
GLuint name = casted->buffer;
|
||||
GlCoreBuffer casted = buffer_slab_.remove(handle);
|
||||
GLuint name = casted.buffer;
|
||||
|
||||
disposal_.push_back([this, name] { gl_->DeleteBuffers(1, &name); });
|
||||
}
|
||||
|
|
@ -625,7 +560,7 @@ void GlCoreRhi::update_buffer_contents(
|
|||
}
|
||||
|
||||
SRB2_ASSERT(buffer_slab_.is_valid(handle) == true);
|
||||
auto& b = *static_cast<GlCoreBuffer*>(&buffer_slab_[handle]);
|
||||
auto& b = buffer_slab_[handle];
|
||||
|
||||
SRB2_ASSERT(offset < b.desc.size && offset + data.size() <= b.desc.size);
|
||||
|
||||
|
|
@ -660,7 +595,7 @@ GlCoreRhi::create_uniform_set(rhi::Handle<rhi::TransferContext> ctx, const rhi::
|
|||
uniform_set.uniforms.push_back(uniform);
|
||||
}
|
||||
|
||||
return uniform_set_slab_.insert(std::make_unique<GlCoreUniformSet>(std::move(uniform_set)));
|
||||
return uniform_set_slab_.insert(std::move(uniform_set));
|
||||
}
|
||||
|
||||
rhi::Handle<rhi::BindingSet> GlCoreRhi::create_binding_set(
|
||||
|
|
@ -674,7 +609,7 @@ rhi::Handle<rhi::BindingSet> GlCoreRhi::create_binding_set(
|
|||
SRB2_ASSERT(ctx.generation() == transfer_context_generation_);
|
||||
|
||||
SRB2_ASSERT(pipeline_slab_.is_valid(pipeline) == true);
|
||||
auto& pl = *static_cast<GlCorePipeline*>(&pipeline_slab_[pipeline]);
|
||||
auto& pl = pipeline_slab_[pipeline];
|
||||
|
||||
SRB2_ASSERT(info.vertex_buffers.size() == pl.desc.vertex_input.buffer_layouts.size());
|
||||
|
||||
|
|
@ -689,8 +624,7 @@ rhi::Handle<rhi::BindingSet> GlCoreRhi::create_binding_set(
|
|||
for (auto& attr_layout : pl.desc.vertex_input.attr_layouts)
|
||||
{
|
||||
SRB2_ASSERT(buffer_slab_.is_valid(info.vertex_buffers[attr_layout.buffer_index].vertex_buffer));
|
||||
auto& buf =
|
||||
*static_cast<GlCoreBuffer*>(&buffer_slab_[info.vertex_buffers[attr_layout.buffer_index].vertex_buffer]);
|
||||
auto& buf = buffer_slab_[info.vertex_buffers[attr_layout.buffer_index].vertex_buffer];
|
||||
SRB2_ASSERT(buf.desc.type == rhi::BufferType::kVertexBuffer);
|
||||
|
||||
auto& buffer_layout = pl.desc.vertex_input.buffer_layouts[attr_layout.buffer_index];
|
||||
|
|
@ -728,11 +662,11 @@ rhi::Handle<rhi::BindingSet> GlCoreRhi::create_binding_set(
|
|||
SRB2_ASSERT(binding.name == sampler_name);
|
||||
|
||||
SRB2_ASSERT(texture_slab_.is_valid(binding.texture));
|
||||
auto& tx = *static_cast<GlCoreTexture*>(&texture_slab_[binding.texture]);
|
||||
auto& tx = texture_slab_[binding.texture];
|
||||
binding_set.textures.insert({sampler_name, tx.texture});
|
||||
}
|
||||
|
||||
return binding_set_slab_.insert(std::make_unique<GlCoreBindingSet>(std::move(binding_set)));
|
||||
return binding_set_slab_.insert(std::move(binding_set));
|
||||
}
|
||||
|
||||
rhi::Handle<rhi::Renderbuffer> GlCoreRhi::create_renderbuffer(const rhi::RenderbufferDesc& desc)
|
||||
|
|
@ -748,7 +682,9 @@ rhi::Handle<rhi::Renderbuffer> GlCoreRhi::create_renderbuffer(const rhi::Renderb
|
|||
gl_->RenderbufferStorage(GL_RENDERBUFFER, map_pixel_format(desc.format), desc.width, desc.height);
|
||||
GL_ASSERT
|
||||
|
||||
return renderbuffer_slab_.insert(std::make_unique<GlCoreRenderbuffer>(GlCoreRenderbuffer {name}));
|
||||
GlCoreRenderbuffer rb;
|
||||
rb.renderbuffer = name;
|
||||
return renderbuffer_slab_.insert(std::move(rb));
|
||||
}
|
||||
|
||||
void GlCoreRhi::destroy_renderbuffer(rhi::Handle<rhi::Renderbuffer> handle)
|
||||
|
|
@ -756,9 +692,8 @@ void GlCoreRhi::destroy_renderbuffer(rhi::Handle<rhi::Renderbuffer> handle)
|
|||
SRB2_ASSERT(graphics_context_active_ == false);
|
||||
|
||||
SRB2_ASSERT(renderbuffer_slab_.is_valid(handle) == true);
|
||||
std::unique_ptr<GlCoreRenderbuffer> casted =
|
||||
static_unique_ptr_cast<GlCoreRenderbuffer>(renderbuffer_slab_.remove(handle));
|
||||
GLuint name = casted->renderbuffer;
|
||||
GlCoreRenderbuffer casted = renderbuffer_slab_.remove(handle);
|
||||
GLuint name = casted.renderbuffer;
|
||||
disposal_.push_back([this, name] { gl_->DeleteRenderbuffers(1, &name); });
|
||||
}
|
||||
|
||||
|
|
@ -1031,7 +966,7 @@ rhi::Handle<rhi::Pipeline> GlCoreRhi::create_pipeline(const PipelineDesc& desc)
|
|||
pipeline.fragment_shader = fragment;
|
||||
pipeline.program = program;
|
||||
|
||||
return pipeline_slab_.insert(std::make_unique<GlCorePipeline>(std::move(pipeline)));
|
||||
return pipeline_slab_.insert(std::move(pipeline));
|
||||
}
|
||||
|
||||
void GlCoreRhi::destroy_pipeline(rhi::Handle<rhi::Pipeline> handle)
|
||||
|
|
@ -1039,10 +974,10 @@ void GlCoreRhi::destroy_pipeline(rhi::Handle<rhi::Pipeline> handle)
|
|||
SRB2_ASSERT(graphics_context_active_ == false);
|
||||
|
||||
SRB2_ASSERT(pipeline_slab_.is_valid(handle) == true);
|
||||
std::unique_ptr<GlCorePipeline> casted = static_unique_ptr_cast<GlCorePipeline>(pipeline_slab_.remove(handle));
|
||||
GLuint vertex_shader = casted->vertex_shader;
|
||||
GLuint fragment_shader = casted->fragment_shader;
|
||||
GLuint program = casted->program;
|
||||
GlCorePipeline casted = pipeline_slab_.remove(handle);
|
||||
GLuint vertex_shader = casted.vertex_shader;
|
||||
GLuint fragment_shader = casted.fragment_shader;
|
||||
GLuint program = casted.program;
|
||||
|
||||
disposal_.push_back([this, fragment_shader] { gl_->DeleteShader(fragment_shader); });
|
||||
disposal_.push_back([this, vertex_shader] { gl_->DeleteShader(vertex_shader); });
|
||||
|
|
@ -1126,7 +1061,7 @@ void GlCoreRhi::begin_render_pass(Handle<GraphicsContext> ctx, const RenderPassB
|
|||
SRB2_ASSERT(current_render_pass_.has_value() == false);
|
||||
|
||||
SRB2_ASSERT(render_pass_slab_.is_valid(info.render_pass) == true);
|
||||
auto& rp = *static_cast<GlCoreRenderPass*>(&render_pass_slab_[info.render_pass]);
|
||||
auto& rp = render_pass_slab_[info.render_pass];
|
||||
SRB2_ASSERT(rp.desc.depth_format.has_value() == info.depth_attachment.has_value());
|
||||
|
||||
auto fb_itr = framebuffers_.find(GlCoreFramebufferKey {info.color_attachment, info.depth_attachment});
|
||||
|
|
@ -1150,14 +1085,14 @@ void GlCoreRhi::begin_render_pass(Handle<GraphicsContext> ctx, const RenderPassB
|
|||
[&, this](const Handle<Texture>& handle)
|
||||
{
|
||||
SRB2_ASSERT(texture_slab_.is_valid(handle));
|
||||
auto& texture = *static_cast<GlCoreTexture*>(&texture_slab_[handle]);
|
||||
auto& texture = texture_slab_[handle];
|
||||
gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.texture, 0);
|
||||
GL_ASSERT
|
||||
},
|
||||
[&, this](const Handle<Renderbuffer>& handle)
|
||||
{
|
||||
SRB2_ASSERT(renderbuffer_slab_.is_valid(handle));
|
||||
auto& renderbuffer = *static_cast<GlCoreRenderbuffer*>(&renderbuffer_slab_[handle]);
|
||||
auto& renderbuffer = renderbuffer_slab_[handle];
|
||||
gl_->FramebufferRenderbuffer(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
|
|
@ -1206,7 +1141,7 @@ void GlCoreRhi::bind_pipeline(Handle<GraphicsContext> ctx, Handle<Pipeline> pipe
|
|||
SRB2_ASSERT(current_render_pass_.has_value() == true);
|
||||
|
||||
SRB2_ASSERT(pipeline_slab_.is_valid(pipeline) == true);
|
||||
auto& pl = *static_cast<GlCorePipeline*>(&pipeline_slab_[pipeline]);
|
||||
auto& pl = pipeline_slab_[pipeline];
|
||||
auto& desc = pl.desc;
|
||||
|
||||
gl_->UseProgram(pl.program);
|
||||
|
|
@ -1288,10 +1223,10 @@ void GlCoreRhi::bind_uniform_set(Handle<GraphicsContext> ctx, uint32_t slot, Han
|
|||
SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true);
|
||||
|
||||
SRB2_ASSERT(pipeline_slab_.is_valid(*current_pipeline_));
|
||||
auto& pl = *static_cast<GlCorePipeline*>(&pipeline_slab_[*current_pipeline_]);
|
||||
auto& pl = pipeline_slab_[*current_pipeline_];
|
||||
|
||||
SRB2_ASSERT(uniform_set_slab_.is_valid(set));
|
||||
auto& us = *static_cast<GlCoreUniformSet*>(&uniform_set_slab_[set]);
|
||||
auto& us = uniform_set_slab_[set];
|
||||
|
||||
auto& uniform_input = pl.desc.uniform_input;
|
||||
SRB2_ASSERT(slot < uniform_input.enabled_uniforms.size());
|
||||
|
|
@ -1384,10 +1319,10 @@ void GlCoreRhi::bind_binding_set(Handle<GraphicsContext> ctx, Handle<BindingSet>
|
|||
SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true);
|
||||
|
||||
SRB2_ASSERT(pipeline_slab_.is_valid(*current_pipeline_));
|
||||
auto& pl = *static_cast<GlCorePipeline*>(&pipeline_slab_[*current_pipeline_]);
|
||||
auto& pl = pipeline_slab_[*current_pipeline_];
|
||||
|
||||
SRB2_ASSERT(binding_set_slab_.is_valid(set));
|
||||
auto& bs = *static_cast<GlCoreBindingSet*>(&binding_set_slab_[set]);
|
||||
auto& bs = binding_set_slab_[set];
|
||||
|
||||
SRB2_ASSERT(bs.textures.size() == pl.desc.sampler_input.enabled_samplers.size());
|
||||
|
||||
|
|
@ -1441,7 +1376,7 @@ void GlCoreRhi::bind_index_buffer(Handle<GraphicsContext> ctx, Handle<Buffer> bu
|
|||
SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true);
|
||||
|
||||
SRB2_ASSERT(buffer_slab_.is_valid(buffer));
|
||||
auto& ib = *static_cast<GlCoreBuffer*>(&buffer_slab_[buffer]);
|
||||
auto& ib = buffer_slab_[buffer];
|
||||
|
||||
SRB2_ASSERT(ib.desc.type == rhi::BufferType::kIndexBuffer);
|
||||
|
||||
|
|
|
|||
|
|
@ -73,19 +73,77 @@ struct GlCorePlatform
|
|||
virtual Rect get_default_framebuffer_dimensions() = 0;
|
||||
};
|
||||
|
||||
struct GlCoreTexture : public rhi::Texture
|
||||
{
|
||||
uint32_t texture;
|
||||
rhi::TextureDesc desc;
|
||||
};
|
||||
|
||||
struct GlCoreBuffer : public rhi::Buffer
|
||||
{
|
||||
uint32_t buffer;
|
||||
rhi::BufferDesc desc;
|
||||
};
|
||||
|
||||
struct GlCoreRenderPass : public rhi::RenderPass
|
||||
{
|
||||
rhi::RenderPassDesc desc;
|
||||
};
|
||||
|
||||
struct GlCoreRenderbuffer : public rhi::Renderbuffer
|
||||
{
|
||||
uint32_t renderbuffer;
|
||||
};
|
||||
|
||||
struct GlCoreUniformSet : public rhi::UniformSet
|
||||
{
|
||||
std::vector<rhi::UniformVariant> uniforms;
|
||||
};
|
||||
|
||||
struct GlCoreBindingSet : public rhi::BindingSet
|
||||
{
|
||||
uint32_t vao;
|
||||
std::unordered_map<rhi::SamplerName, uint32_t> textures {4};
|
||||
};
|
||||
|
||||
struct GlCorePipeline : public rhi::Pipeline
|
||||
{
|
||||
uint32_t vertex_shader = 0;
|
||||
uint32_t fragment_shader = 0;
|
||||
uint32_t program = 0;
|
||||
std::unordered_map<rhi::VertexAttributeName, uint32_t> attrib_locations {2};
|
||||
std::unordered_map<rhi::UniformName, uint32_t> uniform_locations {2};
|
||||
std::unordered_map<rhi::SamplerName, uint32_t> sampler_locations {2};
|
||||
rhi::PipelineDesc desc;
|
||||
};
|
||||
|
||||
struct GlCoreGraphicsContext : public rhi::GraphicsContext
|
||||
{
|
||||
};
|
||||
|
||||
struct GlCoreTransferContext : public rhi::TransferContext
|
||||
{
|
||||
};
|
||||
|
||||
struct GlCoreActiveUniform
|
||||
{
|
||||
uint32_t type;
|
||||
uint32_t location;
|
||||
};
|
||||
|
||||
class GlCoreRhi final : public Rhi
|
||||
{
|
||||
std::unique_ptr<GlCorePlatform> platform_;
|
||||
|
||||
std::unique_ptr<GladGLContext> gl_;
|
||||
|
||||
Slab<RenderPass> render_pass_slab_;
|
||||
Slab<Texture> texture_slab_;
|
||||
Slab<Buffer> buffer_slab_;
|
||||
Slab<Renderbuffer> renderbuffer_slab_;
|
||||
Slab<Pipeline> pipeline_slab_;
|
||||
Slab<UniformSet> uniform_set_slab_;
|
||||
Slab<BindingSet> binding_set_slab_;
|
||||
Slab<GlCoreRenderPass> render_pass_slab_;
|
||||
Slab<GlCoreTexture> texture_slab_;
|
||||
Slab<GlCoreBuffer> buffer_slab_;
|
||||
Slab<GlCoreRenderbuffer> renderbuffer_slab_;
|
||||
Slab<GlCorePipeline> pipeline_slab_;
|
||||
Slab<GlCoreUniformSet> uniform_set_slab_;
|
||||
Slab<GlCoreBindingSet> binding_set_slab_;
|
||||
|
||||
std::unordered_map<GlCoreFramebufferKey, uint32_t> framebuffers_ {16};
|
||||
|
||||
|
|
|
|||
|
|
@ -52,17 +52,10 @@ public:
|
|||
// Conversions from Handles of derived type U to base type T
|
||||
|
||||
template <typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
|
||||
Handle(const Handle<U>& rhs) noexcept : id_(rhs.id_), generation_(rhs.generation_)
|
||||
Handle(const Handle<U>& rhs) noexcept : id_(rhs.id()), generation_(rhs.generation())
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
|
||||
Handle(Handle<U>&& rhs) noexcept
|
||||
{
|
||||
id_ = std::exchange(rhs.id_, 0);
|
||||
generation_ = std::exchange(rhs.generation_, 0);
|
||||
}
|
||||
|
||||
template <typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
|
||||
Handle& operator=(const Handle<U>& rhs) noexcept
|
||||
{
|
||||
|
|
@ -70,14 +63,6 @@ public:
|
|||
generation_ = rhs.generation_;
|
||||
}
|
||||
|
||||
template <typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
|
||||
Handle& operator=(Handle<U>&& rhs) noexcept
|
||||
{
|
||||
id_ = std::exchange(rhs.id_, 0);
|
||||
generation_ = std::exchange(rhs.generation_, 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint32_t id() const noexcept { return id_; }
|
||||
uint32_t generation() const noexcept { return generation_; }
|
||||
|
||||
|
|
@ -175,7 +160,7 @@ public:
|
|||
SlabIterator& operator=(const SlabIterator&) = default;
|
||||
SlabIterator& operator=(SlabIterator&&) = default;
|
||||
|
||||
T& operator*() const noexcept { return *slab_->vec_[index_].item.get(); }
|
||||
T& operator*() const noexcept { return slab_->vec_[index_].item; }
|
||||
|
||||
SlabIterator& operator++() noexcept
|
||||
{
|
||||
|
|
@ -211,7 +196,7 @@ class Slab
|
|||
{
|
||||
struct SlabStorage
|
||||
{
|
||||
std::unique_ptr<T> item;
|
||||
T item;
|
||||
uint32_t gen;
|
||||
};
|
||||
std::vector<SlabStorage> vec_;
|
||||
|
|
@ -226,7 +211,7 @@ public:
|
|||
Slab(const Slab&) = delete;
|
||||
Slab& operator=(const Slab&) = delete;
|
||||
|
||||
Handle<T> insert(std::unique_ptr<T>&& value)
|
||||
Handle<T> insert(T&& value)
|
||||
{
|
||||
uint32_t ret_id = 0;
|
||||
if (!free_list_.empty())
|
||||
|
|
@ -245,21 +230,22 @@ public:
|
|||
return Handle<T>(ret_id, gen_);
|
||||
}
|
||||
|
||||
std::unique_ptr<T> remove(Handle<T> handle)
|
||||
template <typename U, typename std::enable_if_t<std::is_base_of_v<U, T>, bool> = true>
|
||||
T remove(Handle<U> handle)
|
||||
{
|
||||
uint32_t handle_id = handle.id();
|
||||
uint32_t handle_gen = handle.generation();
|
||||
if (handle_id >= vec_.size())
|
||||
{
|
||||
return nullptr;
|
||||
return T();
|
||||
}
|
||||
SlabStorage& storage = vec_[handle_id];
|
||||
if (storage.gen > handle_gen)
|
||||
{
|
||||
return nullptr;
|
||||
return T();
|
||||
}
|
||||
std::unique_ptr<T> ret = std::move(storage.item);
|
||||
storage.item = nullptr;
|
||||
T ret = std::move(storage.item);
|
||||
storage.item = T();
|
||||
free_list_.push_back(handle_id);
|
||||
gen_ += 1;
|
||||
if (gen_ == 0)
|
||||
|
|
@ -269,7 +255,8 @@ public:
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool is_valid(Handle<T> handle)
|
||||
template <typename U, typename std::enable_if_t<std::is_base_of_v<U, T>, bool> = true>
|
||||
bool is_valid(Handle<U> handle)
|
||||
{
|
||||
uint32_t handle_id = handle.id();
|
||||
uint32_t handle_gen = handle.generation();
|
||||
|
|
@ -296,10 +283,11 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
T& operator[](Handle<T> handle)
|
||||
template <typename U, typename std::enable_if_t<std::is_base_of_v<U, T>, bool> = true>
|
||||
T& operator[](Handle<U> handle)
|
||||
{
|
||||
SRB2_ASSERT(is_valid(handle));
|
||||
return *vec_[handle.id()].item;
|
||||
return vec_[handle.id()].item;
|
||||
}
|
||||
|
||||
SlabIterator<T> begin() { return SlabIterator<T> {0, this}; }
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue