Fix Itemtest map being extremely inefficient
This commit is contained in:
parent
f49a16d88b
commit
0378800529
@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -139,8 +139,8 @@ public:
|
||||
void RegisterItem(std::string modelpath, k_EItemType type);
|
||||
k_EItemType GetItemType(CachedEntity *entity);
|
||||
|
||||
std::map<std::string, k_EItemType> models;
|
||||
std::map<uintptr_t, k_EItemType> map;
|
||||
std::unordered_map<std::string, k_EItemType> models;
|
||||
std::unordered_map<uintptr_t, k_EItemType> map;
|
||||
};
|
||||
|
||||
class ItemManager
|
||||
@ -151,10 +151,10 @@ public:
|
||||
void RegisterSpecialMapping(ItemCheckerFn fn, k_EItemType type);
|
||||
k_EItemType GetItemType(CachedEntity *ent);
|
||||
|
||||
std::map<ItemCheckerFn, k_EItemType> special_map;
|
||||
std::unordered_map<ItemCheckerFn, k_EItemType> special_map;
|
||||
std::vector<ItemSpecialMapperFn> specials;
|
||||
ItemModelMapper mapper_special;
|
||||
ItemModelMapper mapper;
|
||||
};
|
||||
|
||||
extern ItemManager g_ItemManager;
|
||||
extern ItemManager g_ItemManager;
|
||||
|
@ -481,12 +481,87 @@ void ReplaceString(std::string &input, const std::string &what, const std::strin
|
||||
}
|
||||
}
|
||||
|
||||
void ReplaceSpecials(std::string &input)
|
||||
{
|
||||
ReplaceString(input, "\\015", "\015");
|
||||
ReplaceString(input, "\\n", "\n");
|
||||
ReplaceString(input, "\\r", "\r");
|
||||
ReplaceString(input, "\\u200F", "\u200F");
|
||||
void ReplaceSpecials(std::string &str) {
|
||||
int val, i;
|
||||
size_t c = 0, len = str.size();
|
||||
for (int i = 0; i + c < len; ++i) {
|
||||
str[i] = str[i + c];
|
||||
if (str[i] != '\\')
|
||||
continue;
|
||||
if (i + c + 1 == len)
|
||||
break;
|
||||
switch (str[i + c + 1]) {
|
||||
// Several control characters
|
||||
case 'b':
|
||||
++c;
|
||||
str[i] = '\b';
|
||||
break;
|
||||
case 'n':
|
||||
++c;
|
||||
str[i] = '\n';
|
||||
break;
|
||||
case 'v':
|
||||
++c;
|
||||
str[i] = '\v';
|
||||
break;
|
||||
case 'r':
|
||||
++c;
|
||||
str[i] = '\r';
|
||||
break;
|
||||
case 't':
|
||||
++c;
|
||||
str[i] = '\t';
|
||||
break;
|
||||
case 'f':
|
||||
++c;
|
||||
str[i] = '\f';
|
||||
break;
|
||||
case 'a':
|
||||
++c;
|
||||
str[i] = '\a';
|
||||
break;
|
||||
case 'e':
|
||||
++c;
|
||||
str[i] = '\e';
|
||||
break;
|
||||
// Write escaped escape character as is
|
||||
case '\\':
|
||||
++c;
|
||||
break;
|
||||
// Convert specified value from HEX
|
||||
case 'x':
|
||||
if (i + c + 4 > len)
|
||||
continue;
|
||||
std::sscanf(&str[i + c + 2], "%02X", &val);
|
||||
c += 3;
|
||||
str[i] = val;
|
||||
break;
|
||||
// Convert from unicode
|
||||
case 'u':
|
||||
if (i + c + 6 > len)
|
||||
continue;
|
||||
// 1. Scan 16bit HEX value
|
||||
std::sscanf(&str[i + c + 2], "%04X", &val);
|
||||
c += 5;
|
||||
// 2. Convert value to UTF-8
|
||||
if (val <= 0x7F) {
|
||||
str[i] = val;
|
||||
} else if (val <= 0x7FF) {
|
||||
str[i] = 0xC0 | ((val >> 6) & 0x1F);
|
||||
str[i + 1] = 0x80 | (val & 0x3F);
|
||||
++i;
|
||||
--c;
|
||||
} else {
|
||||
str[i] = 0xE0 | ((val >> 12) & 0xF);
|
||||
str[i + 1] = 0x80 | ((val >> 6) & 0x3F);
|
||||
str[i + 2] = 0x80 | (val & 0x3F);
|
||||
i += 2;
|
||||
c -= 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
str.resize(len - c);
|
||||
}
|
||||
|
||||
powerup_type GetPowerupOnPlayer(CachedEntity *player)
|
||||
|
@ -167,54 +167,45 @@ void ItemManager::RegisterModelMapping(std::string path, k_EItemType type)
|
||||
|
||||
void ItemManager::RegisterSpecialMapping(ItemCheckerFn fn, k_EItemType type)
|
||||
{
|
||||
special_map.emplace(fn, type);
|
||||
special_map[fn] = type;
|
||||
}
|
||||
|
||||
k_EItemType ItemManager::GetItemType(CachedEntity *ent)
|
||||
{
|
||||
for (const auto &it : specials)
|
||||
{
|
||||
const auto type = it(ent);
|
||||
if (type != ITEM_NONE)
|
||||
return type;
|
||||
}
|
||||
for (const auto &it : special_map)
|
||||
{
|
||||
if (it.first(ent))
|
||||
return it.second;
|
||||
}
|
||||
return mapper.GetItemType(ent);
|
||||
}
|
||||
|
||||
void ItemModelMapper::RegisterItem(std::string modelpath, k_EItemType type)
|
||||
{
|
||||
models.emplace(modelpath, type);
|
||||
models[modelpath] = type;
|
||||
}
|
||||
|
||||
k_EItemType ItemModelMapper::GetItemType(CachedEntity *entity)
|
||||
{
|
||||
const uintptr_t model = (uintptr_t) RAW_ENT(entity)->GetModel();
|
||||
for (const auto &it : map)
|
||||
const uintptr_t model = (uint64_t) RAW_ENT(entity)->GetModel();
|
||||
try
|
||||
{
|
||||
if (it.first == model)
|
||||
return it.second;
|
||||
return map.at(model);
|
||||
}
|
||||
// Do Nothing
|
||||
catch (std::out_of_range)
|
||||
{
|
||||
|
||||
}
|
||||
std::string path(g_IModelInfo->GetModelName((const model_t *) model));
|
||||
bool set = false;
|
||||
for (const auto &it : models)
|
||||
// Do Nothing
|
||||
try
|
||||
{
|
||||
// logging::Info("comparing [%s] to [%s]", path.c_str(),
|
||||
// it.first.c_str());
|
||||
if (it.first == path)
|
||||
{
|
||||
// logging::Info("Found %s!", path.c_str());
|
||||
map.emplace(model, it.second);
|
||||
set = true;
|
||||
break;
|
||||
}
|
||||
models.at(path);
|
||||
set = true;
|
||||
}
|
||||
catch (std::out_of_range)
|
||||
{
|
||||
|
||||
}
|
||||
if (!set)
|
||||
map.emplace(model, k_EItemType::ITEM_NONE);
|
||||
map[model] = k_EItemType::ITEM_NONE;
|
||||
return k_EItemType::ITEM_NONE;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user