Files
Z3D/source/assets/data_loaders/generic/base_dynamic_loader.ipp

93 lines
2.4 KiB
C++

#ifndef INCLUDE_BASE_DYNAMIC_LOADER_IMPLEMENTATION
# error Never include this file directly include 'base_dynamic_loader.hpp'
#endif
#include "util/for_each.hpp"
template<typename C, class... Loaders>
assetsbase_dynamic_loader<C, Loaders...>::base_dynamic_loader(const C enabled_components) :
m_enabled_components{ enabled_components }
{
[&]<std::size_t... Is>(std::index_sequence<Is...>) {
m_loader_id_lookup = { { std::string{ Loaders::name }, { Is } }... };
}(std::index_sequence_for<Loaders...>());
}
template<typename C, class... Loaders>
std::optional<typename base_dynamic_loader<C, Loaders...>::loader_id_type> base_dynamic_loader<C, Loaders...>::find_loader(
std::string_view name
) {
const auto it = m_loader_id_lookup.find(name);
if (it != m_loader_id_lookup.end())
{
return it->second;
}
return std::nullopt;
}
template<typename C, class... Loaders>
consteval std::optional<typename base_dynamic_loader<C, Loaders...>::loader_id_type> base_dynamic_loader<C, Loaders...>::find_loader_static(
std::string_view name
) {
constexpr auto invalid_index = std::numeric_limits<typename loader_id_type::index_type>::max();
auto index = invalid_index;
ztu::for_each::indexed_type<Loaders...>([&]<auto Index, typename Loader>()
{
if (name == Loader::name)
{
index = Index;
return true;
}
return false;
});
return index == invalid_index ? std::nullopt : loader_id_type{ index };
}
template<typename C, class... Loaders>
template<typename base_dynamic_loader<C, Loaders...>::loader_id_type ID>
auto& base_dynamic_loader<C, Loaders...>::get_loader()
{
return std::get<ID.index>(m_loaders);
}
template<typename C, class... Loaders>
template<typename F>
ztu::result<dynamic_point_cloud_store::id_type> base_dynamic_loader<C, Loaders...>::invoke_with_matching_loader(
const loader_id_type loader_id, F&& f
) {
return std::apply(
[&](Loaders&... loaders)
{
return [&]<std::size_t... Is>(std::index_sequence<Is...>)
{
std::error_code error;
const auto found_parser = (
[&](auto& loader, const std::size_t index)
{
if (loader_id == index)
{
error = f(loader);
return true;
}
return false;
} (loaders, Is)
or ...
);
if (not found_parser)
{
error = std::make_error_code(std::errc::invalid_argument);
}
return error;
}(std::index_sequence_for<Loaders...>());
},
m_loaders
);
}