Skip to content

Commit dc6410e

Browse files
committed
Merge branch 'actor-tag-type' of https://github.com/Tryibion/FlaxEngine into Tryibion-actor-tag-type
2 parents e1572a2 + d88b93d commit dc6410e

File tree

6 files changed

+240
-137
lines changed

6 files changed

+240
-137
lines changed

Source/Engine/Level/Actor.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,20 @@ Actor* Actor::FindActor(const MClass* type, const StringView& name) const
13371337
return nullptr;
13381338
}
13391339

1340+
Actor* Actor::FindActor(const MClass* type, const Tag& tag) const
1341+
{
1342+
CHECK_RETURN(type, nullptr);
1343+
if (GetClass()->IsSubClassOf(type) && HasTag(tag))
1344+
return const_cast<Actor*>(this);
1345+
for (auto child : Children)
1346+
{
1347+
const auto actor = child->FindActor(type, tag);
1348+
if (actor)
1349+
return actor;
1350+
}
1351+
return nullptr;
1352+
}
1353+
13401354
Script* Actor::FindScript(const MClass* type) const
13411355
{
13421356
CHECK_RETURN(type, nullptr);

Source/Engine/Level/Actor.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,17 @@ public T FindActor<T>(string name) where T : Actor
269269
{
270270
return FindActor(typeof(T), name) as T;
271271
}
272+
273+
/// <summary>
274+
/// Tries to find actor of the given type and tag in this actor hierarchy (checks this actor and all children hierarchy).
275+
/// </summary>
276+
/// <param name="tag">A tag on the object.</param>
277+
/// <typeparam name="T">Type of the object.</typeparam>
278+
/// <returns>Actor instance if found, null otherwise.</returns>
279+
public T FindActor<T>(Tag tag) where T : Actor
280+
{
281+
return FindActor(typeof(T), tag) as T;
282+
}
272283

273284
/// <summary>
274285
/// Searches for all actors of a specific type in this actor children list.

Source/Engine/Level/Actor.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,14 @@ API_CLASS(Abstract) class FLAXENGINE_API Actor : public SceneObject
739739
/// <returns>Actor instance if found, null otherwise.</returns>
740740
API_FUNCTION() Actor* FindActor(API_PARAM(Attributes="TypeReference(typeof(Actor))") const MClass* type, const StringView& name) const;
741741

742+
/// <summary>
743+
/// Tries to find the actor of the given type and tag in this actor hierarchy.
744+
/// </summary>
745+
/// <param name="type">Type of the actor to search for. Includes any actors derived from the type.</param>
746+
/// <param name="tag">The tag of the actor to search for.</param>
747+
/// <returns>Actor instance if found, null otherwise.</returns>
748+
API_FUNCTION() Actor* FindActor(API_PARAM(Attributes="TypeReference(typeof(Actor))") const MClass* type, const Tag& tag) const;
749+
742750
/// <summary>
743751
/// Tries to find the actor of the given type in this actor hierarchy (checks this actor and all children hierarchy).
744752
/// </summary>
@@ -759,6 +767,17 @@ API_CLASS(Abstract) class FLAXENGINE_API Actor : public SceneObject
759767
{
760768
return (T*)FindActor(T::GetStaticClass(), name);
761769
}
770+
771+
/// <summary>
772+
/// Tries to find the actor of the given type and tag in this actor hierarchy (checks this actor and all children hierarchy).
773+
/// </summary>
774+
/// <param name="tag">The tag of the actor to search for.</param>
775+
/// <returns>Actor instance if found, null otherwise.</returns>
776+
template<typename T>
777+
FORCE_INLINE T* FindActor(const Tag& tag) const
778+
{
779+
return (T*)FindActor(T::GetStaticClass(), tag);
780+
}
762781

763782
/// <summary>
764783
/// Tries to find the script of the given type in this actor hierarchy (checks this actor and all children hierarchy).

Source/Engine/Level/Level.cpp

Lines changed: 137 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -726,116 +726,6 @@ int32 Level::GetLayerIndex(const StringView& layer)
726726
return result;
727727
}
728728

729-
Actor* FindActorRecursive(Actor* node, const Tag& tag)
730-
{
731-
if (node->HasTag(tag))
732-
return node;
733-
Actor* result = nullptr;
734-
for (Actor* child : node->Children)
735-
{
736-
result = FindActorRecursive(child, tag);
737-
if (result)
738-
break;
739-
}
740-
return result;
741-
}
742-
743-
void FindActorsRecursive(Actor* node, const Tag& tag, const bool activeOnly, Array<Actor*>& result)
744-
{
745-
if (activeOnly && !node->GetIsActive())
746-
return;
747-
if (node->HasTag(tag))
748-
result.Add(node);
749-
for (Actor* child : node->Children)
750-
FindActorsRecursive(child, tag, activeOnly, result);
751-
}
752-
753-
void FindActorsRecursiveByParentTags(Actor* node, const Array<Tag>& tags, const bool activeOnly, Array<Actor*>& result)
754-
{
755-
if (activeOnly && !node->GetIsActive())
756-
return;
757-
for (Tag tag : tags)
758-
{
759-
if (node->HasTag(tag))
760-
{
761-
result.Add(node);
762-
break;
763-
}
764-
}
765-
for (Actor* child : node->Children)
766-
FindActorsRecursiveByParentTags(child, tags, activeOnly, result);
767-
}
768-
769-
Actor* Level::FindActor(const Tag& tag, Actor* root)
770-
{
771-
PROFILE_CPU();
772-
if (root)
773-
return FindActorRecursive(root, tag);
774-
Actor* result = nullptr;
775-
for (Scene* scene : Scenes)
776-
{
777-
result = FindActorRecursive(scene, tag);
778-
if (result)
779-
break;
780-
}
781-
return result;
782-
}
783-
784-
void FindActorRecursive(Actor* node, const Tag& tag, Array<Actor*>& result)
785-
{
786-
if (node->HasTag(tag))
787-
result.Add(node);
788-
for (Actor* child : node->Children)
789-
FindActorRecursive(child, tag, result);
790-
}
791-
792-
Array<Actor*> Level::FindActors(const Tag& tag, const bool activeOnly, Actor* root)
793-
{
794-
PROFILE_CPU();
795-
Array<Actor*> result;
796-
if (root)
797-
{
798-
FindActorsRecursive(root, tag, activeOnly, result);
799-
}
800-
else
801-
{
802-
ScopeLock lock(ScenesLock);
803-
for (Scene* scene : Scenes)
804-
FindActorsRecursive(scene, tag, activeOnly, result);
805-
}
806-
return result;
807-
}
808-
809-
Array<Actor*> Level::FindActorsByParentTag(const Tag& parentTag, const bool activeOnly, Actor* root)
810-
{
811-
PROFILE_CPU();
812-
Array<Actor*> result;
813-
const Array<Tag> subTags = Tags::GetSubTags(parentTag);
814-
815-
if (subTags.Count() == 0)
816-
{
817-
return result;
818-
}
819-
if (subTags.Count() == 1)
820-
{
821-
result = FindActors(subTags[0], activeOnly, root);
822-
return result;
823-
}
824-
825-
if (root)
826-
{
827-
FindActorsRecursiveByParentTags(root, subTags, activeOnly, result);
828-
}
829-
else
830-
{
831-
ScopeLock lock(ScenesLock);
832-
for (Scene* scene : Scenes)
833-
FindActorsRecursiveByParentTags(scene, subTags, activeOnly, result);
834-
}
835-
836-
return result;
837-
}
838-
839729
void Level::callActorEvent(ActorEventType eventType, Actor* a, Actor* b)
840730
{
841731
PROFILE_CPU();
@@ -1505,6 +1395,143 @@ Actor* Level::FindActor(const MClass* type, const StringView& name)
15051395
return result;
15061396
}
15071397

1398+
Actor* FindActorRecursive(Actor* node, const Tag& tag)
1399+
{
1400+
if (node->HasTag(tag))
1401+
return node;
1402+
Actor* result = nullptr;
1403+
for (Actor* child : node->Children)
1404+
{
1405+
result = FindActorRecursive(child, tag);
1406+
if (result)
1407+
break;
1408+
}
1409+
return result;
1410+
}
1411+
1412+
Actor* FindActorRecursiveByType(Actor* node, const MClass* type, const Tag& tag)
1413+
{
1414+
CHECK_RETURN(type, nullptr);
1415+
if (node->HasTag(tag) && node->GetClass()->IsSubClassOf(type))
1416+
return node;
1417+
Actor* result = nullptr;
1418+
for (Actor* child : node->Children)
1419+
{
1420+
result = FindActorRecursiveByType(child, type, tag);
1421+
if (result)
1422+
break;
1423+
}
1424+
return result;
1425+
}
1426+
1427+
void FindActorsRecursive(Actor* node, const Tag& tag, const bool activeOnly, Array<Actor*>& result)
1428+
{
1429+
if (activeOnly && !node->GetIsActive())
1430+
return;
1431+
if (node->HasTag(tag))
1432+
result.Add(node);
1433+
for (Actor* child : node->Children)
1434+
FindActorsRecursive(child, tag, activeOnly, result);
1435+
}
1436+
1437+
void FindActorsRecursiveByParentTags(Actor* node, const Array<Tag>& tags, const bool activeOnly, Array<Actor*>& result)
1438+
{
1439+
if (activeOnly && !node->GetIsActive())
1440+
return;
1441+
for (Tag tag : tags)
1442+
{
1443+
if (node->HasTag(tag))
1444+
{
1445+
result.Add(node);
1446+
break;
1447+
}
1448+
}
1449+
for (Actor* child : node->Children)
1450+
FindActorsRecursiveByParentTags(child, tags, activeOnly, result);
1451+
}
1452+
1453+
Actor* Level::FindActor(const Tag& tag, Actor* root)
1454+
{
1455+
PROFILE_CPU();
1456+
if (root)
1457+
return FindActorRecursive(root, tag);
1458+
Actor* result = nullptr;
1459+
for (Scene* scene : Scenes)
1460+
{
1461+
result = FindActorRecursive(scene, tag);
1462+
if (result)
1463+
break;
1464+
}
1465+
return result;
1466+
}
1467+
1468+
Actor* Level::FindActor(const MClass* type, const Tag& tag, Actor* root)
1469+
{
1470+
CHECK_RETURN(type, nullptr);
1471+
if (root)
1472+
return FindActorRecursiveByType(root, type, tag);
1473+
Actor* result = nullptr;
1474+
ScopeLock lock(ScenesLock);
1475+
for (int32 i = 0; result == nullptr && i < Scenes.Count(); i++)
1476+
result = Scenes[i]->FindActor(type, tag);
1477+
return result;
1478+
}
1479+
1480+
void FindActorRecursive(Actor* node, const Tag& tag, Array<Actor*>& result)
1481+
{
1482+
if (node->HasTag(tag))
1483+
result.Add(node);
1484+
for (Actor* child : node->Children)
1485+
FindActorRecursive(child, tag, result);
1486+
}
1487+
1488+
Array<Actor*> Level::FindActors(const Tag& tag, const bool activeOnly, Actor* root)
1489+
{
1490+
PROFILE_CPU();
1491+
Array<Actor*> result;
1492+
if (root)
1493+
{
1494+
FindActorsRecursive(root, tag, activeOnly, result);
1495+
}
1496+
else
1497+
{
1498+
ScopeLock lock(ScenesLock);
1499+
for (Scene* scene : Scenes)
1500+
FindActorsRecursive(scene, tag, activeOnly, result);
1501+
}
1502+
return result;
1503+
}
1504+
1505+
Array<Actor*> Level::FindActorsByParentTag(const Tag& parentTag, const bool activeOnly, Actor* root)
1506+
{
1507+
PROFILE_CPU();
1508+
Array<Actor*> result;
1509+
const Array<Tag> subTags = Tags::GetSubTags(parentTag);
1510+
1511+
if (subTags.Count() == 0)
1512+
{
1513+
return result;
1514+
}
1515+
if (subTags.Count() == 1)
1516+
{
1517+
result = FindActors(subTags[0], activeOnly, root);
1518+
return result;
1519+
}
1520+
1521+
if (root)
1522+
{
1523+
FindActorsRecursiveByParentTags(root, subTags, activeOnly, result);
1524+
}
1525+
else
1526+
{
1527+
ScopeLock lock(ScenesLock);
1528+
for (Scene* scene : Scenes)
1529+
FindActorsRecursiveByParentTags(scene, subTags, activeOnly, result);
1530+
}
1531+
1532+
return result;
1533+
}
1534+
15081535
Script* Level::FindScript(const MClass* type)
15091536
{
15101537
CHECK_RETURN(type, nullptr);

Source/Engine/Level/Level.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@ public static T FindActor<T>(string name) where T : Actor
7777
{
7878
return FindActor(typeof(T), name) as T;
7979
}
80+
81+
/// <summary>
82+
/// Tries to find actor of the given type and tag in a root actor or all loaded scenes.
83+
/// </summary>
84+
/// <param name="tag">A tag on the object.</param>
85+
/// <param name="root">The custom root actor to start searching from (hierarchical), otherwise null to search all loaded scenes.</param>
86+
/// <typeparam name="T">Type of the object.</typeparam>
87+
/// <returns>Found actor or null.</returns>
88+
public static T FindActor<T>(Tag tag, Actor root = null) where T : Actor
89+
{
90+
return FindActor(typeof(T), tag, root) as T;
91+
}
8092

8193
/// <summary>
8294
/// Tries to find actor with the given ID in all loaded scenes. It's very fast O(1) lookup.

0 commit comments

Comments
 (0)