Add utility api for Tags usage

This commit is contained in:
Wojtek Figat
2022-12-20 22:39:11 +01:00
parent 0dd79fe10a
commit 2f6e793df4
4 changed files with 285 additions and 0 deletions

View File

@@ -38,6 +38,71 @@ Tag Tags::Get(const StringView& tagName)
return tag;
}
bool Tags::HasTag(const Array<Tag>& list, const Tag& tag)
{
if (tag.Index == -1)
return false;
const String& tagName = tag.ToString();
for (const Tag& e : list)
{
const String& eName = e.ToString();
if (e == tag || (eName.Length() > tagName.Length() + 1 && eName.StartsWith(tagName) && eName[tagName.Length()] == '.'))
return true;
}
return false;
}
bool Tags::HasTagExact(const Array<Tag>& list, const Tag& tag)
{
if (tag.Index == -1)
return false;
return list.Contains(tag);
}
bool Tags::HasAny(const Array<Tag>& list, const Array<Tag>& tags)
{
for (const Tag& tag : tags)
{
if (HasTag(list, tag))
return true;
}
return false;
}
bool Tags::HasAnyExact(const Array<Tag>& list, const Array<Tag>& tags)
{
for (const Tag& tag : tags)
{
if (HasTagExact(list, tag))
return true;
}
return false;
}
bool Tags::HasAll(const Array<Tag>& list, const Array<Tag>& tags)
{
if (tags.IsEmpty())
return true;
for (const Tag& tag : tags)
{
if (!HasTag(list, tag))
return false;
}
return true;
}
bool Tags::HasAllExact(const Array<Tag>& list, const Array<Tag>& tags)
{
if (tags.IsEmpty())
return true;
for (const Tag& tag : tags)
{
if (!HasTagExact(list, tag))
return false;
}
return true;
}
const String& Tags::GetTagName(int32 tag)
{
return Tag(tag).ToString();

View File

@@ -113,4 +113,123 @@ namespace FlaxEngine
return Tags.Internal_GetTagName(Index);
}
}
partial class Tags
{
/// <summary>
/// Checks if the list of tags contains a given tag (including parent tags check). For example, HasTag({"A.B"}, "A") returns true, for exact check use HasTagExact.
/// </summary>
/// <param name="list">The tags list to use.</param>
/// <param name="tag">The tag to check.</param>
/// <returns>True if given tag is contained by the list of tags. Returns false for empty list.</returns>
public static bool HasTag(Tag[] list, Tag tag)
{
if (tag.Index == -1)
return false;
string tagName = tag.ToString();
foreach (Tag e in list)
{
string eName = e.ToString();
if (e == tag || (eName.Length > tagName.Length + 1 && eName.StartsWith(tagName) && eName[tagName.Length] == '.'))
return true;
}
return false;
}
/// <summary>
/// Checks if the list of tags contains a given tag (exact match). For example, HasTag({"A.B"}, "A") returns false, for parents check use HasTag.
/// </summary>
/// <param name="list">The tags list to use.</param>
/// <param name="tag">The tag to check.</param>
/// <returns>True if given tag is contained by the list of tags. Returns false for empty list.</returns>
public static bool HasTagExact(Tag[] list, Tag tag)
{
if (tag.Index == -1)
return false;
if (list == null)
return false;
foreach (Tag e in list)
{
if (e == tag)
return true;
}
return false;
}
/// <summary>
/// Checks if the list of tags contains any of the given tags (including parent tags check). For example, HasAny({"A.B", "C"}, {"A"}) returns true, for exact check use HasAnyExact.
/// </summary>
/// <param name="list">The tags list to use.</param>
/// <param name="tags">The tags to check.</param>
/// <returns>True if any of of the given tags is contained by the list of tags.</returns>
public static bool HasAny(Tag[] list, Tag[] tags)
{
if (list == null)
return false;
foreach (Tag tag in list)
{
if (HasTag(list, tag))
return true;
}
return false;
}
/// <summary>
/// Checks if the list of tags contains any of the given tags (exact match). For example, HasAnyExact({"A.B", "C"}, {"A"}) returns false, for parents check use HasAny.
/// </summary>
/// <param name="list">The tags list to use.</param>
/// <param name="tags">The tags to check.</param>
/// <returns>True if any of the given tags is contained by the list of tags.</returns>
public static bool HasAnyExact(Tag[] list, Tag[] tags)
{
if (list == null)
return false;
foreach (Tag tag in list)
{
if (HasTagExact(list, tag))
return true;
}
return false;
}
/// <summary>
/// Checks if the list of tags contains all of the given tags (including parent tags check). For example, HasAll({"A.B", "C"}, {"A", "C"}) returns true, for exact check use HasAllExact.
/// </summary>
/// <param name="list">The tags list to use.</param>
/// <param name="tags">The tags to check.</param>
/// <returns>True if all of the given tags are contained by the list of tags. Returns true for empty list.</returns>
public static bool HasAll(Tag[] list, Tag[] tags)
{
if (tags == null || tags.Length == 0)
return true;
if (list == null || list.Length == 0)
return false;
foreach (Tag tag in list)
{
if (!HasTag(list, tag))
return false;
}
return true;
}
/// <summary>
/// Checks if the list of tags contains all of the given tags (exact match). For example, HasAllExact({"A.B", "C"}, {"A", "C"}) returns false, for parents check use HasAll.
/// </summary>
/// <param name="list">The tags list to use.</param>
/// <param name="tags">The tags to check.</param>
/// <returns>True if all of the given tags are contained by the list of tags. Returns true for empty list.</returns>
public static bool HasAllExact(Tag[] list, Tag[] tags)
{
if (tags == null || tags.Length == 0)
return true;
if (list == null || list.Length == 0)
return false;
foreach (Tag tag in list)
{
if (!HasTagExact(list, tag))
return false;
}
return true;
}
}
}

View File

@@ -79,6 +79,55 @@ API_CLASS(Static) class FLAXENGINE_API Tags
/// <returns>The tag.</returns>
API_FUNCTION() static Tag Get(const StringView& tagName);
public:
/// <summary>
/// Checks if the list of tags contains a given tag (including parent tags check). For example, HasTag({"A.B"}, "A") returns true, for exact check use HasTagExact.
/// </summary>
/// <param name="list">The tags list to use.</param>
/// <param name="tag">The tag to check.</param>
/// <returns>True if given tag is contained by the list of tags. Returns false for empty list.</returns>
static bool HasTag(const Array<Tag>& list, const Tag& tag);
/// <summary>
/// Checks if the list of tags contains a given tag (exact match). For example, HasTag({"A.B"}, "A") returns false, for parents check use HasTag.
/// </summary>
/// <param name="list">The tags list to use.</param>
/// <param name="tag">The tag to check.</param>
/// <returns>True if given tag is contained by the list of tags. Returns false for empty list.</returns>
static bool HasTagExact(const Array<Tag>& list, const Tag& tag);
/// <summary>
/// Checks if the list of tags contains any of the given tags (including parent tags check). For example, HasAny({"A.B", "C"}, {"A"}) returns true, for exact check use HasAnyExact.
/// </summary>
/// <param name="list">The tags list to use.</param>
/// <param name="tags">The tags to check.</param>
/// <returns>True if any of of the given tags is contained by the list of tags.</returns>
static bool HasAny(const Array<Tag>& list, const Array<Tag>& tags);
/// <summary>
/// Checks if the list of tags contains any of the given tags (exact match). For example, HasAnyExact({"A.B", "C"}, {"A"}) returns false, for parents check use HasAny.
/// </summary>
/// <param name="list">The tags list to use.</param>
/// <param name="tags">The tags to check.</param>
/// <returns>True if any of the given tags is contained by the list of tags.</returns>
static bool HasAnyExact(const Array<Tag>& list, const Array<Tag>& tags);
/// <summary>
/// Checks if the list of tags contains all of the given tags (including parent tags check). For example, HasAll({"A.B", "C"}, {"A", "C"}) returns true, for exact check use HasAllExact.
/// </summary>
/// <param name="list">The tags list to use.</param>
/// <param name="tags">The tags to check.</param>
/// <returns>True if all of the given tags are contained by the list of tags. Returns true for empty list.</returns>
static bool HasAll(const Array<Tag>& list, const Array<Tag>& tags);
/// <summary>
/// Checks if the list of tags contains all of the given tags (exact match). For example, HasAllExact({"A.B", "C"}, {"A", "C"}) returns false, for parents check use HasAll.
/// </summary>
/// <param name="list">The tags list to use.</param>
/// <param name="tags">The tags to check.</param>
/// <returns>True if all of the given tags are contained by the list of tags. Returns true for empty list.</returns>
static bool HasAllExact(const Array<Tag>& list, const Array<Tag>& tags);
private:
API_FUNCTION(NoProxy) static const String& GetTagName(int32 tag);
};