#include "loader.hpp" #include "tile-atlas.hpp" #include "compat/assert.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Magnum::Examples { struct loader_impl final : loader_ { std::optional shader_res; PluginManager::Manager importer_plugins; Containers::Pointer tga_importer = importer_plugins.loadAndInstantiate("AnyImageImporter"); PluginManager::Manager image_converter_plugins; Containers::Pointer tga_converter = image_converter_plugins.loadAndInstantiate("AnyImageConverter"); std::unordered_map> atlas_map; std::string shader(Containers::StringView filename) override; Trade::ImageData2D tile_texture(Containers::StringView filename) override; std::shared_ptr tile_atlas(Containers::StringView filename, Vector2ui size) override; static void set_application_working_directory(); explicit loader_impl(); ~loader_impl() override; }; std::string loader_impl::shader(Containers::StringView filename) { if (!shader_res) shader_res = std::make_optional("game/shaders"); auto ret = shader_res->getString(filename); if (ret.isEmpty()) ABORT("can't find shader resource '%s'", filename.cbegin()); return ret; } std::shared_ptr loader_impl::tile_atlas(Containers::StringView name, Vector2ui size) { auto it = atlas_map.find(name); if (it != atlas_map.end()) return it->second; auto image = tile_texture(name); auto atlas = std::make_shared(name, image, size); atlas_map[name] = atlas; return atlas; } Trade::ImageData2D loader_impl::tile_texture(Containers::StringView filename) { if(!tga_importer || !tga_importer->openFile(filename)) { const auto path = Utility::Path::currentDirectory(); MESSAGE("note: current working directory: '%s'", path->data()); ABORT("can't open tile image '%s'", filename.cbegin()); } auto img = tga_importer->image2D(0); if (!img) ABORT("can't allocate tile image for '%s'", filename.cbegin()); auto ret = std::move(*img); return ret; } void loader_::destroy() { loader.~loader_(); new (&loader) loader_impl(); } void loader_impl::set_application_working_directory() { static bool once = false; if (once) return; once = true; const auto location = Utility::Path::executableLocation(); if (!location) return; std::filesystem::path path((std::string)*location); path.replace_filename(".."); std::error_code error; std::filesystem::current_path(path, error); if (error.value()) { WARN("failed to change working directory to '%s' (%s)", path.string().data(), error.message().data()); } } loader_impl::loader_impl() { set_application_working_directory(); } loader_impl::~loader_impl() = default; static loader_& make_default_loader() { static loader_impl loader_singleton{}; return loader_singleton; } // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) loader_& loader = make_default_loader(); } // namespace Magnum::Examples