From 511faeef4f5b53fd0247dc0db1b8ccc1437af047 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Fri, 11 Nov 2022 11:18:35 +0100 Subject: a --- editor/CMakeLists.txt | 4 ++-- loader/filesystem.cpp | 35 +++++++++++++++++++++++++++++++++++ loader/impl.hpp | 11 +++++++++++ loader/json.cpp | 12 ++++++++++++ loader/loader-impl.cpp | 42 +++++++++++++++++++----------------------- src/emplacer.hpp | 16 ++++++++++++++++ test/CMakeLists.txt | 4 ++-- 7 files changed, 97 insertions(+), 27 deletions(-) create mode 100644 loader/filesystem.cpp create mode 100644 loader/impl.hpp create mode 100644 loader/json.cpp create mode 100644 src/emplacer.hpp diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 77a2a73e..19895603 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -1,6 +1,6 @@ set(self ${PROJECT_NAME}-editor) -file(GLOB sources "*.cpp" CONFIGURE_ARGS) +file(GLOB sources "*.cpp" "../loader/*.cpp" CONFIGURE_ARGS) corrade_add_resource(res "../resources.conf") if(MSVC) @@ -11,7 +11,7 @@ endif() link_libraries(MagnumIntegration::ImGui fmt::fmt) -add_executable(${self} "${sources}" "${res}" "../loader/loader-impl.cpp") +add_executable(${self} "${sources}" "${res}") target_link_libraries(${self} ${PROJECT_NAME}-main) if(FLOORMAT_PRECOMPILED-HEADERS) diff --git a/loader/filesystem.cpp b/loader/filesystem.cpp new file mode 100644 index 00000000..8c62a9b3 --- /dev/null +++ b/loader/filesystem.cpp @@ -0,0 +1,35 @@ +#include "impl.hpp" +#include "compat/assert.hpp" +#include +#include +#include +#ifdef _WIN32 +#include +#include +#include +#else +#include +#endif + +namespace floormat::loader_detail { + +namespace Unicode = Corrade::Utility::Unicode; + +bool chdir(StringView pathname) +{ + int ret; +#ifdef _WIN32 + ret = _wchdir(Unicode::widen(pathname)); +#else + ret = chdir(pathname.data()); +#endif + if (ret) + { + Error err; + err << "chdir: can't change directory to" << pathname << Error::nospace << ':'; + Corrade::Utility::Implementation::printErrnoErrorString(err, errno); + } + return !ret; +} + +} // namespace floormat::loader_detail diff --git a/loader/impl.hpp b/loader/impl.hpp new file mode 100644 index 00000000..75ca0392 --- /dev/null +++ b/loader/impl.hpp @@ -0,0 +1,11 @@ +#pragma once +#include + +namespace floormat::Serialize { struct anim; } + +namespace floormat::loader_detail { + +bool chdir(StringView pathname); +Serialize::anim deserialize_anim(StringView filename); + +} // namespace floormat::loader_detail diff --git a/loader/json.cpp b/loader/json.cpp new file mode 100644 index 00000000..e66a58f2 --- /dev/null +++ b/loader/json.cpp @@ -0,0 +1,12 @@ +#include "impl.hpp" +#include "serialize/json-helper.hpp" +#include "serialize/anim.hpp" + +namespace floormat::loader_detail { + +Serialize::anim deserialize_anim(StringView filename) +{ + return json_helper::from_json(filename); +} + +} // namespace floormat::loader_detail diff --git a/loader/loader-impl.cpp b/loader/loader-impl.cpp index 23dc4253..4b52ea58 100644 --- a/loader/loader-impl.cpp +++ b/loader/loader-impl.cpp @@ -1,12 +1,13 @@ +#include "impl.hpp" #include "src/loader.hpp" #include "src/tile-atlas.hpp" #include "compat/assert.hpp" #include "compat/alloca.hpp" #include "src/anim-atlas.hpp" -#include "serialize/json-helper.hpp" -#include "serialize/anim.hpp" +#include "src/emplacer.hpp" #include #include +#include #include #include #include @@ -66,14 +67,8 @@ StringView loader_impl::shader(StringView filename) std::shared_ptr loader_impl::tile_atlas(StringView name, Vector2ub size) { - auto it = std::find_if(tile_atlas_map.cbegin(), tile_atlas_map.cend(), [&](const auto& x) { - const auto& [k, v] = x; - return StringView{k} == name; - }); - if (it != tile_atlas_map.cend()) - return it->second; - auto image = texture(FM_IMAGE_PATH, name); - auto atlas = std::make_shared(name, image, size); + const emplacer e{[&] { return std::make_shared(name, texture(FM_IMAGE_PATH, name), size); }}; + auto atlas = tile_atlas_map.try_emplace(name, e).first->second; tile_atlas_map[atlas->name()] = atlas; return atlas; } @@ -131,8 +126,8 @@ std::shared_ptr loader_impl::anim_atlas(StringView name) return it->second; else { - const auto path = Path::join(FM_ANIM_PATH, name); - auto anim_info = json_helper::from_json(Path::splitExtension(path).first() + ".json"); + const auto path = Path::join(FM_ANIM_PATH, Path::splitExtension(name).first()); + auto anim_info = loader_detail::deserialize_anim(path + ".json"); auto tex = texture("", path); fm_assert(!anim_info.anim_name.isEmpty() && !anim_info.object_name.isEmpty()); @@ -141,7 +136,7 @@ std::shared_ptr loader_impl::anim_atlas(StringView name) fm_assert(anim_info.nframes > 0); fm_assert(anim_info.nframes == 1 || anim_info.fps > 0); - auto atlas = std::make_shared(Path::splitExtension(path).first(), tex, std::move(anim_info)); + auto atlas = std::make_shared(path, tex, std::move(anim_info)); return anim_atlas_map[atlas->name()] = atlas; } } @@ -170,17 +165,18 @@ void loader_impl::set_application_working_directory() if (once) return; once = true; - const auto location = 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()) { - fm_warn("failed to change working directory to '%s' (%s)", - path.string().data(), error.message().data()); + if (const auto loc = Path::executableLocation()) + { + auto path = *loc; + if (const auto pos = path.findLast('/'); pos) + { + const auto size = std::size_t(pos.data() - path.data()); + path = path.prefix(size); + loader_detail::chdir(Path::join(path, "..")); + return; + } } + fm_warn("can't find install prefix!"); } loader_impl::loader_impl() diff --git a/src/emplacer.hpp b/src/emplacer.hpp new file mode 100644 index 00000000..eca115e8 --- /dev/null +++ b/src/emplacer.hpp @@ -0,0 +1,16 @@ +#pragma once +#include + +namespace floormat { + +template +class emplacer { + F fun; + using type = std::decay_t()())>; + +public: + explicit constexpr emplacer(F&& fun) noexcept : fun{std::forward(fun)} {} + constexpr operator type() const noexcept { return fun(); } +}; + +} // namespace floormat diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0f5ca85d..eefe72f8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,5 @@ set(self "${PROJECT_NAME}-test") -file(GLOB sources "*.cpp" CONFIGURE_ARGS) +file(GLOB sources "*.cpp" "../loader/*.cpp" CONFIGURE_ARGS) file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/test") @@ -14,5 +14,5 @@ else() link_libraries(Magnum::WindowlessGlxApplication) endif() -add_executable(${self} "${sources}" "../loader/loader-impl.cpp") +add_executable(${self} "${sources}") install(TARGETS ${self} RUNTIME DESTINATION bin) -- cgit v1.2.3