|
|
@@ -1,10 +1,34 @@
|
|
|
#include "mesh_decoder.h"
|
|
|
#include "mesh_codec.hpp"
|
|
|
+#include "third_party/static_block.hpp"
|
|
|
+#include "impl/main_impl.h"
|
|
|
|
|
|
#include <unordered_map>
|
|
|
|
|
|
using namespace mesh_codec;
|
|
|
|
|
|
+namespace mesh_decoder_impl {
|
|
|
+
|
|
|
+ using mesh_map_type =
|
|
|
+ std::unordered_map<size_t, mesh_ptr>;
|
|
|
+ mesh_map_type mesh_pool;
|
|
|
+
|
|
|
+ static_block {
|
|
|
+ register_cleanup_func([] { mesh_pool.clear(); });
|
|
|
+ }
|
|
|
+
|
|
|
+ using hasher_type = std::hash<std::string>;
|
|
|
+ hasher_type name_hasher;
|
|
|
+
|
|
|
+ mesh_ptr get_no_transfer_mesh(size_t name) {
|
|
|
+ assert(mesh_pool.contains(name));
|
|
|
+ return mesh_pool.at(name);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+using namespace mesh_decoder_impl;
|
|
|
+
|
|
|
struct mesh_decoder::impl {
|
|
|
|
|
|
using cache_map_type =
|
|
|
@@ -26,6 +50,12 @@ struct mesh_decoder::impl {
|
|
|
mesh_ptr decode(const data_type &data) {
|
|
|
auto reader = network_reader(data);
|
|
|
auto flag = reader.read_value<flag_type>();
|
|
|
+
|
|
|
+ if (flag == FLAG_NO_TRANSFER) {
|
|
|
+ auto name = reader.read_value<size_t>();
|
|
|
+ return get_no_transfer_mesh(name);
|
|
|
+ }
|
|
|
+
|
|
|
auto id = reader.read_value<hash_type>();
|
|
|
if (cache_map.contains(id)) {
|
|
|
return cache_map.at(id);
|
|
|
@@ -52,4 +82,18 @@ mesh_decoder::~mesh_decoder() = default;
|
|
|
|
|
|
mesh_ptr mesh_decoder::decode(const data_type &data) {
|
|
|
return pimpl->decode(data);
|
|
|
+}
|
|
|
+
|
|
|
+void register_mesh_file(const std::string &name,
|
|
|
+ const std::string &path) {
|
|
|
+ auto mesh = mesh_type::create({.path = path});
|
|
|
+ auto name_id = name_hasher(name);
|
|
|
+ assert(!mesh_pool.contains(name_id));
|
|
|
+ mesh_pool.emplace(name_id, mesh);
|
|
|
+}
|
|
|
+
|
|
|
+void register_mesh_list(const YAML::Node &conf_list) {
|
|
|
+ for (auto &conf: conf_list) {
|
|
|
+ register_mesh_file(LOAD_STR("name"), LOAD_STR("path"));
|
|
|
+ }
|
|
|
}
|