Redesign resources system: centralized id-based resource registry
This commit is contained in:
parent
2c0001be28
commit
75e6db45f1
9 changed files with 183 additions and 10 deletions
|
|
@ -164,7 +164,7 @@ namespace psemek::gfx
|
|||
text_mesh.setup<geom::point<float, 3>, gfx::normalized<color_rgba>, geom::point<std::uint16_t, 2>>();
|
||||
texture_mesh.setup<geom::point<float, 3>, gfx::normalized<geom::point<std::uint16_t, 2>>>();
|
||||
|
||||
font_texture.load(gfx::read_png_monochrome(io::memory_istream{resource::font_9x12_png}));
|
||||
font_texture.load(gfx::read_png_monochrome(io::memory_istream{resource::font_9x12_png.data}));
|
||||
|
||||
font_texture.bind();
|
||||
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_SWIZZLE_G, gl::RED);
|
||||
|
|
|
|||
6
libs/rs/CMakeLists.txt
Normal file
6
libs/rs/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
file(GLOB_RECURSE PSEMEK_IO_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "include/*.hpp")
|
||||
file(GLOB_RECURSE PSEMEK_IO_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "source/*.cpp")
|
||||
|
||||
psemek_add_library(psemek-rs ${PSEMEK_IO_HEADERS} ${PSEMEK_IO_SOURCES})
|
||||
target_include_directories(psemek-rs PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
target_link_libraries(psemek-rs PRIVATE psemek-util)
|
||||
40
libs/rs/include/psemek/rs/registry.hpp
Normal file
40
libs/rs/include/psemek/rs/registry.hpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/rs/resource.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace psemek::rs
|
||||
{
|
||||
|
||||
struct unknown_id_error
|
||||
: std::runtime_error
|
||||
{
|
||||
unknown_id_error(rs::id id);
|
||||
|
||||
rs::id id() const { return id_; }
|
||||
|
||||
private:
|
||||
rs::id id_;
|
||||
};
|
||||
|
||||
struct unknown_name_error
|
||||
: std::runtime_error
|
||||
{
|
||||
unknown_name_error(std::string_view name);
|
||||
|
||||
std::string_view name() const { return name_; }
|
||||
|
||||
private:
|
||||
std::string_view name_;
|
||||
};
|
||||
|
||||
resource const * find(id id);
|
||||
resource const * find(std::string_view name);
|
||||
|
||||
resource const & get(id id);
|
||||
resource const & get(std::string_view name);
|
||||
|
||||
id add(std::string_view name, std::string_view data);
|
||||
|
||||
}
|
||||
18
libs/rs/include/psemek/rs/resource.hpp
Normal file
18
libs/rs/include/psemek/rs/resource.hpp
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
|
||||
namespace psemek::rs
|
||||
{
|
||||
|
||||
using id = std::uint32_t;
|
||||
|
||||
struct resource
|
||||
{
|
||||
rs::id id;
|
||||
std::string_view name;
|
||||
std::string_view data;
|
||||
};
|
||||
|
||||
}
|
||||
106
libs/rs/source/registry.cpp
Normal file
106
libs/rs/source/registry.cpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#include <psemek/rs/registry.hpp>
|
||||
|
||||
#include <psemek/util/to_string.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <optional>
|
||||
|
||||
namespace psemek::rs
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
auto & resources_mutex()
|
||||
{
|
||||
static std::mutex instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
auto & resources()
|
||||
{
|
||||
static std::map<id, resource> instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
auto & name_map_mutex()
|
||||
{
|
||||
static std::mutex instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
auto & name_map()
|
||||
{
|
||||
static std::unordered_map<std::string_view, id> instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
std::atomic<id> next_id{0};
|
||||
|
||||
}
|
||||
|
||||
unknown_id_error::unknown_id_error(rs::id id)
|
||||
: std::runtime_error(util::to_string("unknown resource id: ", id))
|
||||
, id_(id)
|
||||
{}
|
||||
|
||||
unknown_name_error::unknown_name_error(std::string_view name)
|
||||
: std::runtime_error(util::to_string("unknown resource name: ", name))
|
||||
{}
|
||||
|
||||
resource const * find(id id)
|
||||
{
|
||||
std::lock_guard lock{resources_mutex()};
|
||||
auto it = resources().find(id);
|
||||
if (it == resources().end())
|
||||
return nullptr;
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
resource const * find(std::string_view name)
|
||||
{
|
||||
rs::id id;
|
||||
{
|
||||
std::lock_guard lock{name_map_mutex()};
|
||||
auto it = name_map().find(name);
|
||||
if (it == name_map().end())
|
||||
return nullptr;
|
||||
id = it->second;
|
||||
}
|
||||
return find(id);
|
||||
}
|
||||
|
||||
resource const & get(id id)
|
||||
{
|
||||
auto result = find(id);
|
||||
if (!result)
|
||||
throw unknown_id_error{id};
|
||||
return *result;
|
||||
}
|
||||
|
||||
resource const & get(std::string_view name)
|
||||
{
|
||||
auto result = find(name);
|
||||
if (!result)
|
||||
throw unknown_name_error{name};
|
||||
return *result;
|
||||
}
|
||||
|
||||
id add(std::string_view name, std::string_view data)
|
||||
{
|
||||
auto id = next_id.fetch_add(1);
|
||||
{
|
||||
std::lock_guard lock{name_map_mutex()};
|
||||
name_map()[name] = id;
|
||||
}
|
||||
{
|
||||
std::lock_guard lock{resources_mutex()};
|
||||
resources()[id] = {id, name, data};
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -718,7 +718,7 @@ namespace psemek::ui
|
|||
|
||||
default_element_factory::impl::impl()
|
||||
{
|
||||
cross_red_16x16 = std::make_shared<gfx::texture_2d>(gfx::texture_2d::from_pixmap(gfx::read_png(io::memory_istream{resources::cross_red_16x16_png})));
|
||||
cross_red_16x16 = std::make_shared<gfx::texture_2d>(gfx::texture_2d::from_pixmap(gfx::read_png(io::memory_istream{resources::cross_red_16x16_png.data})));
|
||||
cross_red_16x16->nearest_filter();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace psemek::ui
|
|||
std::string_view name = "default_monospace_9x12";
|
||||
geom::vector<int, 2> size{9, 12};
|
||||
|
||||
gfx::texture_2d atlas = gfx::texture_2d::from_pixmap(gfx::read_png_monochrome(io::memory_istream{gfx::resource::font_9x12_png}));
|
||||
gfx::texture_2d atlas = gfx::texture_2d::from_pixmap(gfx::read_png_monochrome(io::memory_istream{gfx::resource::font_9x12_png.data}));
|
||||
atlas.nearest_filter();
|
||||
atlas.clamp();
|
||||
gl::TexParameteri(atlas.target, gl::TEXTURE_SWIZZLE_G, gl::RED);
|
||||
|
|
@ -49,7 +49,7 @@ namespace psemek::ui
|
|||
std::string_view name = "default_9x12";
|
||||
geom::vector<int, 2> size{9, 12};
|
||||
|
||||
gfx::texture_2d atlas = gfx::texture_2d::from_pixmap(gfx::read_png_monochrome(io::memory_istream{gfx::resource::font_9x12_png}));
|
||||
gfx::texture_2d atlas = gfx::texture_2d::from_pixmap(gfx::read_png_monochrome(io::memory_istream{gfx::resource::font_9x12_png.data}));
|
||||
atlas.nearest_filter();
|
||||
atlas.clamp();
|
||||
gl::TexParameteri(atlas.target, gl::TEXTURE_SWIZZLE_G, gl::RED);
|
||||
|
|
@ -58,7 +58,7 @@ namespace psemek::ui
|
|||
|
||||
std::unordered_map<char32_t, kerned_font::glyph_data> glyphs;
|
||||
{
|
||||
std::istringstream is{std::string(ui::resources::font_9x12_glyphs_txt)};
|
||||
std::istringstream is{std::string(ui::resources::font_9x12_glyphs_txt.data)};
|
||||
|
||||
std::string line;
|
||||
while (std::getline(is, line))
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ function(psemek_add_resources_impl MODE TARGET)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(${TARGET} ${MODE} psemek-rs)
|
||||
|
||||
get_target_property(OUT_DIR ${TARGET} BINARY_DIR)
|
||||
get_target_property(INPUT_DIR ${TARGET} SOURCE_DIR)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ int main(int argc, char * argv[])
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::string name = argv[2];
|
||||
std::string fullname = argv[2];
|
||||
std::string name = fullname;
|
||||
std::string ns;
|
||||
|
||||
std::size_t const last_slash = name.find_last_of('/');
|
||||
|
|
@ -43,7 +44,7 @@ int main(int argc, char * argv[])
|
|||
output_header
|
||||
<< "#pragma once\n"
|
||||
<< "\n"
|
||||
<< "#include <string_view>\n"
|
||||
<< "#include <psemek/rs/resource.hpp>\n"
|
||||
<< "\n";
|
||||
|
||||
if (!ns.empty()) output_header
|
||||
|
|
@ -51,7 +52,7 @@ int main(int argc, char * argv[])
|
|||
<< "{\n"
|
||||
<< "\n";
|
||||
|
||||
output_header << tab << "extern std::string_view " << name << ";\n";
|
||||
output_header << tab << "extern ::psemek::rs::resource const & " << name << ";\n";
|
||||
|
||||
if (!ns.empty()) output_header
|
||||
<< "\n"
|
||||
|
|
@ -62,7 +63,7 @@ int main(int argc, char * argv[])
|
|||
std::ofstream output_source{argv[4]};
|
||||
|
||||
output_source
|
||||
<< "#include <string_view>\n"
|
||||
<< "#include <psemek/rs/registry.hpp>\n"
|
||||
<< "\n";
|
||||
|
||||
output_source << "alignas(16) static const char data[" << input_data.size() << "] = {\n";
|
||||
|
|
@ -94,7 +95,7 @@ int main(int argc, char * argv[])
|
|||
<< "{\n"
|
||||
<< "\n";
|
||||
|
||||
output_source << tab << "std::string_view " << name << "{data, sizeof(data)};\n";
|
||||
output_source << tab << "::psemek::rs::resource const & " << name << " = ::psemek::rs::get(::psemek::rs::add(\"" << fullname << "\", {data, sizeof(data)}));\n";
|
||||
|
||||
if (!ns.empty()) output_source
|
||||
<< "\n"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue