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>>();
|
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>>>();
|
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();
|
font_texture.bind();
|
||||||
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_SWIZZLE_G, gl::RED);
|
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()
|
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();
|
cross_red_16x16->nearest_filter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ namespace psemek::ui
|
||||||
std::string_view name = "default_monospace_9x12";
|
std::string_view name = "default_monospace_9x12";
|
||||||
geom::vector<int, 2> size{9, 12};
|
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.nearest_filter();
|
||||||
atlas.clamp();
|
atlas.clamp();
|
||||||
gl::TexParameteri(atlas.target, gl::TEXTURE_SWIZZLE_G, gl::RED);
|
gl::TexParameteri(atlas.target, gl::TEXTURE_SWIZZLE_G, gl::RED);
|
||||||
|
|
@ -49,7 +49,7 @@ namespace psemek::ui
|
||||||
std::string_view name = "default_9x12";
|
std::string_view name = "default_9x12";
|
||||||
geom::vector<int, 2> size{9, 12};
|
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.nearest_filter();
|
||||||
atlas.clamp();
|
atlas.clamp();
|
||||||
gl::TexParameteri(atlas.target, gl::TEXTURE_SWIZZLE_G, gl::RED);
|
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::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;
|
std::string line;
|
||||||
while (std::getline(is, line))
|
while (std::getline(is, line))
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ function(psemek_add_resources_impl MODE TARGET)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(${TARGET} ${MODE} psemek-rs)
|
||||||
|
|
||||||
get_target_property(OUT_DIR ${TARGET} BINARY_DIR)
|
get_target_property(OUT_DIR ${TARGET} BINARY_DIR)
|
||||||
get_target_property(INPUT_DIR ${TARGET} SOURCE_DIR)
|
get_target_property(INPUT_DIR ${TARGET} SOURCE_DIR)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ int main(int argc, char * argv[])
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string name = argv[2];
|
std::string fullname = argv[2];
|
||||||
|
std::string name = fullname;
|
||||||
std::string ns;
|
std::string ns;
|
||||||
|
|
||||||
std::size_t const last_slash = name.find_last_of('/');
|
std::size_t const last_slash = name.find_last_of('/');
|
||||||
|
|
@ -43,7 +44,7 @@ int main(int argc, char * argv[])
|
||||||
output_header
|
output_header
|
||||||
<< "#pragma once\n"
|
<< "#pragma once\n"
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< "#include <string_view>\n"
|
<< "#include <psemek/rs/resource.hpp>\n"
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
if (!ns.empty()) output_header
|
if (!ns.empty()) output_header
|
||||||
|
|
@ -51,7 +52,7 @@ int main(int argc, char * argv[])
|
||||||
<< "{\n"
|
<< "{\n"
|
||||||
<< "\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
|
if (!ns.empty()) output_header
|
||||||
<< "\n"
|
<< "\n"
|
||||||
|
|
@ -62,7 +63,7 @@ int main(int argc, char * argv[])
|
||||||
std::ofstream output_source{argv[4]};
|
std::ofstream output_source{argv[4]};
|
||||||
|
|
||||||
output_source
|
output_source
|
||||||
<< "#include <string_view>\n"
|
<< "#include <psemek/rs/registry.hpp>\n"
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
output_source << "alignas(16) static const char data[" << input_data.size() << "] = {\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"
|
||||||
<< "\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
|
if (!ns.empty()) output_source
|
||||||
<< "\n"
|
<< "\n"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue