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
133
|
#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;
{
int count = 0, index = -1;
bool has_count = jgroup.contains("count"s) && (count = jgroup["count"s]) != 0,
has_index = jgroup.contains("index"s);
fm_soft_assert(has_count == has_index);
fm_soft_assert(!has_index || index >= 0 && index < 1 << 20);
// todo check index within range;
}
if (jgroup.contains("pixel-size"s))
val.pixel_size = jgroup["pixel-size"s];
if (jgroup.contains("tint-mult"s))
val.tint_mult = Vector4(jgroup["tint-mult"s]);
if (jgroup.contains("tint-add"s))
val.tint_add = Vector3(jgroup["tint-add"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("default-tint"s))
val.default_tint = !!jgroup["default-tint"s];
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;
}
Info read_info_header(const json& jroot)
{
Info val { std::string(jroot["name"s]), jroot["depth"] };
return val;
}
void write_group_metadata(json& jgroup, const Group& val)
{
fm_soft_assert(jgroup.is_object());
fm_soft_assert(jgroup.empty());
//jgroup[""s] = ;
if (val.index != none)
jgroup["index"s] = val.index;
jgroup["count"s] = val.count;
jgroup["pixel-size"s] = val.pixel_size;
jgroup["tint-mult"s] = Vector4(val.tint_mult);
jgroup["tint-add"s] = Vector3(val.tint_add);
jgroup["from-rotation"s] = val.from_rotation;
jgroup["mirrored"s] = val.mirrored;
jgroup["default-tint"s] = val.default_tint;
}
} // 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
|