mirror of https://github.com/OpenRCT2/OpenRCT2.git
Optimise object selection search
* Do case insensitive string matching for object search. * Return as soon as first field is a hit.
This commit is contained in:
parent
d556eafc73
commit
142b9ff243
|
@ -1135,7 +1135,7 @@ private:
|
|||
uint8_t selectionFlags = _objectSelectionFlags[i];
|
||||
const ObjectRepositoryItem* item = &items[i];
|
||||
if (item->Type == GetSelectedObjectType() && !(selectionFlags & ObjectSelectionFlags::Flag6) && FilterSource(item)
|
||||
&& FilterString(item) && FilterChunks(item) && FilterSelected(selectionFlags))
|
||||
&& FilterString(*item) && FilterChunks(item) && FilterSelected(selectionFlags))
|
||||
{
|
||||
auto filter = std::make_unique<rct_object_filters>();
|
||||
filter->ride.category[0] = 0;
|
||||
|
@ -1319,12 +1319,32 @@ private:
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool IsFilterInAuthor(const std::vector<std::string>& authors, const std::string& filterUpper)
|
||||
static bool IsFilterInName(const ObjectRepositoryItem& item, std::string_view filter)
|
||||
{
|
||||
for (auto& author : authors)
|
||||
return String::Contains(item.Name, filter, true);
|
||||
}
|
||||
|
||||
static bool IsFilterInRideType(const ObjectRepositoryItem& item, std::string_view filter)
|
||||
{
|
||||
bool inAuthor = String::ToUpper(author).find(filterUpper) != std::string::npos;
|
||||
if (inAuthor)
|
||||
if (item.Type == ObjectType::Ride)
|
||||
{
|
||||
auto rideTypeName = language_get_string(GetRideTypeStringId(&item));
|
||||
if (String::Contains(rideTypeName, filter, true))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsFilterInFilename(const ObjectRepositoryItem& item, std::string_view filter)
|
||||
{
|
||||
return String::Contains(item.Path, filter, true);
|
||||
}
|
||||
|
||||
static bool IsFilterInAuthor(const ObjectRepositoryItem& item, std::string_view filter)
|
||||
{
|
||||
for (auto& author : item.Authors)
|
||||
{
|
||||
if (String::Contains(author, filter, true))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -1332,32 +1352,15 @@ private:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool FilterString(const ObjectRepositoryItem* item)
|
||||
bool FilterString(const ObjectRepositoryItem& item)
|
||||
{
|
||||
// Nothing to search for
|
||||
if (_filter_string[0] == '\0')
|
||||
std::string_view filter = _filter_string;
|
||||
if (filter.empty())
|
||||
return true;
|
||||
|
||||
// Object doesn't have a name
|
||||
if (item->Name.empty())
|
||||
return false;
|
||||
|
||||
// Get ride type
|
||||
const char* rideTypeName = language_get_string(GetRideTypeStringId(item));
|
||||
|
||||
// Get object name (ride/vehicle for rides) and type name (rides only) in uppercase
|
||||
const auto nameUpper = String::ToUpper(item->Name);
|
||||
const auto typeUpper = String::ToUpper(rideTypeName);
|
||||
const auto pathUpper = String::ToUpper(item->Path);
|
||||
const auto filterUpper = String::ToUpper(_filter_string);
|
||||
|
||||
// Check if the searched string exists in the name, ride type, filename, or authors field
|
||||
bool inName = nameUpper.find(filterUpper) != std::string::npos;
|
||||
bool inRideType = (item->Type == ObjectType::Ride) && typeUpper.find(filterUpper) != std::string::npos;
|
||||
bool inPath = pathUpper.find(filterUpper) != std::string::npos;
|
||||
bool inAuthor = IsFilterInAuthor(item->Authors, filterUpper);
|
||||
|
||||
return inName || inRideType || inPath || inAuthor;
|
||||
return IsFilterInName(item, filter) || IsFilterInRideType(item, filter) || IsFilterInFilename(item, filter)
|
||||
|| IsFilterInAuthor(item, filter);
|
||||
}
|
||||
|
||||
bool SourcesMatch(ObjectSourceGame source)
|
||||
|
@ -1425,7 +1428,7 @@ private:
|
|||
for (size_t i = 0; i < numObjects; i++)
|
||||
{
|
||||
const ObjectRepositoryItem* item = &items[i];
|
||||
if (FilterSource(item) && FilterString(item) && FilterChunks(item) && FilterSelected(selectionFlags[i]))
|
||||
if (FilterSource(item) && FilterString(*item) && FilterChunks(item) && FilterSelected(selectionFlags[i]))
|
||||
{
|
||||
_filter_object_counts[EnumValue(item->Type)]++;
|
||||
}
|
||||
|
|
|
@ -242,6 +242,26 @@ namespace String
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Contains(std::string_view haystack, std::string_view needle, bool ignoreCase)
|
||||
{
|
||||
if (needle.size() > haystack.size())
|
||||
return false;
|
||||
|
||||
if (!ignoreCase)
|
||||
return haystack.find(needle) != std::string_view::npos;
|
||||
|
||||
auto end = haystack.size() - needle.size();
|
||||
for (size_t start = 0; start <= end; start++)
|
||||
{
|
||||
auto sub = haystack.substr(start, needle.size());
|
||||
if (Equals(sub, needle, ignoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t IndexOf(const utf8* str, utf8 match, size_t startIndex)
|
||||
{
|
||||
const utf8* ch = str + startIndex;
|
||||
|
|
|
@ -61,6 +61,7 @@ namespace String
|
|||
bool Equals(const utf8* a, const utf8* b, bool ignoreCase = false);
|
||||
bool StartsWith(std::string_view str, std::string_view match, bool ignoreCase = false);
|
||||
bool EndsWith(std::string_view str, std::string_view match, bool ignoreCase = false);
|
||||
bool Contains(std::string_view haystack, std::string_view needle, bool ignoreCase = false);
|
||||
size_t IndexOf(const utf8* str, utf8 match, size_t startIndex = 0);
|
||||
ptrdiff_t LastIndexOf(const utf8* str, utf8 match);
|
||||
|
||||
|
|
Loading…
Reference in New Issue