diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-11 11:18:35 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-11 11:18:35 +0100 |
commit | 511faeef4f5b53fd0247dc0db1b8ccc1437af047 (patch) | |
tree | b2d51496cbfd57f944a719ff71d89a3bf1f8441c /loader | |
parent | cff080f8dfcbf3b5729a38bbe5ba4bc80a1a4d79 (diff) |
a
Diffstat (limited to 'loader')
-rw-r--r-- | loader/filesystem.cpp | 35 | ||||
-rw-r--r-- | loader/impl.hpp | 11 | ||||
-rw-r--r-- | loader/json.cpp | 12 | ||||
-rw-r--r-- | loader/loader-impl.cpp | 42 |
4 files changed, 77 insertions, 23 deletions
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 <Corrade/Containers/StringView.h> +#include <Corrade/Utility/Debug.h> +#include <Corrade/Utility/Implementation/ErrorString.h> +#ifdef _WIN32 +#include <Corrade/Containers/Array.h> +#include <Corrade/Utility/Unicode.h> +#include <direct.h> +#else +#include <unistd.h> +#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 <Corrade/Containers/StringView.h> + +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<Serialize::anim>(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 <unordered_map> #include <utility> +#include <memory> #include <optional> #include <Corrade/Containers/Pair.h> #include <Corrade/Containers/ArrayViewStl.h> @@ -66,14 +67,8 @@ StringView loader_impl::shader(StringView filename) std::shared_ptr<tile_atlas> 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<struct tile_atlas>(name, image, size); + const emplacer e{[&] { return std::make_shared<struct tile_atlas>(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<anim_atlas> 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<Serialize::anim>(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<anim_atlas> 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<struct anim_atlas>(Path::splitExtension(path).first(), tex, std::move(anim_info)); + auto atlas = std::make_shared<struct anim_atlas>(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() |