Отладка получения ресурсов

This commit is contained in:
2025-09-02 13:03:39 +06:00
parent 05570b0844
commit 4eef3ca211
10 changed files with 149 additions and 65 deletions

View File

@@ -249,7 +249,7 @@ void AssetsManager::readWriteThread(AsyncUseControl::Lock lock) {
// Нашли // Нашли
finded = true; finded = true;
Resource res = Resource(end).convertToMem(); Resource res = Resource(end).convertToMem();
ReadyQueue.lock()->emplace_back(rk.Hash, res); ReadyQueue.lock()->emplace_back(rk, res);
break; break;
} }
} }
@@ -264,7 +264,7 @@ void AssetsManager::readWriteThread(AsyncUseControl::Lock lock) {
int size = sqlite3_column_bytes(STMT_INLINE_GET, 0); int size = sqlite3_column_bytes(STMT_INLINE_GET, 0);
Resource res(hash, size); Resource res(hash, size);
finded = true; finded = true;
ReadyQueue.lock()->emplace_back(rk.Hash, res); ReadyQueue.lock()->emplace_back(rk, res);
} else if(errc != SQLITE_DONE) { } else if(errc != SQLITE_DONE) {
sqlite3_reset(STMT_INLINE_GET); sqlite3_reset(STMT_INLINE_GET);
MAKE_ERROR("Не удалось выполнить подготовленный запрос STMT_INLINE_GET: " << sqlite3_errmsg(DB)); MAKE_ERROR("Не удалось выполнить подготовленный запрос STMT_INLINE_GET: " << sqlite3_errmsg(DB));
@@ -323,7 +323,7 @@ void AssetsManager::readWriteThread(AsyncUseControl::Lock lock) {
if(!finded) { if(!finded) {
// Не нашли // Не нашли
ReadyQueue.lock()->emplace_back(rk.Hash, std::nullopt); ReadyQueue.lock()->emplace_back(rk, std::nullopt);
} }
continue; continue;
@@ -342,7 +342,8 @@ void AssetsManager::readWriteThread(AsyncUseControl::Lock lock) {
// TODO: добавить вычистку места при нехватке // TODO: добавить вычистку места при нехватке
if(res.size() <= SMALL_RESOURCE) { if(res.size() <= SMALL_RESOURCE) {
sqlite3_bind_blob(STMT_INLINE_INSERT, 1, (const void*) res.hash().data(), 32, SQLITE_STATIC); Hash_t hash = res.hash();
sqlite3_bind_blob(STMT_INLINE_INSERT, 1, (const void*) hash.data(), 32, SQLITE_STATIC);
sqlite3_bind_int(STMT_INLINE_INSERT, 2, time(nullptr)); sqlite3_bind_int(STMT_INLINE_INSERT, 2, time(nullptr));
sqlite3_bind_blob(STMT_INLINE_INSERT, 3, res.data(), res.size(), SQLITE_STATIC); sqlite3_bind_blob(STMT_INLINE_INSERT, 3, res.data(), res.size(), SQLITE_STATIC);
if(sqlite3_step(STMT_INLINE_INSERT) != SQLITE_DONE) { if(sqlite3_step(STMT_INLINE_INSERT) != SQLITE_DONE) {
@@ -371,7 +372,8 @@ void AssetsManager::readWriteThread(AsyncUseControl::Lock lock) {
fd.close(); fd.close();
sqlite3_bind_blob(STMT_DISK_INSERT, 1, (const void*) res.hash().data(), 32, SQLITE_STATIC); Hash_t hash = res.hash();
sqlite3_bind_blob(STMT_DISK_INSERT, 1, (const void*) hash.data(), 32, SQLITE_STATIC);
sqlite3_bind_int(STMT_DISK_INSERT, 2, time(nullptr)); sqlite3_bind_int(STMT_DISK_INSERT, 2, time(nullptr));
sqlite3_bind_int(STMT_DISK_INSERT, 3, res.size()); sqlite3_bind_int(STMT_DISK_INSERT, 3, res.size());
if(sqlite3_step(STMT_DISK_INSERT) != SQLITE_DONE) { if(sqlite3_step(STMT_DISK_INSERT) != SQLITE_DONE) {

View File

@@ -268,10 +268,10 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
AsyncContext.LoadedResources.emplace_back(std::move(entry)); AsyncContext.LoadedResources.emplace_back(std::move(entry));
// // Проверяем используется ли сейчас ресурс // // Проверяем используется ли сейчас ресурс
// auto iter = Assets.ExistBinds[(int) entry.Type].find(entry.Id); // auto iter = MyAssets.ExistBinds[(int) entry.Type].find(entry.Id);
// if(iter == Assets.ExistBinds[(int) entry.Type].end()) { // if(iter == MyAssets.ExistBinds[(int) entry.Type].end()) {
// // Не используется // // Не используется
// Assets.NotInUse[(int) entry.Type][entry.Domain + ':' + entry.Key] = {entry, TIME_BEFORE_UNLOAD_RESOURCE+time(nullptr)}; // MyAssets.NotInUse[(int) entry.Type][entry.Domain + ':' + entry.Key] = {entry, TIME_BEFORE_UNLOAD_RESOURCE+time(nullptr)};
// } else { // } else {
// // Используется // // Используется
// Assets.InUse[(int) entry.Type][entry.Id] = entry; // Assets.InUse[(int) entry.Type][entry.Id] = entry;
@@ -290,10 +290,10 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
for(auto& [key, res] : resources) { for(auto& [key, res] : resources) {
if(!res) { if(!res) {
// Проверить не был ли уже отправлен запрос на получение этого хеша // Проверить не был ли уже отправлен запрос на получение этого хеша
auto iter = std::lower_bound(AsyncContext.AlreadyLoading.begin(), AsyncContext.AlreadyLoading.end(), res->hash()); auto iter = std::lower_bound(AsyncContext.AlreadyLoading.begin(), AsyncContext.AlreadyLoading.end(), key.Hash);
if(iter == AsyncContext.AlreadyLoading.end()) { if(iter == AsyncContext.AlreadyLoading.end() || *iter != key.Hash) {
AsyncContext.AlreadyLoading.insert(iter, res->hash()); AsyncContext.AlreadyLoading.insert(iter, key.Hash);
needRequest.push_back(res->hash()); needRequest.push_back(key.Hash);
} }
} else { } else {
AssetEntry entry { AssetEntry entry {
@@ -339,7 +339,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
const AssetBindEntry& abe = abc.Binds[iter]; const AssetBindEntry& abe = abc.Binds[iter];
auto& lost = entry.Lost[(int) abe.Type]; auto& lost = entry.Lost[(int) abe.Type];
auto iterator = std::lower_bound(lost.begin(), lost.end(), abe.Id); auto iterator = std::lower_bound(lost.begin(), lost.end(), abe.Id);
if(iterator != lost.end()) { if(iterator != lost.end() && *iterator == abe.Id) {
// Привязка будет удалена // Привязка будет удалена
lost.erase(iterator); lost.erase(iterator);
abc.Binds.erase(abc.Binds.begin()+iter); abc.Binds.erase(abc.Binds.begin()+iter);
@@ -354,7 +354,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
for(AssetBindEntry& abe : entry.Binds) { for(AssetBindEntry& abe : entry.Binds) {
auto iterator = std::lower_bound(entry.Lost[(int) abe.Type].begin(), entry.Lost[(int) abe.Type].end(), abe.Id); auto iterator = std::lower_bound(entry.Lost[(int) abe.Type].begin(), entry.Lost[(int) abe.Type].end(), abe.Id);
if(iterator != entry.Lost[(int) abe.Type].end()) { if(iterator != entry.Lost[(int) abe.Type].end() && *iterator == abe.Id) {
// Получили новую привязку, которая была удалена в предыдущем такте // Получили новую привязку, которая была удалена в предыдущем такте
entry.Lost[(int) abe.Type].erase(iterator); entry.Lost[(int) abe.Type].erase(iterator);
} else { } else {
@@ -382,26 +382,26 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
// Запрос к дисковому кешу новых ресурсов // Запрос к дисковому кешу новых ресурсов
std::vector<AssetsManager::ResourceKey> needToLoad; std::vector<AssetsManager::ResourceKey> needToLoad;
for(const AssetBindEntry& bind : abc.Binds) { for(const AssetBindEntry& bind : abc.Binds) {
bool needQuery = false; bool needQuery = true;
// Проверить in memory кеш по домену+ключу // Проверить in memory кеш по домену+ключу
{ {
std::string dk = bind.Domain + ':' + bind.Key; std::string dk = bind.Domain + ':' + bind.Key;
auto &niubdk = Assets.NotInUse[(int) bind.Type]; auto &niubdk = MyAssets.NotInUse[(int) bind.Type];
auto iter = niubdk.find(dk); auto iter = niubdk.find(dk);
if(iter != niubdk.end()) { if(iter != niubdk.end()) {
// Есть ресурс // Есть ресурс
needQuery = true; needQuery = false;
} }
} }
// Проверить если такой запрос уже был отправлен в AssetsManager и ожидает ответа // Проверить если такой запрос уже был отправлен в AssetsManager и ожидает ответа
if(!needQuery) { if(needQuery) {
auto& list = AsyncContext.ResourceWait[(int) bind.Type]; auto& list = AsyncContext.ResourceWait[(int) bind.Type];
auto iterDomain = list.find(bind.Domain); auto iterDomain = list.find(bind.Domain);
if(iterDomain != list.end()) { if(iterDomain != list.end()) {
for(const auto& [key, hash] : iterDomain->second) { for(const auto& [key, hash] : iterDomain->second) {
if(key == bind.Key && hash == bind.Hash) { if(key == bind.Key && hash == bind.Hash) {
needQuery = true; needQuery = false;
break; break;
} }
} }
@@ -452,7 +452,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
{ {
for(auto& [id, profile] : data.Profile_Voxel_AddOrChange) { for(auto& [id, profile] : data.Profile_Voxel_AddOrChange) {
auto iter = std::lower_bound(profile_Voxel_Lost.begin(), profile_Voxel_Lost.end(), id); auto iter = std::lower_bound(profile_Voxel_Lost.begin(), profile_Voxel_Lost.end(), id);
if(iter != profile_Voxel_Lost.end()) if(iter != profile_Voxel_Lost.end() && *iter == id)
profile_Voxel_Lost.erase(iter); profile_Voxel_Lost.erase(iter);
profile_Voxel_AddOrChange[id] = profile; profile_Voxel_AddOrChange[id] = profile;
@@ -471,7 +471,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
{ {
for(auto& [id, profile] : data.Profile_Node_AddOrChange) { for(auto& [id, profile] : data.Profile_Node_AddOrChange) {
auto iter = std::lower_bound(profile_Node_Lost.begin(), profile_Node_Lost.end(), id); auto iter = std::lower_bound(profile_Node_Lost.begin(), profile_Node_Lost.end(), id);
if(iter != profile_Node_Lost.end()) if(iter != profile_Node_Lost.end() && *iter == id)
profile_Node_Lost.erase(iter); profile_Node_Lost.erase(iter);
profile_Node_AddOrChange[id] = profile; profile_Node_AddOrChange[id] = profile;
@@ -490,7 +490,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
{ {
for(auto& [id, profile] : data.Profile_World_AddOrChange) { for(auto& [id, profile] : data.Profile_World_AddOrChange) {
auto iter = std::lower_bound(profile_World_Lost.begin(), profile_World_Lost.end(), id); auto iter = std::lower_bound(profile_World_Lost.begin(), profile_World_Lost.end(), id);
if(iter != profile_World_Lost.end()) if(iter != profile_World_Lost.end() && *iter == id)
profile_World_Lost.erase(iter); profile_World_Lost.erase(iter);
profile_World_AddOrChange[id] = profile; profile_World_AddOrChange[id] = profile;
@@ -509,7 +509,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
{ {
for(auto& [id, profile] : data.Profile_Portal_AddOrChange) { for(auto& [id, profile] : data.Profile_Portal_AddOrChange) {
auto iter = std::lower_bound(profile_Portal_Lost.begin(), profile_Portal_Lost.end(), id); auto iter = std::lower_bound(profile_Portal_Lost.begin(), profile_Portal_Lost.end(), id);
if(iter != profile_Portal_Lost.end()) if(iter != profile_Portal_Lost.end() && *iter == id)
profile_Portal_Lost.erase(iter); profile_Portal_Lost.erase(iter);
profile_Portal_AddOrChange[id] = profile; profile_Portal_AddOrChange[id] = profile;
@@ -528,7 +528,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
{ {
for(auto& [id, profile] : data.Profile_Entity_AddOrChange) { for(auto& [id, profile] : data.Profile_Entity_AddOrChange) {
auto iter = std::lower_bound(profile_Entity_Lost.begin(), profile_Entity_Lost.end(), id); auto iter = std::lower_bound(profile_Entity_Lost.begin(), profile_Entity_Lost.end(), id);
if(iter != profile_Entity_Lost.end()) if(iter != profile_Entity_Lost.end() && *iter == id)
profile_Entity_Lost.erase(iter); profile_Entity_Lost.erase(iter);
profile_Entity_AddOrChange[id] = profile; profile_Entity_AddOrChange[id] = profile;
@@ -547,7 +547,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
{ {
for(auto& [id, profile] : data.Profile_Item_AddOrChange) { for(auto& [id, profile] : data.Profile_Item_AddOrChange) {
auto iter = std::lower_bound(profile_Item_Lost.begin(), profile_Item_Lost.end(), id); auto iter = std::lower_bound(profile_Item_Lost.begin(), profile_Item_Lost.end(), id);
if(iter != profile_Item_Lost.end()) if(iter != profile_Item_Lost.end() && *iter == id)
profile_Item_Lost.erase(iter); profile_Item_Lost.erase(iter);
profile_Item_AddOrChange[id] = profile; profile_Item_AddOrChange[id] = profile;
@@ -713,7 +713,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
const AssetBindEntry& abe = abc.Binds[iter]; const AssetBindEntry& abe = abc.Binds[iter];
auto& lost = entry.Lost[(int) abe.Type]; auto& lost = entry.Lost[(int) abe.Type];
auto iterator = std::lower_bound(lost.begin(), lost.end(), abe.Id); auto iterator = std::lower_bound(lost.begin(), lost.end(), abe.Id);
if(iterator != lost.end()) { if(iterator != lost.end() && *iterator == abe.Id) {
lost.erase(iterator); lost.erase(iterator);
abc.Binds.erase(abc.Binds.begin()+iter); abc.Binds.erase(abc.Binds.begin()+iter);
} }
@@ -727,7 +727,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
for(AssetBindEntry& abe : entry.Binds) { for(AssetBindEntry& abe : entry.Binds) {
auto iterator = std::lower_bound(entry.Lost[(int) abe.Type].begin(), entry.Lost[(int) abe.Type].end(), abe.Id); auto iterator = std::lower_bound(entry.Lost[(int) abe.Type].begin(), entry.Lost[(int) abe.Type].end(), abe.Id);
if(iterator != entry.Lost[(int) abe.Type].end()) { if(iterator != entry.Lost[(int) abe.Type].end() && *iterator == abe.Id) {
// Получили новую привязку, которая была удалена в предыдущем такте // Получили новую привязку, которая была удалена в предыдущем такте
entry.Lost[(int) abe.Type].erase(iterator); entry.Lost[(int) abe.Type].erase(iterator);
} else { } else {
@@ -754,25 +754,25 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
AsyncContext.Binds.clear(); AsyncContext.Binds.clear();
for(AssetBindEntry& entry : abc.Binds) { for(AssetBindEntry& entry : abc.Binds) {
Assets.ExistBinds[(int) entry.Type].insert(entry.Id); MyAssets.ExistBinds[(int) entry.Type].insert(entry.Id);
result.Assets_ChangeOrAdd[entry.Type].push_back(entry.Id); result.Assets_ChangeOrAdd[entry.Type].push_back(entry.Id);
// Если ресурс был в кеше, то достаётся от туда // Если ресурс был в кеше, то достаётся от туда
auto iter = Assets.NotInUse[(int) entry.Type].find(entry.Domain+':'+entry.Key); auto iter = MyAssets.NotInUse[(int) entry.Type].find(entry.Domain+':'+entry.Key);
if(iter != Assets.NotInUse[(int) entry.Type].end()) { if(iter != MyAssets.NotInUse[(int) entry.Type].end()) {
IServerSession::Assets[entry.Type][entry.Id] = std::get<0>(iter->second); IServerSession::Assets[entry.Type][entry.Id] = std::get<0>(iter->second);
Assets.NotInUse[(int) entry.Type].erase(iter); MyAssets.NotInUse[(int) entry.Type].erase(iter);
} }
} }
for(int type = 0; type < (int) EnumAssets::MAX_ENUM; type++) { for(int type = 0; type < (int) EnumAssets::MAX_ENUM; type++) {
for(ResourceId id : abc.Lost[type]) { for(ResourceId id : abc.Lost[type]) {
Assets.ExistBinds[type].erase(id); MyAssets.ExistBinds[type].erase(id);
// Потерянные ресурсы уходят в кеш // Потерянные ресурсы уходят в кеш
auto iter = IServerSession::Assets[(EnumAssets) type].find(id); auto iter = IServerSession::Assets[(EnumAssets) type].find(id);
if(iter != IServerSession::Assets[(EnumAssets) type].end()) { if(iter != IServerSession::Assets[(EnumAssets) type].end()) {
Assets.NotInUse[(int) iter->second.Type][iter->second.Domain+':'+iter->second.Key] = {iter->second, TIME_BEFORE_UNLOAD_RESOURCE+time(nullptr)}; MyAssets.NotInUse[(int) iter->second.Type][iter->second.Domain+':'+iter->second.Key] = {iter->second, TIME_BEFORE_UNLOAD_RESOURCE+time(nullptr)};
IServerSession::Assets[(EnumAssets) type].erase(iter); IServerSession::Assets[(EnumAssets) type].erase(iter);
} }
} }
@@ -784,12 +784,12 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
// Получаем ресурсы // Получаем ресурсы
{ {
for(AssetEntry& entry : AsyncContext.LoadedResources) { for(AssetEntry& entry : AsyncContext.LoadedResources) {
if(Assets.ExistBinds[(int) entry.Type].contains(entry.Id)) { if(MyAssets.ExistBinds[(int) entry.Type].contains(entry.Id)) {
// Ресурс ещё нужен // Ресурс ещё нужен
IServerSession::Assets[entry.Type][entry.Id] = entry; IServerSession::Assets[entry.Type][entry.Id] = entry;
} else { } else {
// Ресурс уже не нужен, отправляем в кеш // Ресурс уже не нужен, отправляем в кеш
Assets.NotInUse[(int) entry.Type][entry.Domain+':'+entry.Key] = {entry, TIME_BEFORE_UNLOAD_RESOURCE+time(nullptr)}; MyAssets.NotInUse[(int) entry.Type][entry.Domain+':'+entry.Key] = {entry, TIME_BEFORE_UNLOAD_RESOURCE+time(nullptr)};
} }
} }
@@ -801,13 +801,13 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
uint64_t now = time(nullptr); uint64_t now = time(nullptr);
for(int type = 0; type < (int) EnumAssets::MAX_ENUM; type++) { for(int type = 0; type < (int) EnumAssets::MAX_ENUM; type++) {
std::vector<std::string> toDelete; std::vector<std::string> toDelete;
for(auto& [key, value] : Assets.NotInUse[type]) { for(auto& [key, value] : MyAssets.NotInUse[type]) {
if(std::get<1>(value) < now) if(std::get<1>(value) < now)
toDelete.push_back(key); toDelete.push_back(key);
} }
for(std::string& key : toDelete) for(std::string& key : toDelete)
Assets.NotInUse[type].erase(Assets.NotInUse[type].find(key)); MyAssets.NotInUse[type].erase(MyAssets.NotInUse[type].find(key));
} }
} }
@@ -1017,6 +1017,10 @@ coro<> ServerSession::rP_Resource(Net::AsyncSocket &sock) {
for(size_t iter = 0; iter < count; iter++) { for(size_t iter = 0; iter < count; iter++) {
uint8_t type = co_await sock.read<uint8_t>(); uint8_t type = co_await sock.read<uint8_t>();
if(type >= (int) EnumAssets::MAX_ENUM)
protocolError();
uint32_t id = co_await sock.read<uint32_t>(); uint32_t id = co_await sock.read<uint32_t>();
std::string domain, key; std::string domain, key;
domain = co_await sock.read<std::string>(); domain = co_await sock.read<std::string>();
@@ -1031,6 +1035,7 @@ coro<> ServerSession::rP_Resource(Net::AsyncSocket &sock) {
} }
AsyncContext.AssetsBinds.lock()->push_back(AssetsBindsChange(binds, {})); AsyncContext.AssetsBinds.lock()->push_back(AssetsBindsChange(binds, {}));
co_return;
} }
case ToClient::L2Resource::Lost: case ToClient::L2Resource::Lost:
{ {
@@ -1041,10 +1046,14 @@ coro<> ServerSession::rP_Resource(Net::AsyncSocket &sock) {
uint8_t type = co_await sock.read<uint8_t>(); uint8_t type = co_await sock.read<uint8_t>();
uint32_t id = co_await sock.read<uint32_t>(); uint32_t id = co_await sock.read<uint32_t>();
if(type >= (int) EnumAssets::MAX_ENUM)
protocolError();
abc.Lost[(int) type].push_back(id); abc.Lost[(int) type].push_back(id);
} }
AsyncContext.AssetsBinds.lock()->emplace_back(std::move(abc)); AsyncContext.AssetsBinds.lock()->emplace_back(std::move(abc));
co_return;
} }
case ToClient::L2Resource::InitResSend: case ToClient::L2Resource::InitResSend:
{ {
@@ -1053,6 +1062,10 @@ coro<> ServerSession::rP_Resource(Net::AsyncSocket &sock) {
co_await sock.read((std::byte*) hash.data(), hash.size()); co_await sock.read((std::byte*) hash.data(), hash.size());
ResourceId id = co_await sock.read<uint32_t>(); ResourceId id = co_await sock.read<uint32_t>();
EnumAssets type = (EnumAssets) co_await sock.read<uint8_t>(); EnumAssets type = (EnumAssets) co_await sock.read<uint8_t>();
if(type >= EnumAssets::MAX_ENUM)
protocolError();
std::string domain = co_await sock.read<std::string>(); std::string domain = co_await sock.read<std::string>();
std::string key = co_await sock.read<std::string>(); std::string key = co_await sock.read<std::string>();

View File

@@ -70,11 +70,9 @@ private:
struct { struct {
// Существующие привязки ресурсов // Существующие привязки ресурсов
std::unordered_set<ResourceId> ExistBinds[(int) EnumAssets::MAX_ENUM]; std::unordered_set<ResourceId> ExistBinds[(int) EnumAssets::MAX_ENUM];
// Используемые в данных момент ресурсы (определяется по действующей привязке)
std::unordered_map<ResourceId, AssetEntry> InUse[(int) EnumAssets::MAX_ENUM];
// Недавно использованные ресурсы, пока хранятся здесь в течении TIME_BEFORE_UNLOAD_RESOURCE секунд // Недавно использованные ресурсы, пока хранятся здесь в течении TIME_BEFORE_UNLOAD_RESOURCE секунд
std::unordered_map<std::string, std::pair<AssetEntry, uint64_t>> NotInUse[(int) EnumAssets::MAX_ENUM]; std::unordered_map<std::string, std::pair<AssetEntry, uint64_t>> NotInUse[(int) EnumAssets::MAX_ENUM];
} Assets; } MyAssets;
struct AssetLoading { struct AssetLoading {
EnumAssets Type; EnumAssets Type;

View File

@@ -169,7 +169,7 @@ public:
assert(vkInst); assert(vkInst);
assert(serverSession); assert(serverSession);
CMG.changeThreadsCount(2); CMG.changeThreadsCount(1);
const VkCommandPoolCreateInfo infoCmdPool = const VkCommandPoolCreateInfo infoCmdPool =
{ {

View File

@@ -2024,9 +2024,9 @@ Resource::Resource(const std::u8string& data)
: In(std::make_shared<std::variant<InlineMMap, InlinePtr>>(InlinePtr((const uint8_t*) data.data(), data.size()))) : In(std::make_shared<std::variant<InlineMMap, InlinePtr>>(InlinePtr((const uint8_t*) data.data(), data.size())))
{} {}
Resource::Resource(std::u8string&& data) { Resource::Resource(std::u8string&& data)
: In(std::make_shared<std::variant<InlineMMap, InlinePtr>>(InlinePtr(std::move(data))))
} {}
const std::byte* Resource::data() const { assert(In); return std::visit<const std::byte*>([](auto& obj){ return obj.data(); }, *In); } const std::byte* Resource::data() const { assert(In); return std::visit<const std::byte*>([](auto& obj){ return obj.data(); }, *In); }
size_t Resource::size() const { assert(In); return std::visit<size_t>([](auto& obj){ return obj.size(); }, *In); } size_t Resource::size() const { assert(In); return std::visit<size_t>([](auto& obj){ return obj.size(); }, *In); }

View File

@@ -498,6 +498,8 @@ AssetsManager::Out_applyResourceChange AssetsManager::applyResourceChange(const
keyToIdDomain[key] = id; keyToIdDomain[key] = id;
data->emplace(lwt, resource, domain, key); data->emplace(lwt, resource, domain, key);
lock->HashToId[resource.hash()] = {(EnumAssets) type, id};
} }
} }
@@ -511,6 +513,39 @@ AssetsManager::Out_applyResourceChange AssetsManager::applyResourceChange(const
std::set_difference(l.begin(), l.end(), noc.begin(), noc.end(), std::back_inserter(result.Lost[type])); std::set_difference(l.begin(), l.end(), noc.begin(), noc.end(), std::back_inserter(result.Lost[type]));
} }
// Дамп ключей assets
{
std::stringstream result;
auto lock = LocalObj.lock();
for(int type = 0; type < (int) EnumAssets::MAX_ENUM; type++) {
if(type == 0)
result << "Nodestate:\n";
else if(type == 1)
result << "Particle:\n";
else if(type == 2)
result << "Animation:\n";
else if(type == 3)
result << "Model:\n";
else if(type == 4)
result << "Texture:\n";
else if(type == 5)
result << "Sound:\n";
else if(type == 6)
result << "Font:\n";
for(const auto& [domain, list] : lock->KeyToId[type]) {
result << "\t" << domain << ":\n";
for(const auto& [key, id] : list) {
result << "\t\t" << key << " = " << id << '\n';
}
}
}
LOG.debug() << "Дамп ассетов:\n" << result.str();
}
if(!orr.Nodestates.empty()) if(!orr.Nodestates.empty())
{ {
auto lock = LocalObj.lock(); auto lock = LocalObj.lock();
@@ -617,6 +652,7 @@ AssetsManager::Out_applyResourceChange AssetsManager::applyResourceChange(const
} }
} }
entry.FullSubTextureDeps.append_range(entry.TextureDeps);
{ {
std::sort(entry.FullSubTextureDeps.begin(), entry.FullSubTextureDeps.end()); std::sort(entry.FullSubTextureDeps.begin(), entry.FullSubTextureDeps.end());
auto eraseIter = std::unique(entry.FullSubTextureDeps.begin(), entry.FullSubTextureDeps.end()); auto eraseIter = std::unique(entry.FullSubTextureDeps.begin(), entry.FullSubTextureDeps.end());

View File

@@ -105,6 +105,7 @@ private:
// Связь домены -> {ключ -> идентификатор} // Связь домены -> {ключ -> идентификатор}
std::unordered_map<std::string, std::unordered_map<std::string, ResourceId>> KeyToId[(int) EnumAssets::MAX_ENUM]; std::unordered_map<std::string, std::unordered_map<std::string, ResourceId>> KeyToId[(int) EnumAssets::MAX_ENUM];
std::unordered_map<Hash_t, std::tuple<EnumAssets, ResourceId>> HashToId;
std::tuple<ResourceId, std::optional<DataEntry>&> nextId(EnumAssets type); std::tuple<ResourceId, std::optional<DataEntry>&> nextId(EnumAssets type);
@@ -132,6 +133,28 @@ private:
return std::nullopt; return std::nullopt;
} }
std::optional<std::tuple<Resource, const std::string&, const std::string&, EnumAssets, ResourceId>> getResource(const Hash_t& hash) {
auto iter = HashToId.find(hash);
if(iter == HashToId.end())
return std::nullopt;
auto [type, id] = iter->second;
std::optional<std::tuple<Resource, const std::string&, const std::string&>> res = getResource(type, id);
if(!res) {
HashToId.erase(iter);
return std::nullopt;
}
if(std::get<Resource>(*res).hash() == hash) {
auto& [resource, domain, key] = *res;
return std::tuple<Resource, const std::string&, const std::string&, EnumAssets, ResourceId>{resource, domain, key, type, id};
}
HashToId.erase(iter);
return std::nullopt;
}
const std::optional<std::vector<AssetsModel>>& getResourceNodestate(ResourceId id) { const std::optional<std::vector<AssetsModel>>& getResourceNodestate(ResourceId id) {
assert(id < Table_NodeState.size()*TableEntry<DataEntry>::ChunkSize); assert(id < Table_NodeState.size()*TableEntry<DataEntry>::ChunkSize);
return Table_NodeState[id / TableEntry<DataEntry>::ChunkSize] return Table_NodeState[id / TableEntry<DataEntry>::ChunkSize]
@@ -224,6 +247,11 @@ public:
return LocalObj.lock()->getResource(type, id); return LocalObj.lock()->getResource(type, id);
} }
// Выдаёт ресурс по хешу
std::optional<std::tuple<Resource, const std::string&, const std::string&, EnumAssets, ResourceId>> getResource(const Hash_t& hash) {
return LocalObj.lock()->getResource(hash);
}
// Выдаёт зависимости к ресурсам профиля ноды // Выдаёт зависимости к ресурсам профиля ноды
std::tuple<AssetsNodestate, std::vector<AssetsModel>, std::vector<AssetsTexture>> std::tuple<AssetsNodestate, std::vector<AssetsModel>, std::vector<AssetsTexture>>
getNodeDependency(const std::string& domain, const std::string& key) getNodeDependency(const std::string& domain, const std::string& key)

View File

@@ -806,14 +806,15 @@ void GameServer::BackingNoiseGenerator_t::run(int id) {
std::array<float, 64*64*64> data; std::array<float, 64*64*64> data;
float *ptr = &data[0]; float *ptr = &data[0];
std::fill(ptr, ptr+64*64*64, 0);
for(int z = 0; z < 64; z++) // for(int z = 0; z < 64; z++)
for(int y = 0; y < 64; y++) // for(int y = 0; y < 64; y++)
for(int x = 0; x < 64; x++, ptr++) { // for(int x = 0; x < 64; x++, ptr++) {
// *ptr = TOS::genRand(); // // *ptr = TOS::genRand();
*ptr = glm::perlin(glm::vec3(posNode.x+x, posNode.y+y, posNode.z+z) / 16.13f); // *ptr = glm::perlin(glm::vec3(posNode.x+x, posNode.y+y, posNode.z+z) / 16.13f);
//*ptr = std::pow(*ptr, 0.75f)*1.5f; // //*ptr = std::pow(*ptr, 0.75f)*1.5f;
} // }
Output.lock()->push_back({key, std::move(data)}); Output.lock()->push_back({key, std::move(data)});
} }
@@ -1493,7 +1494,7 @@ void GameServer::init(fs::path worldPath) {
BackingNoiseGenerator.Threads[iter] = std::thread(&BackingNoiseGenerator_t::run, &BackingNoiseGenerator, iter); BackingNoiseGenerator.Threads[iter] = std::thread(&BackingNoiseGenerator_t::run, &BackingNoiseGenerator, iter);
} }
BackingAsyncLua.Threads.resize(4); BackingAsyncLua.Threads.resize(1);
for(size_t iter = 0; iter < BackingAsyncLua.Threads.size(); iter++) { for(size_t iter = 0; iter < BackingAsyncLua.Threads.size(); iter++) {
BackingAsyncLua.Threads[iter] = std::thread(&BackingAsyncLua_t::run, &BackingAsyncLua, iter); BackingAsyncLua.Threads[iter] = std::thread(&BackingAsyncLua_t::run, &BackingAsyncLua, iter);
} }
@@ -1837,12 +1838,8 @@ void GameServer::stepGeneratorAndLuaAsync(IWorldSaveBackend::TickSyncInfo_Out db
// Обработка шума на стороне луа // Обработка шума на стороне луа
{ {
std::vector<std::pair<BackingNoiseGenerator_t::NoiseKey, std::array<float, 64*64*64>>> calculatedNoise = BackingNoiseGenerator.tickSync(std::move(db.NotExisten)); std::vector<std::pair<BackingNoiseGenerator_t::NoiseKey, std::array<float, 64*64*64>>> calculatedNoise = BackingNoiseGenerator.tickSync(std::move(db.NotExisten));
if(!calculatedNoise.empty()) { if(!calculatedNoise.empty())
auto lock = BackingAsyncLua.NoiseIn.lock(); BackingAsyncLua.NoiseIn.lock()->push_range(calculatedNoise);
for(auto& pair : calculatedNoise)
lock->push(pair);
}
calculatedNoise.clear(); calculatedNoise.clear();
@@ -2408,7 +2405,15 @@ void GameServer::stepSyncContent() {
auto& [resource, domain, key] = *result; auto& [resource, domain, key] = *result;
resources.emplace_back((EnumAssets) type, resId, domain, key, resource); resources.emplace_back((EnumAssets) type, resId, domain, key, resource);
} }
}
for(const Hash_t& hash : full.Hashes) {
std::optional<std::tuple<Resource, const std::string&, const std::string&, EnumAssets, ResourceId>> result = Content.AM.getResource(hash);
if(!result)
continue;
auto& [resource, domain, key, type, id] = *result;
resources.emplace_back(type, id, domain, key, resource);
} }
// Информируем о запрошенных профилях // Информируем о запрошенных профилях

View File

@@ -192,7 +192,7 @@ class GameServer : public AsyncObject {
thread.join(); thread.join();
} }
__attribute__((optimize("O3"))) void run(int id); /* __attribute__((optimize("O3"))) */ void run(int id);
} BackingChunkPressure; } BackingChunkPressure;
/* /*

View File

@@ -523,10 +523,12 @@ void RemoteClient::informateAssets(const std::vector<std::tuple<EnumAssets, Reso
auto it = std::lower_bound(AssetsInWork.OnClient.begin(), AssetsInWork.OnClient.end(), hash); auto it = std::lower_bound(AssetsInWork.OnClient.begin(), AssetsInWork.OnClient.end(), hash);
if(it == AssetsInWork.OnClient.end() || *it != hash) if(it == AssetsInWork.OnClient.end() || *it != hash) {
AssetsInWork.OnClient.insert(it, hash); AssetsInWork.OnClient.insert(it, hash);
AssetsInWork.ToSend.emplace_back(type, domain, key, resId, resource, 0);
AssetsInWork.ToSend.emplace_back(type, domain, key, resId, resource, 0); } else {
LOG.warn() << "Клиент повторно запросил имеющийся у него ресурс";
}
lock = NetworkAndResource.lock(); lock = NetworkAndResource.lock();
} }
@@ -552,13 +554,13 @@ void RemoteClient::informateAssets(const std::vector<std::tuple<EnumAssets, Reso
assert(newForClient.size() < 65535*4); assert(newForClient.size() < 65535*4);
auto lock = NetworkAndResource.lock(); auto lock = NetworkAndResource.lock();
lock->checkPacketBorder(2+4+newForClient.size()*(1+4+32)); lock->checkPacketBorder(2+1+4+newForClient.size()*(1+4+64+32));
lock->NextPacket << (uint8_t) ToClient::L1::Resource // Оповещение lock->NextPacket << (uint8_t) ToClient::L1::Resource // Оповещение
<< ((uint8_t) ToClient::L2Resource::Bind) << uint32_t(newForClient.size()); << ((uint8_t) ToClient::L2Resource::Bind) << uint32_t(newForClient.size());
for(auto& [type, resId, domain, key, hash, size] : newForClient) { for(auto& [type, resId, domain, key, hash, size] : newForClient) {
// TODO: может внести ограничение на длину домена и ключа? // TODO: может внести ограничение на длину домена и ключа?
lock->NextPacket << uint8_t(type) << uint32_t(resId) << domain << key << size; lock->NextPacket << uint8_t(type) << uint32_t(resId) << domain << key;
lock->NextPacket.write((const std::byte*) hash.data(), hash.size()); lock->NextPacket.write((const std::byte*) hash.data(), hash.size());
} }
} }