|
|
|
|
@ -20,6 +20,7 @@
|
|
|
|
|
#include <AzCore/Serialization/Utils.h>
|
|
|
|
|
#include <AzCore/UnitTest/TestTypes.h>
|
|
|
|
|
#include <random>
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using namespace AZ;
|
|
|
|
|
@ -726,6 +727,101 @@ namespace UnitTest
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class InstanceDataHierarchyGroupTestFixture
|
|
|
|
|
: public AllocatorsFixture
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
InstanceDataHierarchyGroupTestFixture() = default;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class GroupTestComponent
|
|
|
|
|
: public AZ::Component
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
AZ_COMPONENT(GroupTestComponent, "{C088C81D-D59D-43F1-85F8-B2E591BABA36}")
|
|
|
|
|
|
|
|
|
|
GroupTestComponent() = default;
|
|
|
|
|
|
|
|
|
|
struct SubData
|
|
|
|
|
{
|
|
|
|
|
AZ_TYPE_INFO(SubData, "{983316B5-17C0-476E-9CEB-CA749B3ABE5D}");
|
|
|
|
|
AZ_CLASS_ALLOCATOR(SubData, AZ::SystemAllocator, 0);
|
|
|
|
|
|
|
|
|
|
SubData() {}
|
|
|
|
|
SubData(int v) : m_int(v) {}
|
|
|
|
|
SubData(bool b) : m_bool(b) {}
|
|
|
|
|
SubData(float f) : m_float(f) {}
|
|
|
|
|
~SubData() = default;
|
|
|
|
|
|
|
|
|
|
float m_float = 0.f;
|
|
|
|
|
int m_int = 0;
|
|
|
|
|
bool m_bool = true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void Reflect(AZ::ReflectContext* context)
|
|
|
|
|
{
|
|
|
|
|
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
|
|
|
{
|
|
|
|
|
serializeContext->Class<SubData>()
|
|
|
|
|
->Version(1)
|
|
|
|
|
->Field("SubInt", &SubData::m_int)
|
|
|
|
|
->Field("SubToggle", &SubData::m_bool)
|
|
|
|
|
->Field("SubFloat", &SubData::m_float)
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
serializeContext->Class<GroupTestComponent, AZ::Component>()
|
|
|
|
|
->Version(1)
|
|
|
|
|
->Field("Float", &GroupTestComponent::m_float)
|
|
|
|
|
->Field("GroupToggle", &GroupTestComponent::m_groupToggle)
|
|
|
|
|
->Field("GroupFloat", &GroupTestComponent::m_groupFloat)
|
|
|
|
|
->Field("ToggleGroupInt", &GroupTestComponent::m_toggleGroupInt)
|
|
|
|
|
->Field("SubDataNormal", &GroupTestComponent::m_subGroupForNormal)
|
|
|
|
|
->Field("SubDataToggle", &GroupTestComponent::m_subGroupForToggle)
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
if (AZ::EditContext* edit = serializeContext->GetEditContext())
|
|
|
|
|
{
|
|
|
|
|
edit->Class<GroupTestComponent>("Group Test Component", "Testing normal groups and toggle groups")
|
|
|
|
|
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
|
|
|
|
->DataElement(0, &GroupTestComponent::m_float, "Float Field", "A float field")
|
|
|
|
|
->ClassElement(AZ::Edit::ClassElements::Group, "Normal Group")
|
|
|
|
|
->DataElement(0, &GroupTestComponent::m_groupFloat, "Float Field", "A float field")
|
|
|
|
|
->DataElement(0, &GroupTestComponent::m_subGroupForNormal, "Struct Field", "A sub data type")
|
|
|
|
|
->GroupElementToggle("Group Toggle", &GroupTestComponent::m_groupToggle)
|
|
|
|
|
->DataElement(0, &GroupTestComponent::m_toggleGroupInt, "Normal Integer", "An Integer")
|
|
|
|
|
->DataElement(0, &GroupTestComponent::m_subGroupForToggle, "Struct Field", "A sub data type")
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
edit->Class<SubData>("SubGroup Test Component", "Testing nested normal groups and toggle groups")
|
|
|
|
|
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
|
|
|
|
->ClassElement(AZ::Edit::ClassElements::Group, "Normal SubGroup")
|
|
|
|
|
->DataElement(0, &SubData::m_int, "SubGroup Int Field", "An int")
|
|
|
|
|
->GroupElementToggle("SubGroup Toggle", &SubData::m_bool)
|
|
|
|
|
->DataElement(0, &SubData::m_float, "SubGroup Float Field", "An int")
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Activate() override
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Deactivate() override
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float m_float = 0.f;
|
|
|
|
|
float m_groupFloat = 0.f;
|
|
|
|
|
int m_toggleGroupInt = 0;
|
|
|
|
|
AZStd::string m_string;
|
|
|
|
|
bool m_groupToggle = false;
|
|
|
|
|
|
|
|
|
|
SubData m_subGroupForNormal;
|
|
|
|
|
SubData m_subGroupForToggle;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class InstanceDataHierarchyKeyedContainerTest
|
|
|
|
|
: public AllocatorsFixture
|
|
|
|
|
{
|
|
|
|
|
@ -1314,4 +1410,243 @@ namespace UnitTest
|
|
|
|
|
run();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(InstanceDataHierarchyGroupTestFixture, TestNormalGroups)
|
|
|
|
|
{
|
|
|
|
|
using namespace AzToolsFramework;
|
|
|
|
|
|
|
|
|
|
// Setting up the data node hierarchy
|
|
|
|
|
AZ::SerializeContext serializeContext;
|
|
|
|
|
serializeContext.CreateEditContext();
|
|
|
|
|
Entity::Reflect(&serializeContext);
|
|
|
|
|
GroupTestComponent::Reflect(&serializeContext);
|
|
|
|
|
|
|
|
|
|
AZStd::unique_ptr<AZ::Entity> testEntity1(new AZ::Entity());
|
|
|
|
|
testEntity1->CreateComponent<GroupTestComponent>();
|
|
|
|
|
|
|
|
|
|
InstanceDataHierarchy instanceDataHierarchy;
|
|
|
|
|
instanceDataHierarchy.AddRootInstance(testEntity1.get());
|
|
|
|
|
instanceDataHierarchy.Build(&serializeContext, 0);
|
|
|
|
|
|
|
|
|
|
// Adding the nodes to a node stack
|
|
|
|
|
auto rootNode = instanceDataHierarchy.GetRootNode();
|
|
|
|
|
AZStd::stack<InstanceDataNode*> nodeStack;
|
|
|
|
|
nodeStack.push(rootNode);
|
|
|
|
|
InstanceDataNode* componentNode1 = nullptr;
|
|
|
|
|
while (!nodeStack.empty())
|
|
|
|
|
{
|
|
|
|
|
InstanceDataNode* node = nodeStack.top();
|
|
|
|
|
nodeStack.pop();
|
|
|
|
|
if (node->GetClassMetadata()->m_typeId == AZ::AzTypeInfo<GroupTestComponent>::Uuid())
|
|
|
|
|
{
|
|
|
|
|
componentNode1 = node;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (InstanceDataNode& child : node->GetChildren())
|
|
|
|
|
{
|
|
|
|
|
nodeStack.push(&child);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Iterating through the children in the instance data hierarchy to verify their properties
|
|
|
|
|
ASSERT_TRUE(componentNode1 != nullptr);
|
|
|
|
|
for (auto child : componentNode1->GetChildren())
|
|
|
|
|
{
|
|
|
|
|
AZStd::string childName(child.GetElementMetadata()->m_name);
|
|
|
|
|
if (childName.compare("GroupFloat") == 0)
|
|
|
|
|
{
|
|
|
|
|
// False for any child node with serializable data
|
|
|
|
|
ASSERT_FALSE(child.GetElementEditMetadata()->IsClassElement());
|
|
|
|
|
// Child node should never be a ClassElement::Group, unless it is the root node of a ToggleGroup
|
|
|
|
|
ASSERT_NE(child.GetElementEditMetadata()->m_elementId, AZ::Edit::ClassElements::Group);
|
|
|
|
|
// Ensuring that this node was assigned to the appropriate group
|
|
|
|
|
ASSERT_EQ(child.GetGroupElementMetadata()->m_description, "Normal Group");
|
|
|
|
|
// Ensuring that this node has the correct parent
|
|
|
|
|
ASSERT_EQ(child.GetParent()->GetClassMetadata()->m_name, "GroupTestComponent");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(InstanceDataHierarchyGroupTestFixture, TestToggleGroups)
|
|
|
|
|
{
|
|
|
|
|
using namespace AzToolsFramework;
|
|
|
|
|
|
|
|
|
|
// Setting up the data node hierarchy
|
|
|
|
|
AZ::SerializeContext serializeContext;
|
|
|
|
|
serializeContext.CreateEditContext();
|
|
|
|
|
Entity::Reflect(&serializeContext);
|
|
|
|
|
GroupTestComponent::Reflect(&serializeContext);
|
|
|
|
|
|
|
|
|
|
AZStd::unique_ptr<AZ::Entity> testEntity1(new AZ::Entity());
|
|
|
|
|
testEntity1->CreateComponent<GroupTestComponent>();
|
|
|
|
|
|
|
|
|
|
InstanceDataHierarchy instanceDataHierarchy;
|
|
|
|
|
instanceDataHierarchy.AddRootInstance(testEntity1.get());
|
|
|
|
|
instanceDataHierarchy.Build(&serializeContext, 0);
|
|
|
|
|
|
|
|
|
|
// Adding the nodes to a node stack
|
|
|
|
|
auto rootNode = instanceDataHierarchy.GetRootNode();
|
|
|
|
|
AZStd::stack<InstanceDataNode*> nodeStack;
|
|
|
|
|
nodeStack.push(rootNode);
|
|
|
|
|
InstanceDataNode* componentNode1 = nullptr;
|
|
|
|
|
while (!nodeStack.empty())
|
|
|
|
|
{
|
|
|
|
|
InstanceDataNode* node = nodeStack.top();
|
|
|
|
|
nodeStack.pop();
|
|
|
|
|
if (node->GetClassMetadata()->m_typeId == AZ::AzTypeInfo<GroupTestComponent>::Uuid())
|
|
|
|
|
{
|
|
|
|
|
componentNode1 = node;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (InstanceDataNode& child : node->GetChildren())
|
|
|
|
|
{
|
|
|
|
|
nodeStack.push(&child);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Iterating through the children in the instance data hierarchy to verify their properties
|
|
|
|
|
ASSERT_TRUE(componentNode1 != nullptr);
|
|
|
|
|
for (auto child : componentNode1->GetChildren())
|
|
|
|
|
{
|
|
|
|
|
AZStd::string childName(child.GetElementMetadata()->m_name);
|
|
|
|
|
if (childName.compare("GroupToggle") == 0)
|
|
|
|
|
{
|
|
|
|
|
// False for any child node with serializable data
|
|
|
|
|
ASSERT_FALSE(child.GetElementEditMetadata()->IsClassElement());
|
|
|
|
|
// Child node is the root node of a ToggleGroup, so it should be a ClassElement::Group
|
|
|
|
|
ASSERT_EQ(child.GetElementEditMetadata()->m_elementId, AZ::Edit::ClassElements::Group);
|
|
|
|
|
// Ensuring that this node has the correct parent
|
|
|
|
|
ASSERT_EQ(child.GetParent()->GetClassMetadata()->m_name, "GroupTestComponent");
|
|
|
|
|
}
|
|
|
|
|
if (childName.compare("ToggleGroupInt") == 0)
|
|
|
|
|
{
|
|
|
|
|
// False for any child node with serializable data
|
|
|
|
|
ASSERT_FALSE(child.GetElementEditMetadata()->IsClassElement());
|
|
|
|
|
// Child node should never be a ClassElement::Group, unless it is the root node of a ToggleGroup
|
|
|
|
|
ASSERT_NE(child.GetElementEditMetadata()->m_elementId, AZ::Edit::ClassElements::Group);
|
|
|
|
|
// Ensuring that this node was assigned to the appropriate group
|
|
|
|
|
ASSERT_EQ(child.GetGroupElementMetadata()->m_description, "Group Toggle");
|
|
|
|
|
// Ensuring that this node has the correct parent
|
|
|
|
|
ASSERT_EQ(child.GetParent()->GetClassMetadata()->m_name, "GroupTestComponent");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(InstanceDataHierarchyGroupTestFixture, TestNestedGroups)
|
|
|
|
|
{
|
|
|
|
|
using namespace AzToolsFramework;
|
|
|
|
|
|
|
|
|
|
// Setting up the data node hierarchy
|
|
|
|
|
AZ::SerializeContext serializeContext;
|
|
|
|
|
serializeContext.CreateEditContext();
|
|
|
|
|
Entity::Reflect(&serializeContext);
|
|
|
|
|
GroupTestComponent::Reflect(&serializeContext);
|
|
|
|
|
|
|
|
|
|
AZStd::unique_ptr<AZ::Entity> testEntity1(new AZ::Entity());
|
|
|
|
|
testEntity1->CreateComponent<GroupTestComponent>();
|
|
|
|
|
|
|
|
|
|
InstanceDataHierarchy instanceDataHierarchy;
|
|
|
|
|
instanceDataHierarchy.AddRootInstance(testEntity1.get());
|
|
|
|
|
instanceDataHierarchy.Build(&serializeContext, 0);
|
|
|
|
|
|
|
|
|
|
// Adding the nodes to a node stack
|
|
|
|
|
auto rootNode = instanceDataHierarchy.GetRootNode();
|
|
|
|
|
AZStd::stack<InstanceDataNode*> nodeStack;
|
|
|
|
|
nodeStack.push(rootNode);
|
|
|
|
|
InstanceDataNode* componentNode1 = nullptr;
|
|
|
|
|
while (!nodeStack.empty())
|
|
|
|
|
{
|
|
|
|
|
InstanceDataNode* node = nodeStack.top();
|
|
|
|
|
nodeStack.pop();
|
|
|
|
|
if (node->GetClassMetadata()->m_typeId == AZ::AzTypeInfo<GroupTestComponent>::Uuid())
|
|
|
|
|
{
|
|
|
|
|
componentNode1 = node;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (InstanceDataNode& child : node->GetChildren())
|
|
|
|
|
{
|
|
|
|
|
nodeStack.push(&child);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Iterating through the children in the instance data hierarchy to verify their properties
|
|
|
|
|
ASSERT_TRUE(componentNode1 != nullptr);
|
|
|
|
|
for (auto child : componentNode1->GetChildren())
|
|
|
|
|
{
|
|
|
|
|
AZStd::string childName(child.GetElementMetadata()->m_name);
|
|
|
|
|
if (childName.compare("SubDataNormal") == 0)
|
|
|
|
|
{
|
|
|
|
|
for (InstanceDataNode& subChild : child.GetChildren())
|
|
|
|
|
{
|
|
|
|
|
childName = subChild.GetElementMetadata()->m_name;
|
|
|
|
|
if (childName.compare("SubInt") == 0)
|
|
|
|
|
{
|
|
|
|
|
// False for any child node with serializable data
|
|
|
|
|
ASSERT_FALSE(subChild.GetElementEditMetadata()->IsClassElement());
|
|
|
|
|
// Child node should never be a ClassElement::Group, unless it is the root node of a ToggleGroup
|
|
|
|
|
ASSERT_NE(subChild.GetElementEditMetadata()->m_elementId, AZ::Edit::ClassElements::Group);
|
|
|
|
|
// Ensuring that this node was assigned to the appropriate group
|
|
|
|
|
ASSERT_EQ(subChild.GetGroupElementMetadata()->m_description, "Normal SubGroup");
|
|
|
|
|
// Ensuring that this node has the correct parent
|
|
|
|
|
ASSERT_EQ(subChild.GetParent()->GetClassMetadata()->m_name, "SubData");
|
|
|
|
|
}
|
|
|
|
|
if (childName.compare("SubToggle") == 0)
|
|
|
|
|
{
|
|
|
|
|
// False for any child node with serializable data
|
|
|
|
|
ASSERT_FALSE(subChild.GetElementEditMetadata()->IsClassElement());
|
|
|
|
|
// Child node is the root node of a ToggleGroup, so it should be a ClassElement::Group
|
|
|
|
|
ASSERT_EQ(subChild.GetElementEditMetadata()->m_elementId, AZ::Edit::ClassElements::Group);
|
|
|
|
|
// Ensuring that this node has the correct parent
|
|
|
|
|
ASSERT_EQ(subChild.GetParent()->GetClassMetadata()->m_name, "SubData");
|
|
|
|
|
}
|
|
|
|
|
if (childName.compare("SubFloat") == 0)
|
|
|
|
|
{
|
|
|
|
|
// False for any child node with serializable data
|
|
|
|
|
ASSERT_FALSE(subChild.GetElementEditMetadata()->IsClassElement());
|
|
|
|
|
// Child node should never be a ClassElement::Group, unless it is the root node of a ToggleGroup
|
|
|
|
|
ASSERT_NE(subChild.GetElementEditMetadata()->m_elementId, AZ::Edit::ClassElements::Group);
|
|
|
|
|
// Ensuring that this node was assigned to the appropriate group
|
|
|
|
|
ASSERT_EQ(subChild.GetGroupElementMetadata()->m_description, "SubGroup Toggle");
|
|
|
|
|
// Ensuring that this node has the correct parent
|
|
|
|
|
ASSERT_EQ(subChild.GetParent()->GetClassMetadata()->m_name, "SubData");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (childName.compare("SubDataToggle") == 0)
|
|
|
|
|
{
|
|
|
|
|
for (InstanceDataNode& subChild : child.GetChildren())
|
|
|
|
|
{
|
|
|
|
|
childName = subChild.GetElementMetadata()->m_name;
|
|
|
|
|
if (childName.compare("SubInt") == 0)
|
|
|
|
|
{
|
|
|
|
|
// False for any child node with serializable data
|
|
|
|
|
ASSERT_FALSE(subChild.GetElementEditMetadata()->IsClassElement());
|
|
|
|
|
// Child node should never be a ClassElement::Group, unless it is the root node of a ToggleGroup
|
|
|
|
|
ASSERT_NE(subChild.GetElementEditMetadata()->m_elementId, AZ::Edit::ClassElements::Group);
|
|
|
|
|
// Ensuring that this node was assigned to the appropriate group
|
|
|
|
|
ASSERT_EQ(subChild.GetGroupElementMetadata()->m_description, "Normal SubGroup");
|
|
|
|
|
// Ensuring that this node has the correct parent
|
|
|
|
|
ASSERT_EQ(subChild.GetParent()->GetClassMetadata()->m_name, "SubData");
|
|
|
|
|
}
|
|
|
|
|
if (childName.compare("SubToggle") == 0)
|
|
|
|
|
{
|
|
|
|
|
// False for any child node with serializable data
|
|
|
|
|
ASSERT_FALSE(subChild.GetElementEditMetadata()->IsClassElement());
|
|
|
|
|
// Child node is the root node of a ToggleGroup, so it should be a ClassElement::Group
|
|
|
|
|
ASSERT_EQ(subChild.GetElementEditMetadata()->m_elementId, AZ::Edit::ClassElements::Group);
|
|
|
|
|
// Ensuring that this node has the correct parent
|
|
|
|
|
ASSERT_EQ(subChild.GetParent()->GetClassMetadata()->m_name, "SubData");
|
|
|
|
|
}
|
|
|
|
|
if (childName.compare("SubFloat") == 0)
|
|
|
|
|
{
|
|
|
|
|
// False for any child node with serializable data
|
|
|
|
|
ASSERT_FALSE(subChild.GetElementEditMetadata()->IsClassElement());
|
|
|
|
|
// Child node should never be a ClassElement::Group, unless it is the root node of a ToggleGroup
|
|
|
|
|
ASSERT_NE(subChild.GetElementEditMetadata()->m_elementId, AZ::Edit::ClassElements::Group);
|
|
|
|
|
// Ensuring that this node was assigned to the appropriate group
|
|
|
|
|
ASSERT_EQ(subChild.GetGroupElementMetadata()->m_description, "SubGroup Toggle");
|
|
|
|
|
// Ensuring that this node has the correct parent
|
|
|
|
|
ASSERT_EQ(subChild.GetParent()->GetClassMetadata()->m_name, "SubData");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace UnitTest
|
|
|
|
|
|