1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#include "wall-atlas.hpp"
#include "magnum-vector2i.hpp"
#include "magnum-vector.hpp"
#include "compat/exception.hpp"
#include <utility>
#include <string_view>
#include <Corrade/Containers/StringStl.h>
#include <Corrade/Containers/StringStlView.h>
#include <nlohmann/json.hpp>
// todo add test on dummy files that generates 100% coverage on the j.contains() blocks!
namespace floormat::Wall::detail {
using nlohmann::json;
using namespace std::string_literals;
namespace {
constexpr auto none = (uint8_t)-1;
constexpr StringView direction_names[] = { "n"_s, "e"_s, "s"_s, "w"_s, };
} // namespace
uint8_t direction_index_from_name(StringView s)
{
for (uint8_t i = 0; auto n : direction_names)
if (n == s)
return i;
else
i++;
fm_throw("bad rotation name '{}'"_cf, fmt::string_view{s.data(), s.size()});
}
StringView direction_index_to_name(size_t i)
{
fm_soft_assert(i < arraySize(direction_names));
return direction_names[i];
}
Group read_group_metadata(const json& jgroup)
{
fm_assert(jgroup.is_object());
Group val;
if (jgroup.contains("pixel-size"s))
val.pixel_size = jgroup["pixel-size"s];
if (jgroup.contains("tint"s))
std::tie(val.tint_mult, val.tint_add) = std::pair<Vector4, Vector3>{ jgroup["tint"s] };
if (jgroup.contains("from-rotation"s))
val.from_rotation = (uint8_t)direction_index_from_name(std::string{ jgroup["from-rotation"s] });
if (jgroup.contains("mirrored"s))
val.mirrored = jgroup["mirrored"s];
if (jgroup.contains("use-default-tint"s))
val.use_default_tint = jgroup["use-default-tint"s];
fm_soft_assert(val.tint_mult >= Color4{0});
return val;
}
Direction read_direction_metadata(const json& jroot, Direction_ dir)
{
std::string_view s = direction_index_to_name((size_t)dir);
if (!jroot.contains(s))
return {};
const auto& jdir = jroot[s];
Direction val;
for (auto [s_, memfn, tag] : Direction::members)
{
std::string_view s = s_;
if (!jdir.contains(s))
continue;
val.*memfn = read_group_metadata(jdir[s]);
}
return val;
}
void write_group_metadata(json& jgroup, const Group& val)
{
constexpr Group default_value;
fm_soft_assert(jgroup.is_object());
fm_soft_assert(jgroup.empty());
jgroup["pixel-size"s] = val.pixel_size;
if (val.tint_mult != default_value.tint_mult || val.tint_add != default_value.tint_add)
{
auto tint = std::pair<Vector4, Vector3>{{val.tint_mult}, {val.tint_add}};
jgroup["tint"s] = tint;
}
if (val.from_rotation != default_value.from_rotation)
{
fm_soft_assert(val.from_rotation != none && val.from_rotation < 4);
jgroup["from-rotation"s] = val.from_rotation;
}
if (val.mirrored != default_value.mirrored)
jgroup["mirrored"s] = val.mirrored;
if (val.use_default_tint)
if (val.tint_mult != default_value.tint_mult || val.tint_add != default_value.tint_add)
jgroup["use-default-tint"s] = true;
}
Info read_info_header(const json& jroot)
{
Info val { std::string(jroot["name"s]), jroot["depth"] };
return val;
}
} // namespace floormat::Wall::detail
namespace nlohmann {
using namespace floormat;
using namespace floormat::Wall::detail;
void adl_serializer<std::shared_ptr<wall_atlas>>::to_json(json& j, const std::shared_ptr<const wall_atlas>& x)
{
}
void adl_serializer<std::shared_ptr<wall_atlas>>::from_json(const json& j, std::shared_ptr<wall_atlas>& x)
{
}
} // namespace nlohmann
|