diff --git a/Src/Common/IdProvider.hpp b/Src/Common/IdProvider.hpp index ad7eb57..e8a0ffd 100644 --- a/Src/Common/IdProvider.hpp +++ b/Src/Common/IdProvider.hpp @@ -26,6 +26,47 @@ public: std::string Domain, Key; }; + struct BindDomainKeyViewInfo { + std::string_view Domain, Key; + }; + + struct KeyHash { + using is_transparent = void; + + static inline std::size_t h(std::string_view sv) noexcept { + return std::hash{}(sv); + } + + static inline std::size_t mix(std::size_t a, std::size_t b) noexcept { + a ^= b + 0x9e3779b97f4a7c15ULL + (a << 6) + (a >> 2); + return a; + } + + std::size_t operator()(const BindDomainKeyInfo& k) const noexcept { + return mix(h(k.Domain), h(k.Key)); + } + + std::size_t operator()(const BindDomainKeyViewInfo& kv) const noexcept { + return mix(h(kv.Domain), h(kv.Key)); + } + }; + + struct KeyEq { + using is_transparent = void; + + bool operator()(const BindDomainKeyInfo& a, const BindDomainKeyInfo& b) const noexcept { + return a.Domain == b.Domain && a.Key == b.Key; + } + + bool operator()(const BindDomainKeyInfo& a, const BindDomainKeyViewInfo& b) const noexcept { + return a.Domain == b.Domain && a.Key == b.Key; + } + + bool operator()(const BindDomainKeyViewInfo& a, const BindDomainKeyInfo& b) const noexcept { + return a.Domain == b.Domain && a.Key == b.Key; + } + }; + public: explicit IdProvider() { for(size_t type = 0; type < MAX_ENUM; ++type) { @@ -36,7 +77,7 @@ public: auto& sh = _shardFor(static_cast(type), "core", "none"); std::unique_lock lk(sh.mutex); - sh.map.emplace(Key{"core", "none"}, 0); + sh.map.emplace(BindDomainKeyInfo{"core", "none"}, 0); } } @@ -53,14 +94,14 @@ public: // 1) Поиск в режиме для чтения { std::shared_lock lk(sh.mutex); - if(auto it = sh.map.find(KeyView{domain, key}); it != sh.map.end()) { + if(auto it = sh.map.find(BindDomainKeyViewInfo{domain, key}); it != sh.map.end()) { return it->second; } } // 2) Блокируем и повторно ищем запись (может кто уже успел её добавить) std::unique_lock lk(sh.mutex); - if (auto it = sh.map.find(KeyView{domain, key}); it != sh.map.end()) { + if (auto it = sh.map.find(BindDomainKeyViewInfo{domain, key}); it != sh.map.end()) { return it->second; } @@ -70,7 +111,7 @@ public: std::string d(domain); std::string k(key); - sh.map.emplace(Key{d, k}, id); + sh.map.emplace(BindDomainKeyInfo{d, k}, id); sh.newlyInserted.push_back(id); _storeReverse(type, id, std::move(d), std::move(k)); @@ -159,56 +200,7 @@ public: } private: - // ---- key types for unordered_dense ---- - struct Key { - std::string domain; - std::string key; - }; - - struct KeyView { - std::string_view domain; - std::string_view key; - }; - - struct KeyHash { - using is_transparent = void; - - static inline std::size_t h(std::string_view sv) noexcept { - // если у тебя есть detail::TSVHash под string_view — можно подставить - return std::hash{}(sv); - } - - static inline std::size_t mix(std::size_t a, std::size_t b) noexcept { - a ^= b + 0x9e3779b97f4a7c15ULL + (a << 6) + (a >> 2); - return a; - } - - std::size_t operator()(const Key& k) const noexcept { - return mix(h(k.domain), h(k.key)); - } - - std::size_t operator()(const KeyView& kv) const noexcept { - return mix(h(kv.domain), h(kv.key)); - } - }; - - struct KeyEq { - using is_transparent = void; - - bool operator()(const Key& a, const Key& b) const noexcept { - return a.domain == b.domain && a.key == b.key; - } - - bool operator()(const Key& a, const KeyView& b) const noexcept { - return a.domain == b.domain && a.key == b.key; - } - - bool operator()(const KeyView& a, const Key& b) const noexcept { - return a.domain == b.domain && a.key == b.key; - } - }; - - using Map = ankerl::unordered_dense::map; + using Map = ankerl::unordered_dense::map; struct Shard { mutable std::shared_mutex mutex; @@ -237,13 +229,13 @@ private: std::array, MAX_ENUM> IdToDK; private: - Shard& _shardFor(Enum type, std::string_view domain, std::string_view key) { - const std::size_t idx = KeyHash{}(KeyView{domain, key}) % ShardCount; + Shard& _shardFor(Enum type, const std::string_view domain, const std::string_view key) { + const std::size_t idx = KeyHash{}(BindDomainKeyViewInfo{domain, key}) % ShardCount; return _Shards[static_cast(type)][idx]; } - const Shard& _shardFor(Enum type, std::string_view domain, std::string_view key) const { - const std::size_t idx = KeyHash{}(KeyView{domain, key}) % ShardCount; + const Shard& _shardFor(Enum type, const std::string_view domain, const std::string_view key) const { + const std::size_t idx = KeyHash{}(BindDomainKeyViewInfo{domain, key}) % ShardCount; return _Shards[static_cast(type)][idx]; } diff --git a/Src/Server/ContentManager.cpp b/Src/Server/ContentManager.cpp index 72abeb5..3da4517 100644 --- a/Src/Server/ContentManager.cpp +++ b/Src/Server/ContentManager.cpp @@ -7,7 +7,6 @@ namespace LV::Server { ContentManager::ContentManager(AssetsManager& am) : AM(am) { - std::fill(std::begin(NextId), std::end(NextId), 1); } ContentManager::~ContentManager() = default; @@ -124,30 +123,13 @@ void ContentManager::unRegisterModifier(EnumDefContent type, const std::string& } void ContentManager::markAllProfilesDirty(EnumDefContent type) { - const auto &table = ContentKeyToId[(int) type]; - for(const auto& domainPair : table) { - for(const auto& keyPair : domainPair.second) { - ProfileChanges[(int) type].push_back(keyPair.second); - } + const auto &table = this->idToDK()[(int) type]; + size_t counter = 0; + for(const auto& [domain, key] : table) { + ProfileChanges[static_cast(type)].push_back(counter++); } } -std::vector ContentManager::collectProfileIds(EnumDefContent type) const { - std::vector ids; - const auto &table = ContentKeyToId[(int) type]; - - for(const auto& domainPair : table) { - for(const auto& keyPair : domainPair.second) { - ids.push_back(keyPair.second); - } - } - - std::sort(ids.begin(), ids.end()); - auto last = std::unique(ids.begin(), ids.end()); - ids.erase(last, ids.end()); - return ids; -} - ContentManager::Out_buildEndProfiles ContentManager::buildEndProfiles() { Out_buildEndProfiles result; @@ -156,6 +138,8 @@ ContentManager::Out_buildEndProfiles ContentManager::buildEndProfiles() { std::sort(keys.begin(), keys.end()); auto iterErase = std::unique(keys.begin(), keys.end()); keys.erase(iterErase, keys.end()); + + } return result; diff --git a/Src/Server/ContentManager.hpp b/Src/Server/ContentManager.hpp index 828ad9b..6a33fe3 100644 --- a/Src/Server/ContentManager.hpp +++ b/Src/Server/ContentManager.hpp @@ -2,6 +2,9 @@ #include "Common/Abstract.hpp" #include "AssetsManager.hpp" +#include "Common/IdProvider.hpp" +#include +#include #include #include @@ -37,18 +40,247 @@ struct DefPortal : public ResourceBase { }; struct DefEntity : public ResourceBase { }; struct DefItem : public ResourceBase { }; -class ContentManager { +/* + DK to id + id to profile +*/ + +class ContentManager : public IdProvider { +public: + class LRU { + public: + LRU(ContentManager& cm) + : CM(&cm) + { + } + + LRU(const LRU&) = default; + LRU(LRU&&) = default; + LRU& operator=(const LRU&) = default; + LRU& operator=(LRU&&) = default; + + ResourceId getId(EnumDefContent type, const std::string_view domain, const std::string_view key) { + auto iter = DKToId[static_cast(type)].find(BindDomainKeyViewInfo(domain, key)); + if(iter == DKToId[static_cast(type)].end()) { + ResourceId id = CM->getId(type, domain, key); + DKToId[static_cast(type)].emplace_hint(iter, BindDomainKeyInfo((std::string) domain, (std::string) key), id); + return id; + } + + return iter->second; + + // switch(type) { + // case EnumDefContent::Voxel: + + // case EnumDefContent::Node: + // case EnumDefContent::World: + // case EnumDefContent::Portal: + // case EnumDefContent::Entity: + // case EnumDefContent::Item: + // default: + // std::unreachable(); + // } + } + + ResourceId getIdVoxel(const std::string_view domain, const std::string_view key) { + return getId(EnumDefContent::Voxel, domain, key); + } + + ResourceId getIdNode(const std::string_view domain, const std::string_view key) { + return getId(EnumDefContent::Node, domain, key); + } + + ResourceId getIdWorld(const std::string_view domain, const std::string_view key) { + return getId(EnumDefContent::World, domain, key); + } + + ResourceId getIdPortal(const std::string_view domain, const std::string_view key) { + return getId(EnumDefContent::Portal, domain, key); + } + + ResourceId getIdEntity(const std::string_view domain, const std::string_view key) { + return getId(EnumDefContent::Entity, domain, key); + } + + ResourceId getIdItem(const std::string_view domain, const std::string_view key) { + return getId(EnumDefContent::Item, domain, key); + } + + private: + ContentManager* CM; + + std::array< + ankerl::unordered_dense::map, + MAX_ENUM + > DKToId; + + std::unordered_map*> Profiles_Voxel; + std::unordered_map*> Profiles_Node; + std::unordered_map*> Profiles_World; + std::unordered_map*> Profiles_Portal; + std::unordered_map*> Profiles_Entity; + std::unordered_map*> Profiles_Item; + }; + +public: + ContentManager(AssetsManager &am); + ~ContentManager(); + + // Регистрирует определение контента + void registerBase(EnumDefContent type, const std::string& domain, const std::string& key, const sol::table& profile); + void unRegisterBase(EnumDefContent type, const std::string& domain, const std::string& key); + // Регистрация модификатора предмета модом + void registerModifier(EnumDefContent type, const std::string& mod, const std::string& domain, const std::string& key, const sol::table& profile); + void unRegisterModifier(EnumDefContent type, const std::string& mod, const std::string& domain, const std::string& key); + // Пометить все профили типа как изменённые (например, после перезагрузки ассетов) + void markAllProfilesDirty(EnumDefContent type); + // Список всех зарегистрированных профилей выбранного типа + std::vector collectProfileIds(EnumDefContent type) const; + // Компилирует изменённые профили + struct Out_buildEndProfiles { + std::vector ChangedProfiles[MAX_ENUM]; + }; + + Out_buildEndProfiles buildEndProfiles(); + + + std::optional& getEntry_Voxel(ResourceId resId) { + std::shared_lock mtx(Profiles_Mtx[static_cast(EnumDefContent::Voxel)]); + + assert(resId / TableEntry::ChunkSize <= Profiles_Voxel.size()); + return Profiles_Voxel[resId / TableEntry::ChunkSize]->Entries[resId % TableEntry::ChunkSize]; + } + + std::optional& getEntry_Voxel(const std::string_view domain, const std::string_view key) { + return getEntry_Voxel(getId(EnumDefContent::Voxel, domain, key)); + } + + std::optional& getEntry_Node(ResourceId resId) { + std::shared_lock mtx(Profiles_Mtx[static_cast(EnumDefContent::Node)]); + + assert(resId / TableEntry::ChunkSize < Profiles_Node.size()); + return Profiles_Node[resId / TableEntry::ChunkSize]->Entries[resId % TableEntry::ChunkSize]; + } + + std::optional& getEntry_Node(const std::string_view domain, const std::string_view key) { + return getEntry_Node(getId(EnumDefContent::Node, domain, key)); + } + + std::optional& getEntry_World(ResourceId resId) { + std::shared_lock mtx(Profiles_Mtx[static_cast(EnumDefContent::World)]); + + assert(resId / TableEntry::ChunkSize < Profiles_World.size()); + return Profiles_World[resId / TableEntry::ChunkSize]->Entries[resId % TableEntry::ChunkSize]; + } + + std::optional& getEntry_World(const std::string_view domain, const std::string_view key) { + return getEntry_World(getId(EnumDefContent::World, domain, key)); + } + + std::optional& getEntry_Portal(ResourceId resId) { + std::shared_lock mtx(Profiles_Mtx[static_cast(EnumDefContent::Portal)]); + + assert(resId / TableEntry::ChunkSize < Profiles_Portal.size()); + return Profiles_Portal[resId / TableEntry::ChunkSize]->Entries[resId % TableEntry::ChunkSize]; + } + + std::optional& getEntry_Portal(const std::string_view domain, const std::string_view key) { + return getEntry_Portal(getId(EnumDefContent::Portal, domain, key)); + } + + std::optional& getEntry_Entity(ResourceId resId) { + std::shared_lock mtx(Profiles_Mtx[static_cast(EnumDefContent::Entity)]); + + assert(resId / TableEntry::ChunkSize < Profiles_Entity.size()); + return Profiles_Entity[resId / TableEntry::ChunkSize]->Entries[resId % TableEntry::ChunkSize]; + } + + std::optional& getEntry_Entity(const std::string_view domain, const std::string_view key) { + return getEntry_Entity(getId(EnumDefContent::Entity, domain, key)); + } + + std::optional& getEntry_Item(ResourceId resId) { + std::shared_lock mtx(Profiles_Mtx[static_cast(EnumDefContent::Item)]); + + assert(resId / TableEntry::ChunkSize < Profiles_Item.size()); + return Profiles_Item[resId / TableEntry::ChunkSize]->Entries[resId % TableEntry::ChunkSize]; + } + + std::optional& getEntry_Item(const std::string_view domain, const std::string_view key) { + return getEntry_Item(getId(EnumDefContent::Item, domain, key)); + } + + ResourceId getId(EnumDefContent type, const std::string_view domain, const std::string_view key) { + ResourceId resId = IdProvider::getId(type, domain, key); + + switch(type) { + case EnumDefContent::Voxel: + if(resId >= Profiles_Voxel.size()*TableEntry::ChunkSize) { + std::unique_lock mtx(Profiles_Mtx[static_cast(EnumDefContent::Voxel)]); + if(resId >= Profiles_Voxel.size()*TableEntry::ChunkSize) + Profiles_Voxel.push_back(std::make_unique>()); + } + break; + case EnumDefContent::Node: + if(resId >= Profiles_Node.size()*TableEntry::ChunkSize) { + std::unique_lock mtx(Profiles_Mtx[static_cast(EnumDefContent::Node)]); + if(resId >= Profiles_Node.size()*TableEntry::ChunkSize) + Profiles_Node.push_back(std::make_unique>()); + } + break; + case EnumDefContent::World: + if(resId >= Profiles_World.size()*TableEntry::ChunkSize) { + std::unique_lock mtx(Profiles_Mtx[static_cast(EnumDefContent::World)]); + if(resId >= Profiles_World.size()*TableEntry::ChunkSize) + Profiles_World.push_back(std::make_unique>()); + } + break; + case EnumDefContent::Portal: + if(resId >= Profiles_Portal.size()*TableEntry::ChunkSize) { + std::unique_lock mtx(Profiles_Mtx[static_cast(EnumDefContent::Portal)]); + if(resId >= Profiles_Portal.size()*TableEntry::ChunkSize) + Profiles_Portal.push_back(std::make_unique>()); + } + break; + case EnumDefContent::Entity: + if(resId >= Profiles_Entity.size()*TableEntry::ChunkSize) { + std::unique_lock mtx(Profiles_Mtx[static_cast(EnumDefContent::Entity)]); + if(resId >= Profiles_Entity.size()*TableEntry::ChunkSize) + Profiles_Entity.push_back(std::make_unique>()); + } + break; + case EnumDefContent::Item: + if(resId >= Profiles_Item.size()*TableEntry::ChunkSize) { + std::unique_lock mtx(Profiles_Mtx[static_cast(EnumDefContent::Item)]); + if(resId >= Profiles_Item.size()*TableEntry::ChunkSize) + Profiles_Item.push_back(std::make_unique>()); + } + break; + default: + std::unreachable(); + } + + return resId; + } + + LRU createLRU() { + return {*this}; + } + +private: template struct TableEntry { static constexpr size_t ChunkSize = 4096; std::array, ChunkSize> Entries; }; + void registerBase_Node(ResourceId id, const std::string& domain, const std::string& key, const sol::table& profile); + void registerBase_World(ResourceId id, const std::string& domain, const std::string& key, const sol::table& profile); + void registerBase_Entity(ResourceId id, const std::string& domain, const std::string& key, const sol::table& profile); - // Следующие идентификаторы регистрации контента - ResourceId NextId[(int) EnumDefContent::MAX_ENUM] = {}; - // Домен -> {ключ -> идентификатор} - std::unordered_map> ContentKeyToId[(int) EnumDefContent::MAX_ENUM]; + + TOS::Logger LOG = "Server>ContentManager"; + AssetsManager& AM; // Профили зарегистрированные модами std::vector>> Profiles_Base_Voxel; @@ -69,151 +301,16 @@ class ContentManager { // Затронутые профили в процессе регистраций // По ним будут пересобраны профили - std::vector ProfileChanges[(int) EnumDefContent::MAX_ENUM]; + std::vector ProfileChanges[MAX_ENUM]; // Конечные профили контента + std::array Profiles_Mtx; std::vector>> Profiles_Voxel; std::vector>> Profiles_Node; std::vector>> Profiles_World; std::vector>> Profiles_Portal; std::vector>> Profiles_Entity; std::vector>> Profiles_Item; - - std::optional& getEntry_Voxel(ResourceId resId) { return Profiles_Voxel[resId / TableEntry::ChunkSize]->Entries[resId % TableEntry::ChunkSize];} - std::optional& getEntry_Node(ResourceId resId) { return Profiles_Node[resId / TableEntry::ChunkSize]->Entries[resId % TableEntry::ChunkSize];} - std::optional& getEntry_World(ResourceId resId) { return Profiles_World[resId / TableEntry::ChunkSize]->Entries[resId % TableEntry::ChunkSize];} - std::optional& getEntry_Portal(ResourceId resId) { return Profiles_Portal[resId / TableEntry::ChunkSize]->Entries[resId % TableEntry::ChunkSize];} - std::optional& getEntry_Entity(ResourceId resId) { return Profiles_Entity[resId / TableEntry::ChunkSize]->Entries[resId % TableEntry::ChunkSize];} - std::optional& getEntry_Item(ResourceId resId) { return Profiles_Item[resId / TableEntry::ChunkSize]->Entries[resId % TableEntry::ChunkSize];} - - ResourceId getId(EnumDefContent type, const std::string& domain, const std::string& key) { - if(auto iterCKTI = ContentKeyToId[(int) type].find(domain); iterCKTI != ContentKeyToId[(int) type].end()) { - if(auto iterKey = iterCKTI->second.find(key); iterKey != iterCKTI->second.end()) { - return iterKey->second; - } - } - - ResourceId resId = NextId[(int) type]++; - ContentKeyToId[(int) type][domain][key] = resId; - - switch(type) { - case EnumDefContent::Voxel: - if(resId >= Profiles_Voxel.size()*TableEntry::ChunkSize) - Profiles_Voxel.push_back(std::make_unique>()); - break; - case EnumDefContent::Node: - if(resId >= Profiles_Node.size()*TableEntry::ChunkSize) - Profiles_Node.push_back(std::make_unique>()); - break; - case EnumDefContent::World: - if(resId >= Profiles_World.size()*TableEntry::ChunkSize) - Profiles_World.push_back(std::make_unique>()); - break; - case EnumDefContent::Portal: - if(resId >= Profiles_Portal.size()*TableEntry::ChunkSize) - Profiles_Portal.push_back(std::make_unique>()); - break; - case EnumDefContent::Entity: - if(resId >= Profiles_Entity.size()*TableEntry::ChunkSize) - Profiles_Entity.push_back(std::make_unique>()); - break; - case EnumDefContent::Item: - if(resId >= Profiles_Item.size()*TableEntry::ChunkSize) - Profiles_Item.push_back(std::make_unique>()); - break; - default: - std::unreachable(); - } - - return resId; - } - - void registerBase_Node(ResourceId id, const std::string& domain, const std::string& key, const sol::table& profile); - void registerBase_World(ResourceId id, const std::string& domain, const std::string& key, const sol::table& profile); - void registerBase_Entity(ResourceId id, const std::string& domain, const std::string& key, const sol::table& profile); - -public: - ContentManager(AssetsManager &am); - ~ContentManager(); - - // Регистрирует определение контента - void registerBase(EnumDefContent type, const std::string& domain, const std::string& key, const sol::table& profile); - void unRegisterBase(EnumDefContent type, const std::string& domain, const std::string& key); - // Регистрация модификатора предмета модом - void registerModifier(EnumDefContent type, const std::string& mod, const std::string& domain, const std::string& key, const sol::table& profile); - void unRegisterModifier(EnumDefContent type, const std::string& mod, const std::string& domain, const std::string& key); - // Пометить все профили типа как изменённые (например, после перезагрузки ассетов) - void markAllProfilesDirty(EnumDefContent type); - // Список всех зарегистрированных профилей выбранного типа - std::vector collectProfileIds(EnumDefContent type) const; - // Компилирует изменённые профили - struct Out_buildEndProfiles { - std::vector ChangedProfiles[(int) EnumDefContent::MAX_ENUM]; - }; - - Out_buildEndProfiles buildEndProfiles(); - - std::optional getProfile_Voxel(ResourceId id) { - assert(id < Profiles_Voxel.size()*TableEntry::ChunkSize); - auto& value = Profiles_Voxel[id / TableEntry::ChunkSize]->Entries[id % TableEntry::ChunkSize]; - if(value) - return {&*value}; - else - return std::nullopt; - } - - std::optional getProfile_Node(ResourceId id) { - assert(id < Profiles_Node.size()*TableEntry::ChunkSize); - auto& value = Profiles_Node[id / TableEntry::ChunkSize]->Entries[id % TableEntry::ChunkSize]; - if(value) - return {&*value}; - else - return std::nullopt; - } - - std::optional getProfile_World(ResourceId id) { - assert(id < Profiles_World.size()*TableEntry::ChunkSize); - auto& value = Profiles_World[id / TableEntry::ChunkSize]->Entries[id % TableEntry::ChunkSize]; - if(value) - return {&*value}; - else - return std::nullopt; - } - - std::optional getProfile_Portal(ResourceId id) { - assert(id < Profiles_Portal.size()*TableEntry::ChunkSize); - auto& value = Profiles_Portal[id / TableEntry::ChunkSize]->Entries[id % TableEntry::ChunkSize]; - if(value) - return {&*value}; - else - return std::nullopt; - } - - std::optional getProfile_Entity(ResourceId id) { - assert(id < Profiles_Entity.size()*TableEntry::ChunkSize); - auto& value = Profiles_Entity[id / TableEntry::ChunkSize]->Entries[id % TableEntry::ChunkSize]; - if(value) - return {&*value}; - else - return std::nullopt; - } - - std::optional getProfile_Item(ResourceId id) { - assert(id < Profiles_Item.size()*TableEntry::ChunkSize); - auto& value = Profiles_Item[id / TableEntry::ChunkSize]->Entries[id % TableEntry::ChunkSize]; - if(value) - return {&*value}; - else - return std::nullopt; - } - - ResourceId getContentId(EnumDefContent type, const std::string& domain, const std::string& key) { - return getId(type, domain, key); - } - -private: - TOS::Logger LOG = "Server>ContentManager"; - AssetsManager& AM; }; } diff --git a/Src/Server/GameServer.cpp b/Src/Server/GameServer.cpp index 060847c..9279fb0 100644 --- a/Src/Server/GameServer.cpp +++ b/Src/Server/GameServer.cpp @@ -487,7 +487,7 @@ std::variant, std::vector> resolveDepends(cons GameServer::GameServer(asio::io_context &ioc, fs::path worldPath) : AsyncObject(ioc), - Content(ioc) + Content(ioc), BackingAsyncLua(Content.CM) { init(worldPath); } @@ -778,17 +778,19 @@ void GameServer::BackingAsyncLua_t::run(int id) { out.Voxels.clear(); out.Entityes.clear(); + auto lru = CM.createLRU(); + { - constexpr DefNodeId kNodeAir = 0; - constexpr DefNodeId kNodeGrass = 2; - constexpr uint8_t kMetaGrass = 1; - constexpr DefNodeId kNodeDirt = 3; - constexpr DefNodeId kNodeStone = 4; - constexpr DefNodeId kNodeWood = 1; - constexpr DefNodeId kNodeLeaves = 5; - constexpr DefNodeId kNodeLava = 7; - constexpr DefNodeId kNodeWater = 8; - constexpr DefNodeId kNodeFire = 9; + DefNodeId kNodeAir = 0; + DefNodeId kNodeGrass = lru.getIdNode("test", "grass"); + uint8_t kMetaGrass = 1; + DefNodeId kNodeDirt = lru.getIdNode("test", "dirt"); + DefNodeId kNodeStone = lru.getIdNode("test", "stone"); + DefNodeId kNodeWood = lru.getIdNode("test", "wood"); + DefNodeId kNodeLeaves = lru.getIdNode("test", "leaves"); + DefNodeId kNodeLava = lru.getIdNode("test", "lava"); + DefNodeId kNodeWater = lru.getIdNode("test", "water"); + DefNodeId kNodeFire = lru.getIdNode("test", "fire"); auto hash32 = [](uint32_t x) { x ^= x >> 16; @@ -1355,7 +1357,7 @@ void GameServer::init(fs::path worldPath) { // Content.CM.registerBase(EnumDefContent::Node, "core", "none", t); Content.CM.registerBase(EnumDefContent::World, "test", "devel_world", t); Content.CM.registerBase(EnumDefContent::Entity, "core", "player", t); - PlayerEntityDefId = Content.CM.getContentId(EnumDefContent::Entity, "core", "player"); + // PlayerEntityDefId = Content.CM.getContentId(EnumDefContent::Entity, "core", "player"); } initLuaPre(); diff --git a/Src/Server/GameServer.hpp b/Src/Server/GameServer.hpp index ff62d5b..ca07374 100644 --- a/Src/Server/GameServer.hpp +++ b/Src/Server/GameServer.hpp @@ -249,6 +249,13 @@ class GameServer : public AsyncObject { std::vector Threads; TOS::SpinlockObject>>> NoiseIn; TOS::SpinlockObject>> RegionOut; + ContentManager &CM; + + BackingAsyncLua_t(ContentManager& cm) + : CM(cm) + { + + } void stop() { NeedShutdown = true;