summaryrefslogtreecommitdiffhomepage
path: root/loader
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-11-11 11:18:35 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-11-11 11:18:35 +0100
commit511faeef4f5b53fd0247dc0db1b8ccc1437af047 (patch)
treeb2d51496cbfd57f944a719ff71d89a3bf1f8441c /loader
parentcff080f8dfcbf3b5729a38bbe5ba4bc80a1a4d79 (diff)
a
Diffstat (limited to 'loader')
-rw-r--r--loader/filesystem.cpp35
-rw-r--r--loader/impl.hpp11
-rw-r--r--loader/json.cpp12
-rw-r--r--loader/loader-impl.cpp42
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()