SceneResolver.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #include "../Precompiled.h"
  4. #include "../IO/Log.h"
  5. #include "../Scene/Component.h"
  6. #include "../Scene/SceneResolver.h"
  7. #include "../Scene/Node.h"
  8. #include "../DebugNew.h"
  9. namespace Urho3D
  10. {
  11. SceneResolver::SceneResolver() = default;
  12. SceneResolver::~SceneResolver() = default;
  13. void SceneResolver::Reset()
  14. {
  15. nodes_.Clear();
  16. components_.Clear();
  17. }
  18. void SceneResolver::AddNode(NodeId oldID, Node* node)
  19. {
  20. if (node)
  21. nodes_[oldID] = node;
  22. }
  23. void SceneResolver::AddComponent(ComponentId oldID, Component* component)
  24. {
  25. if (component)
  26. components_[oldID] = component;
  27. }
  28. void SceneResolver::Resolve()
  29. {
  30. // Nodes do not have component or node ID attributes, so only have to go through components
  31. HashSet<StringHash> noIDAttributes;
  32. for (HashMap<ComponentId, WeakPtr<Component>>::ConstIterator i = components_.Begin(); i != components_.End(); ++i)
  33. {
  34. Component* component = i->second_;
  35. if (!component || noIDAttributes.Contains(component->GetType()))
  36. continue;
  37. bool hasIDAttributes = false;
  38. const Vector<AttributeInfo>* attributes = component->GetAttributes();
  39. if (!attributes)
  40. {
  41. noIDAttributes.Insert(component->GetType());
  42. continue;
  43. }
  44. for (unsigned j = 0; j < attributes->Size(); ++j)
  45. {
  46. const AttributeInfo& info = attributes->At(j);
  47. if (info.mode_ & AM_NODEID)
  48. {
  49. hasIDAttributes = true;
  50. NodeId oldNodeID = component->GetAttribute(j).GetU32();
  51. if (oldNodeID)
  52. {
  53. HashMap<NodeId, WeakPtr<Node>>::ConstIterator k = nodes_.Find(oldNodeID);
  54. if (k != nodes_.End() && k->second_)
  55. {
  56. NodeId newNodeID = k->second_->GetID();
  57. component->SetAttribute(j, Variant(newNodeID));
  58. }
  59. else
  60. URHO3D_LOGWARNING("Could not resolve node ID " + String(oldNodeID));
  61. }
  62. }
  63. else if (info.mode_ & AM_COMPONENTID)
  64. {
  65. hasIDAttributes = true;
  66. ComponentId oldComponentID = component->GetAttribute(j).GetU32();
  67. if (oldComponentID)
  68. {
  69. HashMap<ComponentId, WeakPtr<Component>>::ConstIterator k = components_.Find(oldComponentID);
  70. if (k != components_.End() && k->second_)
  71. {
  72. ComponentId newComponentID = k->second_->GetID();
  73. component->SetAttribute(j, Variant(newComponentID));
  74. }
  75. else
  76. URHO3D_LOGWARNING("Could not resolve component ID " + String(oldComponentID));
  77. }
  78. }
  79. else if (info.mode_ & AM_NODEIDVECTOR)
  80. {
  81. hasIDAttributes = true;
  82. Variant attrValue = component->GetAttribute(j);
  83. const VariantVector& oldNodeIDs = attrValue.GetVariantVector();
  84. if (oldNodeIDs.Size())
  85. {
  86. // The first index stores the number of IDs redundantly. This is for editing
  87. unsigned numIDs = oldNodeIDs[0].GetU32();
  88. VariantVector newIDs;
  89. newIDs.Push(numIDs);
  90. for (unsigned k = 1; k < oldNodeIDs.Size(); ++k)
  91. {
  92. NodeId oldNodeID = oldNodeIDs[k].GetU32();
  93. HashMap<NodeId, WeakPtr<Node>>::ConstIterator l = nodes_.Find(oldNodeID);
  94. if (l != nodes_.End() && l->second_)
  95. newIDs.Push(l->second_->GetID());
  96. else
  97. {
  98. // If node was not found, retain number of elements, just store ID 0
  99. newIDs.Push(0);
  100. URHO3D_LOGWARNING("Could not resolve node ID " + String(oldNodeID));
  101. }
  102. }
  103. component->SetAttribute(j, newIDs);
  104. }
  105. }
  106. }
  107. // If component type had no ID attributes, cache this fact for optimization
  108. if (!hasIDAttributes)
  109. noIDAttributes.Insert(component->GetType());
  110. }
  111. // Attributes have been resolved, so no need to remember the nodes after this
  112. Reset();
  113. }
  114. }