summaryrefslogtreecommitdiffhomepage
path: root/serialize/world-writer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'serialize/world-writer.cpp')
-rw-r--r--serialize/world-writer.cpp35
1 files changed, 33 insertions, 2 deletions
diff --git a/serialize/world-writer.cpp b/serialize/world-writer.cpp
index 4bf7315f..99ae0b61 100644
--- a/serialize/world-writer.cpp
+++ b/serialize/world-writer.cpp
@@ -16,7 +16,7 @@
#include <cstring>
#include <vector>
#include <algorithm>
-#include <Corrade/Containers/StringView.h>
+#include <Corrade/Containers/StringStlHash.h>
#include <Corrade/Utility/Path.h>
using namespace floormat;
@@ -53,20 +53,23 @@ private:
atlasid intern_atlas(const tile_image_proto& img);
atlasid maybe_intern_atlas(const tile_image_proto& img);
scenery_pair intern_scenery(const scenery& sc, bool create);
+ uint32_t intern_string(StringView name);
void serialize_new_scenery(const chunk& c, writer_t& s);
void serialize_chunk(const chunk& c, chunk_coords coord);
void serialize_atlases();
void serialize_scenery();
+ void serialize_strings();
void load_scenery_1(const serialized_scenery& s);
void load_scenery();
const world* _world;
- std::vector<char> atlas_buf, scenery_buf, chunk_buf, file_buf;
+ std::vector<char> atlas_buf, scenery_buf, chunk_buf, file_buf, string_buf;
std::vector<std::vector<char>> chunk_bufs;
std::unordered_map<const void*, interned_atlas> tile_images;
std::unordered_map<const void*, std::vector<interned_scenery>> scenery_map;
+ std::unordered_map<StringView, uint32_t> string_map;
atlasid scenery_map_size = 0;
};
@@ -80,6 +83,13 @@ writer_state::writer_state(const world& world) : _world{&world}
chunk_bufs.reserve(world.chunks().size());
atlas_buf.reserve(atlas_name_max * 64);
scenery_map.reserve(64);
+ string_map.reserve(64);
+}
+
+uint32_t writer_state::intern_string(StringView name)
+{
+ auto [kv, fresh] = string_map.try_emplace(name, string_map.size());
+ return kv->second;
}
atlasid writer_state::intern_atlas(const tile_image_proto& img)
@@ -285,6 +295,24 @@ void writer_state::serialize_scenery()
scenery_buf.resize(s.bytes_written());
}
+void writer_state::serialize_strings()
+{
+ static_assert(character_name_max <= string_max);
+ auto len = 0_uz;
+ for (const auto& [k, v] : string_map)
+ {
+ fm_assert(k.size()+1 < string_max);
+ len += k.size()+1;
+ }
+ string_buf.resize(sizeof(uint32_t) + len);
+ auto s = binary_writer{string_buf.begin()};
+ s << (uint32_t)string_map.size();
+ for (const auto& [k, v] : string_map)
+ s.write_asciiz_string(k);
+ fm_assert(s.bytes_written() == sizeof(uint32_t) + len);
+ fm_assert(s.bytes_written() == string_buf.size());
+}
+
const auto def_char_bbox_size = character_proto{}.bbox_size;
const auto def_char_pass = character_proto{}.pass;
@@ -471,6 +499,7 @@ ArrayView<const char> writer_state::serialize_world()
}
serialize_atlases();
serialize_scenery();
+ serialize_strings();
using proto_t = std::decay_t<decltype(proto_version)>;
fm_assert(_world->size() <= int_max<chunksiz>);
@@ -481,6 +510,7 @@ ArrayView<const char> writer_state::serialize_world()
len += sizeof(proto_t);
len += atlas_buf.size();
len += scenery_buf.size();
+ len += string_buf.size();
len += sizeof(object_id);
len += sizeof(chunksiz);
for (const auto& buf : chunk_bufs)
@@ -505,6 +535,7 @@ ArrayView<const char> writer_state::serialize_world()
copy_int((proto_t)proto_version);
copy(atlas_buf);
copy(scenery_buf);
+ copy(string_buf);
copy_int((object_id)_world->entity_counter());
copy_int((chunksiz)_world->size());
for (const auto& buf : chunk_bufs)