summaryrefslogtreecommitdiffhomepage
path: root/serialize/scenery.cpp
blob: b2490739b085e868d8e0a8be2be58b5236cafbd2 (plain)
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
#include "scenery.hpp"
#include "anim-atlas.hpp"
#include "compat/assert.hpp"
#include "loader/loader.hpp"
#include "serialize/corrade-string.hpp"
#include <array>
#include <Corrade/Containers/StringStlView.h>
#include <nlohmann/json.hpp>

namespace {

using namespace floormat;

constexpr struct {
    scenery_type value = scenery_type::none;
    StringView str;
} scenery_type_map[] = {
    { scenery_type::none,    "none"_s    },
    { scenery_type::generic, "generic"_s },
    { scenery_type::door,    "door"_s    },
    { scenery_type::object,  "object"_s  },
};

constexpr struct {
    rotation value = rotation::N;
    StringView str;
} rotation_map[] = {
    { rotation::N,  "n"_s  },
    { rotation::NE, "ne"_s },
    { rotation::E,  "e"_s  },
    { rotation::SE, "se"_s },
    { rotation::S,  "s"_s  },
    { rotation::SW, "sw"_s },
    { rotation::W,  "w"_s  },
    { rotation::NW, "nw"_s },
};

template<std::size_t N, typename T>
auto foo_from_string(StringView str, const T(&map)[N], const char* desc)
{
    for (const auto& [value, str2] : map)
        if (str2 == str)
            return value;
    fm_abort("wrong %s string '%s'", desc, str.data());
}

template<std::size_t N, typename T>
StringView foo_to_string(auto type, const T(&map)[N], const char* desc)
{
    for (const auto& [type2, str] : map)
        if (type2 == type)
            return str;
    fm_abort("wrong %s enum '%hhu'", desc, type);
}

} // namespace

namespace floormat {

} // namespace floormat

namespace nlohmann {

void adl_serializer<scenery_type>::to_json(json& j, const scenery_type val)
{
    j = foo_to_string(val, scenery_type_map, "scenery_type");
}

void adl_serializer<scenery_type>::from_json(const json& j, scenery_type& val)
{
    val = foo_from_string(j, scenery_type_map, "scenery_type");
}

void adl_serializer<rotation>::to_json(json& j, const rotation val)
{
    j = foo_to_string(val, rotation_map, "rotation");
}

void adl_serializer<rotation>::from_json(const json& j, rotation& val)
{
    val = foo_from_string(j, rotation_map, "rotation");
}

void adl_serializer<scenery_proto>::to_json(json& j, const scenery_proto& val)
{
    const scenery& f = val.frame;
    j["type"] = f.type;
    fm_assert(val.atlas);
    j["atlas-name"] = val.atlas->name();
    fm_assert(f.frame != scenery::NO_FRAME);
    j["frame"] = f.frame;
    j["rotation"] = f.r;
    j["passable"] = f.passable;
    j["blocks-view"] = f.blocks_view;
    j["active"] = f.active;
}

void adl_serializer<scenery_proto>::from_json(const json& j, scenery_proto& val)
{
    auto& f = val.frame;
    f.type = j["type"];
    StringView atlas_name = j["atlas-name"];
    val.atlas = loader.anim_atlas(atlas_name);
    f = {};
    if (j.contains("frame"))
        f.frame = j["frame"];
    if (j.contains("animated"))
        f.animated = j["animated"];
    fm_assert(f.animated == (f.frame == scenery::NO_FRAME));
    if (j.contains("rotation"))
        f.r = j["rotation"];
    if (j.contains("passable"))
        f.passable = j["passable"];
    if (j.contains("blocks-view"))
        f.blocks_view = j["blocks-view"];
    if (j.contains("active"))
        f.active = j["active"];
}

} // namespace nlohmann