summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-01-20 19:01:20 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-01-20 19:01:20 +0100
commit670d15fbe177ed7018d8102ad5dc04c0c4a2d783 (patch)
treec8733d0abb9141b1a74650af52b6a6eb8ee78fe5
parentad9cd66554fc2b57b56ca07f33b87fd16c4cfdab (diff)
w
-rw-r--r--serialize/savegame.cpp67
1 files changed, 21 insertions, 46 deletions
diff --git a/serialize/savegame.cpp b/serialize/savegame.cpp
index 829459b7..765d0084 100644
--- a/serialize/savegame.cpp
+++ b/serialize/savegame.cpp
@@ -50,12 +50,14 @@ struct string_container
StringView str;
bool operator==(const string_container&) const = default;
+#if 0
friend void swap(string_container& a, string_container& b)
{
auto tmp = a.str;
a.str = b.str;
b.str = tmp;
}
+#endif
};
struct FILE_raii final
@@ -68,26 +70,8 @@ private:
FILE* s;
};
-} // namespace
-
-} // namespace floormat::Serialize
-
-using floormat::Serialize::string_container;
using floormat::Hash::fnvhash_buf;
-template<> struct std::hash<string_container>
-{
- size_t operator()(const string_container& x) const noexcept
- {
- return fnvhash_buf(x.str.data(), x.str.size());
- }
-};
-
-
-namespace floormat::Serialize {
-
-namespace {
-
template<typename T> T& non_const(const T& value) { return const_cast<T&>(value); }
template<typename T> T& non_const(T& value) = delete;
template<typename T> T& non_const(T&& value) = delete;
@@ -95,13 +79,6 @@ template<typename T> T& non_const(const T&& value) = delete;
constexpr size_t vector_initial_size = 128, hash_initial_size = vector_initial_size*2;
-template<typename T>
-struct magic
-{
- using type = T;
- uint16_t magic;
-};
-
struct buffer
{
std::unique_ptr<char[]> data;
@@ -149,7 +126,7 @@ struct visitor_
template<typename T, typename F>
requires (std::is_arithmetic_v<T> && std::is_fundamental_v<T>)
- void visit(T& x, F&& f)
+ static void visit(T& x, F&& f)
{
f(x);
}
@@ -161,14 +138,6 @@ struct visitor_
do_visit(x.data()[i], f);
}
-#if 0
- template<typename F>
- void visit(StringView str, F&& f)
- {
- f(str);
- }
-#endif
-
template<typename E, typename F>
requires std::is_enum_v<E>
void visit(E& x, F&& f)
@@ -220,10 +189,16 @@ struct visitor_
struct writer final : visitor_<writer>
{
+ using string_hasher = decltype(
+ [](const string_container& x) {
+ return fnvhash_buf(x.str.data(), x.str.size());
+ }
+ );
+
const world& w;
std::vector<StringView> string_array{};
- tsl::robin_map<string_container, uint32_t> string_map{hash_initial_size};
+ tsl::robin_map<string_container, uint32_t, string_hasher> string_map{hash_initial_size};
std::vector<serialized_atlas> atlas_array{};
tsl::robin_map<const void*, uint32_t> atlas_map{hash_initial_size};
@@ -232,7 +207,7 @@ struct writer final : visitor_<writer>
buffer header_buf{}, string_buf{};
- writer(const world& w) : w{w} { } // added to avoid spurious warning until GCC 14: warning: missing initializer for member writer::<anonymous>
+ writer(const world& w) : w{w} { } // added to avoid spurious warning until GCC 14: warning: missing initializer for member ::<anonymous>
struct size_counter
{
@@ -392,23 +367,23 @@ ok: do_visit(intern_string(name), f);
void serialize_chunk_(chunk& c, buffer& buf)
{
+ const auto fn = [this](chunk& c, auto&& f) {
+ do_visit(chunk_magic, f);
+ do_visit(c.coord(), f);
+ for (uint32_t i = 0; i < TILE_COUNT; i++)
+ serialize_tile_(c[i], f);
+ serialize_objects_(c, f);
+ };
+
size_t len = 0;
auto ctr = size_counter{len};
- do_visit(chunk_magic, ctr);
- do_visit(c.coord(), ctr);
+ fn(c, ctr);
fm_assert(len > 0);
- for (uint32_t i = 0; i < TILE_COUNT; i++)
- serialize_tile_(c[i], ctr);
- serialize_objects_(c, ctr);
buf = buffer{len};
binary_writer<char*> s{&buf.data[0], buf.size};
byte_writer b{s};
- do_visit(chunk_magic, b);
- do_visit(c.coord(), b);
- for (uint32_t i = 0; i < TILE_COUNT; i++)
- serialize_tile_(c[i], b);
- serialize_objects_(c, b);
+ fn(c, b);
fm_assert(s.bytes_written() == s.bytes_allocated());
}