Add utility api for Tags usage
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Engine/Core/Math/Vector3.h"
|
||||
#include "Engine/Core/Types/String.h"
|
||||
#include "Engine/Core/Types/StringView.h"
|
||||
#include "Engine/Level/LargeWorlds.h"
|
||||
#include "Engine/Level/Tags.h"
|
||||
#include <ThirdParty/catch2/catch.hpp>
|
||||
|
||||
TEST_CASE("LargeWorlds")
|
||||
@@ -16,3 +19,52 @@ TEST_CASE("LargeWorlds")
|
||||
CHECK(origin == Vector3(0, 0, LargeWorlds::ChunkSize * 1));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Tags")
|
||||
{
|
||||
SECTION("Tag")
|
||||
{
|
||||
auto prevTags = Tags::List;
|
||||
|
||||
Tags::List = Array<String>({ TEXT("A"), TEXT("A.1"), TEXT("B"), TEXT("B.1"), });
|
||||
|
||||
auto a = Tags::Get(TEXT("A"));
|
||||
auto a1 = Tags::Get(TEXT("A.1"));
|
||||
auto b = Tags::Get(TEXT("B"));
|
||||
auto b1 = Tags::Get(TEXT("B.1"));
|
||||
auto c = Tags::Get(TEXT("C"));
|
||||
CHECK(a.Index == 0);
|
||||
CHECK(a1.Index == 1);
|
||||
CHECK(b.Index == 2);
|
||||
CHECK(b1.Index == 3);
|
||||
CHECK(c.Index == 4);
|
||||
|
||||
Tags::List = prevTags;
|
||||
}
|
||||
|
||||
SECTION("Tags")
|
||||
{
|
||||
auto prevTags = Tags::List;
|
||||
|
||||
Tags::List = Array<String>({ TEXT("A"), TEXT("A.1"), TEXT("B"), TEXT("B.1"), });
|
||||
|
||||
auto a = Tags::Get(TEXT("A"));
|
||||
auto a1 = Tags::Get(TEXT("A.1"));
|
||||
auto b = Tags::Get(TEXT("B"));
|
||||
auto b1 = Tags::Get(TEXT("B.1"));
|
||||
auto c = Tags::Get(TEXT("C"));
|
||||
|
||||
Array<Tag> list = { a1, b1 };
|
||||
|
||||
CHECK(Tags::HasTag(list, Tag()) == false);
|
||||
CHECK(Tags::HasTag(list, a1) == true);
|
||||
CHECK(Tags::HasTag(list, a) == true);
|
||||
CHECK(Tags::HasTag(list, c) == false);
|
||||
|
||||
CHECK(Tags::HasTagExact(list, a1) == true);
|
||||
CHECK(Tags::HasTagExact(list, a) == false);
|
||||
CHECK(Tags::HasTagExact(list, c) == false);
|
||||
|
||||
Tags::List = prevTags;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user