diff options
-rw-r--r-- | compat/assert.hpp | 4 | ||||
-rw-r--r-- | main/loader-impl.cpp | 30 | ||||
-rw-r--r-- | main/main.cpp | 10 | ||||
-rw-r--r-- | serialize/anim.cpp | 8 | ||||
-rw-r--r-- | serialize/anim.hpp | 4 | ||||
-rw-r--r-- | serialize/json-helper.hpp | 59 | ||||
-rw-r--r-- | serialize/magnum-vector.hpp | 20 | ||||
-rw-r--r-- | test/app.hpp | 13 | ||||
-rw-r--r-- | test/json.cpp | 29 | ||||
-rw-r--r-- | test/main.cpp | 47 |
10 files changed, 130 insertions, 94 deletions
diff --git a/compat/assert.hpp b/compat/assert.hpp index 0d433274..e4dd827a 100644 --- a/compat/assert.hpp +++ b/compat/assert.hpp @@ -23,12 +23,12 @@ constexpr void abort(const char (&fmt)[N], Xs... xs) namespace Magnum::Examples { -#define ABORT(fmt, ...) \ +#define ABORT(...) \ do { \ if (std::is_constant_evaluated()) \ throw "aborting"; \ else \ - ::Magnum::Examples::detail:: abort(fmt, __VA_ARGS__); \ + ::Magnum::Examples::detail:: abort(__VA_ARGS__); \ } while (false) #define ASSERT(expr) \ diff --git a/main/loader-impl.cpp b/main/loader-impl.cpp index 1ddb8cdb..77f96672 100644 --- a/main/loader-impl.cpp +++ b/main/loader-impl.cpp @@ -1,20 +1,36 @@ #include "loader.hpp" #include "tile-atlas.hpp" #include "compat/assert.hpp" +#include <filesystem> +#include <unordered_map> +#include <utility> +#include <optional> #include <Corrade/Containers/Optional.h> -#include <Corrade/Containers/StringView.h> +#include <Corrade/Containers/Pair.h> +#include <Corrade/Containers/StringStlView.h> #include <Corrade/PluginManager/PluginManager.h> #include <Corrade/Utility/Resource.h> +#include <Corrade/Utility/Path.h> #include <Magnum/ImageView.h> #include <Magnum/Trade/AbstractImporter.h> #include <Magnum/Trade/ImageData.h> #include <Magnum/Trade/AbstractImageConverter.h> -#include <unordered_map> -#include <utility> -#include <optional> namespace Magnum::Examples { +static void set_application_working_directory() +{ + static bool once = false; + if (once) + return; + once = true; + const auto location = *Utility::Path::executableLocation(); + if (const auto dir = Utility::Path::split(location).first(); !dir.isEmpty()) { + const std::filesystem::path path(std::string{dir}); + std::filesystem::current_path(path/".."); + } +} + struct loader_impl final : loader_ { std::optional<Utility::Resource> shader_res; @@ -74,7 +90,11 @@ void loader_::destroy() new (&loader) loader_impl(); } -loader_impl::loader_impl() = default; +loader_impl::loader_impl() +{ + set_application_working_directory(); +} + loader_impl::~loader_impl() = default; static loader_& make_default_loader() diff --git a/main/main.cpp b/main/main.cpp index 14828cad..22cec94f 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -6,9 +6,7 @@ #include "floor-mesh.hpp" #include "wall-mesh.hpp" #include "compat/defs.hpp" - #include <bitset> - #include <Magnum/Magnum.h> #include <Magnum/Math/Vector.h> #include <Magnum/GL/DefaultFramebuffer.h> @@ -55,10 +53,10 @@ struct app final : Platform::Application chunk make_test_chunk(); tile_shader _shader; - tile_atlas_ floor1 = loader.tile_atlas("../share/game/images/metal1.tga", {2, 2}); - tile_atlas_ floor2 = loader.tile_atlas("../share/game/images/floor1.tga", {4, 4}); - tile_atlas_ wall1 = loader.tile_atlas("../share/game/images/wood2.tga", {2, 2}); - tile_atlas_ wall2 = loader.tile_atlas("../share/game/images/wood1.tga", {2, 2}); + tile_atlas_ floor1 = loader.tile_atlas("share/game/images/metal1.tga", {2, 2}); + tile_atlas_ floor2 = loader.tile_atlas("share/game/images/floor1.tga", {4, 4}); + tile_atlas_ wall1 = loader.tile_atlas("share/game/images/wood2.tga", {2, 2}); + tile_atlas_ wall2 = loader.tile_atlas("share/game/images/wood1.tga", {2, 2}); chunk _chunk = make_test_chunk(); floor_mesh _floor_mesh; wall_mesh _wall_mesh; diff --git a/serialize/anim.cpp b/serialize/anim.cpp index b7d3ce95..dffe2449 100644 --- a/serialize/anim.cpp +++ b/serialize/anim.cpp @@ -23,14 +23,14 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(anim, name, nframes, actionframe, fps, groups # pragma clang diagnostic pop #endif -std::tuple<anim, bool> anim::from_json(const std::filesystem::path& pathname) noexcept +std::tuple<anim, bool> anim::from_json(const std::filesystem::path& pathname) { - return json_helper<anim>::from_json(pathname); + return json_helper::from_json<anim>(pathname); } -bool anim::to_json(const std::filesystem::path& pathname) const noexcept +bool anim::to_json(const std::filesystem::path& pathname) const { - return json_helper<anim>::to_json(*this, pathname); + return json_helper::to_json(*this, pathname); } } // namespace Magnum::Examples::Serialize diff --git a/serialize/anim.hpp b/serialize/anim.hpp index f03e3c8c..726efa44 100644 --- a/serialize/anim.hpp +++ b/serialize/anim.hpp @@ -32,8 +32,8 @@ struct anim_group final struct anim final { - static std::tuple<anim, bool> from_json(const std::filesystem::path& pathname) noexcept; - [[nodiscard]] bool to_json(const std::filesystem::path& pathname) const noexcept; + static std::tuple<anim, bool> from_json(const std::filesystem::path& pathname); + [[nodiscard]] bool to_json(const std::filesystem::path& pathname) const; static constexpr int default_fps = 24; std::string name; diff --git a/serialize/json-helper.hpp b/serialize/json-helper.hpp index af6fd211..4a9ee0ac 100644 --- a/serialize/json-helper.hpp +++ b/serialize/json-helper.hpp @@ -6,57 +6,46 @@ #include <nlohmann/json.hpp> #include <Corrade/Utility/DebugStl.h> -template<typename t> struct json_helper final { - [[nodiscard]] static std::tuple<t, bool> from_json(const std::filesystem::path& pathname) noexcept; - [[nodiscard]] static bool to_json(const t& self, const std::filesystem::path& pathname) noexcept; + template<typename t> + [[nodiscard]] + static std::tuple<t, bool> from_json(const std::filesystem::path& pathname); + + template<typename t> + [[nodiscard]] + static bool to_json(const t& self, const std::filesystem::path& pathname); }; template<typename t> -std::tuple<t, bool> json_helper<t>::from_json(const std::filesystem::path& pathname) noexcept { +std::tuple<t, bool> json_helper::from_json(const std::filesystem::path& pathname) { using namespace nlohmann; using Corrade::Utility::Error; std::ifstream s; s.exceptions(s.exceptions() | std::ios::failbit | std::ios::badbit); - try { - s.open(pathname, std::ios_base::in); - } catch (const std::ios::failure& e) { - Error{Error::Flag::NoSpace} << "failed to open '" << pathname << "': " << e.what(); - return { {}, false }; - } + s.open(pathname, std::ios_base::in); t ret; - try { - json j; - s >> j; - using nlohmann::from_json; - from_json(j, ret); - } catch (const std::exception& e) { - Error{Error::Flag::NoSpace} << "failed to parse '" << pathname << "': " << e.what(); - return { {}, false }; - } + json j; + s >> j; + using nlohmann::from_json; + from_json(j, ret); return { std::move(ret), true }; } template<typename t> -bool json_helper<t>::to_json(const t& self, const std::filesystem::path& pathname) noexcept { +bool json_helper::to_json(const t& self, const std::filesystem::path& pathname) { using Corrade::Utility::Error; - try { - nlohmann::json j(self); + nlohmann::json j = self; - std::ofstream s; - s.exceptions(s.exceptions() | std::ios::failbit | std::ios::badbit); - try { - s.open(pathname, std::ios_base::out | std::ios_base::trunc); - } catch (const std::ios::failure& e) { - Error{Error::Flag::NoSpace} << "failed to open '" << pathname << "' for writing: " << e.what(); - return false; - } - s << j.dump(4); - s.flush(); - } catch (const std::exception& e) { - Error{Error::Flag::NoSpace} << "failed writing to '" << pathname << "': " << e.what(); + std::ofstream s; + s.exceptions(s.exceptions() | std::ios::failbit | std::ios::badbit); + try { + s.open(pathname, std::ios_base::out | std::ios_base::trunc); + } catch (const std::ios::failure& e) { + Error{Error::Flag::NoSpace} << "failed to open '" << pathname << "' for writing: " << e.what(); return false; } - + s << j.dump(4); + s.flush(); return true; } + diff --git a/serialize/magnum-vector.hpp b/serialize/magnum-vector.hpp index 3e95c8eb..eed37708 100644 --- a/serialize/magnum-vector.hpp +++ b/serialize/magnum-vector.hpp @@ -1,25 +1,35 @@ #pragma once #include <Magnum/Magnum.h> #include <Magnum/Math/Vector.h> +#include <Magnum/Math/Vector2.h> +#include <Magnum/Math/Vector3.h> +#include <Magnum/Math/Vector4.h> +#include <Magnum/Math/Color.h> #include <nlohmann/json.hpp> namespace nlohmann { template<std::size_t N, typename T> -struct adl_serializer<Magnum::Math::Vector<N, T>> final { - static void to_json(json& j, const Magnum::Math::Vector2<T>& val) +struct adl_serializer<Magnum::Math::Vector<N, T>> { + static void to_json(json& j, const Magnum::Math::Vector<N, T>& val) { std::array<T, N> array{}; - for (std::size_t i; i < std::size(val); i++) + for (std::size_t i = 0; i < N; i++) array[i] = val[i]; j = array; } - static void from_json(const json& j, Magnum::Math::Vector2<T>& val) + static void from_json(const json& j, Magnum::Math::Vector<N, T>& val) { std::array<T, N> array = j; - for (std::size_t i; i < std::size(val); i++) + for (std::size_t i = 0; i < N; i++) val[i] = array[i]; } }; +template<typename T> struct adl_serializer<Magnum::Math::Vector2<T>> : adl_serializer<Magnum::Math::Vector<2, T>> {}; +template<typename T> struct adl_serializer<Magnum::Math::Vector3<T>> : adl_serializer<Magnum::Math::Vector<3, T>> {}; +template<typename T> struct adl_serializer<Magnum::Math::Vector4<T>> : adl_serializer<Magnum::Math::Vector<4, T>> {}; +template<typename T> struct adl_serializer<Magnum::Math::Color3<T>> : adl_serializer<Magnum::Math::Vector<3, T>> {}; +template<typename T> struct adl_serializer<Magnum::Math::Color4<T>> : adl_serializer<Magnum::Math::Vector<4, T>> {}; + } // namespace nlohmann diff --git a/test/app.hpp b/test/app.hpp new file mode 100644 index 00000000..53ee24b5 --- /dev/null +++ b/test/app.hpp @@ -0,0 +1,13 @@ +#pragma once +#include <Magnum/Magnum.h> +#include <Magnum/Platform/Sdl2Application.h> +namespace Magnum::Examples { +struct app final : Platform::Application // NOLINT(cppcoreguidelines-virtual-class-destructor) +{ + explicit app(const Arguments& arguments); + ~app(); + void drawEvent() override; + static void test_json(); + void test(); +}; +} // namespace Magnum::Examples diff --git a/test/json.cpp b/test/json.cpp new file mode 100644 index 00000000..51bc6f80 --- /dev/null +++ b/test/json.cpp @@ -0,0 +1,29 @@ +#include "app.hpp" +#include "serialize/tile-atlas.hpp" +#include "serialize/magnum-vector.hpp" +#include "serialize/json-helper.hpp" +#include "compat/assert.hpp" +#include "tile-atlas.hpp" +#include "loader.hpp" + +namespace Magnum::Examples { +void app::test_json() // NOLINT(readability-convert-member-functions-to-static) +{ + bool ret = true; + using nlohmann::to_json; + const std::filesystem::path output_dir = "f:/dev/game/build/test/"; + { + nlohmann::json j; + auto atlas = loader.tile_atlas("share/game/images/metal1.tga", {2, 2}); + ret &= json_helper::to_json(atlas, output_dir/"atlas.json"); + } + { + Magnum::Math::Vector<2, int> v2i_1{1, 2}; + Vector2 v2i_2{2, 3}; + ret &= json_helper::to_json(v2i_1, output_dir/"vec2i_1.json"); + ret &= json_helper::to_json(v2i_2, output_dir/"vec2i_2.json"); + } + ASSERT(ret); +} + +} // namespace Magnum::Examples diff --git a/test/main.cpp b/test/main.cpp index f7014255..dffb19e1 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,35 +1,26 @@ -#include <Magnum/Magnum.h> -#include <Magnum/Platform/Sdl2Application.h> -#include "compat/assert.hpp" -#include "tile-atlas.hpp" -#include "serialize/tile-atlas.hpp" -#include "serialize/json-helper.hpp" +#include "app.hpp" #include "loader.hpp" -#include "serialize/magnum-vector.hpp" +#include <filesystem> +#include <Corrade/Containers/Pair.h> +#include <Corrade/Containers/StringStlView.h> +#include <Corrade/Utility/Path.h> +#include <Magnum/Magnum.h> namespace Magnum::Examples { -struct app final : Platform::Application -{ - using dpi_policy = Platform::Implementation::Sdl2DpiScalingPolicy; - - explicit app(const Arguments& arguments); - ~app(); - void drawEvent() override; - void test(); -}; - app::app(const Arguments& arguments): Platform::Application{ arguments, Configuration{} .setTitle("Test") - .setSize({1024, 768}, dpi_policy::Physical), + .setSize({1024, 768}, Platform::Implementation::Sdl2DpiScalingPolicy::Physical), GLConfiguration{} .setSampleCount(4) - //.setFlags(Platform::Sdl2Application::GLConfiguration::Flag::Debug) + .setFlags(Platform::Sdl2Application::GLConfiguration::Flag::Debug) } { + if (auto path_opt = Utility::Path::executableLocation(); path_opt) + std::filesystem::current_path(std::string{Utility::Path::split(*path_opt).first()}); } app::~app() @@ -43,11 +34,9 @@ void app::drawEvent() Platform::Sdl2Application::exit(0); } -void app::test() // NOLINT(readability-convert-member-functions-to-static) +void app::test() { - auto atlas = loader.tile_atlas("../share/game/images/metal1.tga", {2, 2}); - bool ret = json_helper<std::shared_ptr<tile_atlas>>::to_json(atlas, "f:/dev/game/build/test/atlas.json"); - ASSERT(ret); + test_json(); } } // namespace Magnum::Examples @@ -55,15 +44,3 @@ void app::test() // NOLINT(readability-convert-member-functions-to-static) using namespace Magnum::Examples; MAGNUM_APPLICATION_MAIN(Magnum::Examples::app) - -#ifdef _MSC_VER -# include <cstdlib> -# ifdef __clang__ -# pragma clang diagnostic ignored "-Wmissing-prototypes" -# pragma clang diagnostic ignored "-Wmain" -# endif - -extern "C" int __stdcall WinMain(void*, void*, void*, int /* nCmdShow */) { - return main(__argc, __argv); -} -#endif |