CDependencyTree: Make use of unique_ptr

Makes the ownership semantics explicit in the interface.
This commit is contained in:
Lioncash 2020-06-12 13:46:49 -04:00
parent e2190793fd
commit 7da16efe9d
4 changed files with 48 additions and 51 deletions

View File

@ -9,11 +9,7 @@
#include <array> #include <array>
// ************ IDependencyNode ************ // ************ IDependencyNode ************
IDependencyNode::~IDependencyNode() IDependencyNode::~IDependencyNode() = default;
{
for (uint32 iChild = 0; iChild < mChildren.size(); iChild++)
delete mChildren[iChild];
}
bool IDependencyNode::HasDependency(const CAssetID& id) const bool IDependencyNode::HasDependency(const CAssetID& id) const
{ {
@ -51,8 +47,7 @@ void IDependencyNode::ParseProperties(CResourceEntry* pParentEntry, CStructPrope
if (Info.pAudioGroup) if (Info.pAudioGroup)
{ {
CPropertyDependency *pDep = new CPropertyDependency(pProp->IDString(true), Info.pAudioGroup->ID()); mChildren.push_back(std::make_unique<CPropertyDependency>(pProp->IDString(true), Info.pAudioGroup->ID()));
mChildren.push_back(pDep);
} }
} }
} }
@ -63,8 +58,7 @@ void IDependencyNode::ParseProperties(CResourceEntry* pParentEntry, CStructPrope
if (ID.IsValid()) if (ID.IsValid())
{ {
CPropertyDependency *pDep = new CPropertyDependency(pProp->IDString(true), ID); mChildren.push_back(std::make_unique<CPropertyDependency>(pProp->IDString(true), ID));
mChildren.push_back(pDep);
} }
} }
@ -78,13 +72,11 @@ void IDependencyNode::ParseProperties(CResourceEntry* pParentEntry, CStructPrope
// Character sets are removed starting in MP3, so we only need char property dependencies in Echoes and earlier // Character sets are removed starting in MP3, so we only need char property dependencies in Echoes and earlier
if (pProperties->Game() <= EGame::Echoes) if (pProperties->Game() <= EGame::Echoes)
{ {
CCharPropertyDependency *pDep = new CCharPropertyDependency(pProp->IDString(true), ID, Params.CharacterIndex()); mChildren.push_back(std::make_unique<CCharPropertyDependency>(pProp->IDString(true), ID, Params.CharacterIndex()));
mChildren.push_back(pDep);
} }
else else
{ {
CPropertyDependency *pDep = new CPropertyDependency(pProp->IDString(true), ID); mChildren.push_back(std::make_unique<CPropertyDependency>(pProp->IDString(true), ID));
mChildren.push_back(pDep);
} }
} }
} }
@ -120,22 +112,25 @@ void CDependencyTree::Serialize(IArchive& rArc)
rArc << SerialParameter("Children", mChildren); rArc << SerialParameter("Children", mChildren);
} }
void CDependencyTree::AddChild(IDependencyNode *pNode) void CDependencyTree::AddChild(std::unique_ptr<IDependencyNode>&& pNode)
{ {
ASSERT(pNode); ASSERT(pNode);
mChildren.push_back(pNode); mChildren.push_back(std::move(pNode));
} }
void CDependencyTree::AddDependency(const CAssetID& rkID, bool AvoidDuplicates /*= true*/) void CDependencyTree::AddDependency(const CAssetID& rkID, bool AvoidDuplicates /*= true*/)
{ {
if (!rkID.IsValid() || (AvoidDuplicates && HasDependency(rkID))) return; if (!rkID.IsValid() || (AvoidDuplicates && HasDependency(rkID)))
CResourceDependency *pDepend = new CResourceDependency(rkID); return;
mChildren.push_back(pDepend);
mChildren.push_back(std::make_unique<CResourceDependency>(rkID));
} }
void CDependencyTree::AddDependency(CResource *pRes, bool AvoidDuplicates /*= true*/) void CDependencyTree::AddDependency(CResource *pRes, bool AvoidDuplicates /*= true*/)
{ {
if (!pRes) return; if (!pRes)
return;
AddDependency(pRes->ID(), AvoidDuplicates); AddDependency(pRes->ID(), AvoidDuplicates);
} }
@ -146,8 +141,7 @@ void CDependencyTree::AddCharacterDependency(const CAnimationParameters& rkAnimP
if (!pSet || rkAnimParams.CharacterIndex() == UINT32_MAX) if (!pSet || rkAnimParams.CharacterIndex() == UINT32_MAX)
return; return;
CCharPropertyDependency *pChar = new CCharPropertyDependency("NULL", pSet->ID(), rkAnimParams.CharacterIndex()); mChildren.push_back(std::make_unique<CCharPropertyDependency>("NULL", pSet->ID(), rkAnimParams.CharacterIndex()));
mChildren.push_back(pChar);
} }
// ************ CResourceDependency ************ // ************ CResourceDependency ************
@ -208,9 +202,9 @@ void CScriptInstanceDependency::Serialize(IArchive& rArc)
} }
// Static // Static
CScriptInstanceDependency* CScriptInstanceDependency::BuildTree(CScriptObject *pInstance) std::unique_ptr<CScriptInstanceDependency> CScriptInstanceDependency::BuildTree(CScriptObject *pInstance)
{ {
CScriptInstanceDependency *pInst = new CScriptInstanceDependency(); auto pInst = std::make_unique<CScriptInstanceDependency>();
pInst->mObjectType = pInstance->ObjectTypeID(); pInst->mObjectType = pInstance->ObjectTypeID();
pInst->ParseProperties(pInstance->Area()->Entry(), pInstance->Template()->Properties(), pInstance->PropertyData()); pInst->ParseProperties(pInstance->Area()->Entry(), pInstance->Template()->Properties(), pInstance->PropertyData());
return pInst; return pInst;
@ -228,9 +222,9 @@ void CSetCharacterDependency::Serialize(IArchive& rArc)
<< SerialParameter("Children", mChildren); << SerialParameter("Children", mChildren);
} }
CSetCharacterDependency* CSetCharacterDependency::BuildTree(const SSetCharacter& rkChar) std::unique_ptr<CSetCharacterDependency> CSetCharacterDependency::BuildTree(const SSetCharacter& rkChar)
{ {
CSetCharacterDependency *pTree = new CSetCharacterDependency(rkChar.ID); auto pTree = std::make_unique<CSetCharacterDependency>(rkChar.ID);
pTree->AddDependency(rkChar.pModel); pTree->AddDependency(rkChar.pModel);
pTree->AddDependency(rkChar.pSkeleton); pTree->AddDependency(rkChar.pSkeleton);
pTree->AddDependency(rkChar.pSkin); pTree->AddDependency(rkChar.pSkin);
@ -271,9 +265,9 @@ void CSetAnimationDependency::Serialize(IArchive& rArc)
<< SerialParameter("Children", mChildren); << SerialParameter("Children", mChildren);
} }
CSetAnimationDependency* CSetAnimationDependency::BuildTree(const CAnimSet *pkOwnerSet, uint32 AnimIndex) std::unique_ptr<CSetAnimationDependency> CSetAnimationDependency::BuildTree(const CAnimSet *pkOwnerSet, uint32 AnimIndex)
{ {
CSetAnimationDependency *pTree = new CSetAnimationDependency; auto pTree = std::make_unique<CSetAnimationDependency>();
const SAnimation *pkAnim = pkOwnerSet->Animation(AnimIndex); const SAnimation *pkAnim = pkOwnerSet->Animation(AnimIndex);
// Find relevant character indices // Find relevant character indices
@ -297,7 +291,7 @@ CSetAnimationDependency* CSetAnimationDependency::BuildTree(const CAnimSet *pkOw
{ {
CAnimEventData *pEvents = pkOwnerSet->AnimationEventData(prim.ID()); CAnimEventData *pEvents = pkOwnerSet->AnimationEventData(prim.ID());
ASSERT(pEvents && !pEvents->Entry()); ASSERT(pEvents && !pEvents->Entry());
pEvents->AddDependenciesToTree(pTree); pEvents->AddDependenciesToTree(pTree.get());
} }
} }
@ -330,23 +324,23 @@ void CAreaDependencyTree::Serialize(IArchive& rArc)
void CAreaDependencyTree::AddScriptLayer(CScriptLayer *pLayer, const std::vector<CAssetID>& rkExtraDeps) void CAreaDependencyTree::AddScriptLayer(CScriptLayer *pLayer, const std::vector<CAssetID>& rkExtraDeps)
{ {
if (!pLayer) return; if (!pLayer)
return;
mLayerOffsets.push_back(mChildren.size()); mLayerOffsets.push_back(mChildren.size());
std::set<CAssetID> UsedIDs; std::set<CAssetID> UsedIDs;
for (uint32 iInst = 0; iInst < pLayer->NumInstances(); iInst++) for (uint32 iInst = 0; iInst < pLayer->NumInstances(); iInst++)
{ {
CScriptInstanceDependency *pTree = CScriptInstanceDependency::BuildTree( pLayer->InstanceByIndex(iInst) ); auto pTree = CScriptInstanceDependency::BuildTree( pLayer->InstanceByIndex(iInst) );
ASSERT(pTree != nullptr); ASSERT(pTree != nullptr);
// Note: MP2+ need to track all instances (not just instances with dependencies) to be able to build the layer module list // Note: MP2+ need to track all instances (not just instances with dependencies) to be able to build the layer module list
if (pTree->NumChildren() > 0 || pLayer->Area()->Game() >= EGame::EchoesDemo) if (pTree->NumChildren() > 0 || pLayer->Area()->Game() >= EGame::EchoesDemo)
{ {
mChildren.push_back(pTree);
pTree->GetAllResourceReferences(UsedIDs); pTree->GetAllResourceReferences(UsedIDs);
mChildren.push_back(std::move(pTree));
} }
else
delete pTree;
} }
for (uint32 iDep = 0; iDep < rkExtraDeps.size(); iDep++) for (uint32 iDep = 0; iDep < rkExtraDeps.size(); iDep++)
@ -372,10 +366,11 @@ void CAreaDependencyTree::GetModuleDependencies(EGame Game, std::vector<TString>
for (uint32 iInst = StartIdx; iInst < EndIdx; iInst++) for (uint32 iInst = StartIdx; iInst < EndIdx; iInst++)
{ {
IDependencyNode *pNode = mChildren[iInst]; auto& pNode = mChildren[iInst];
if (pNode->Type() != EDependencyNodeType::ScriptInstance) continue; if (pNode->Type() != EDependencyNodeType::ScriptInstance)
continue;
CScriptInstanceDependency *pInst = static_cast<CScriptInstanceDependency*>(pNode); const auto *pInst = static_cast<CScriptInstanceDependency*>(pNode.get());
uint32 ObjType = pInst->ObjectType(); uint32 ObjType = pInst->ObjectType();
if (UsedObjectTypes.find(ObjType) == UsedObjectTypes.end()) if (UsedObjectTypes.find(ObjType) == UsedObjectTypes.end())

View File

@ -5,6 +5,7 @@
#include <Common/CAssetID.h> #include <Common/CAssetID.h>
#include <Common/FileIO.h> #include <Common/FileIO.h>
#include <Common/Macros.h> #include <Common/Macros.h>
#include <memory>
class CScriptLayer; class CScriptLayer;
class CScriptObject; class CScriptObject;
@ -31,7 +32,7 @@ enum class EDependencyNodeType
class IDependencyNode class IDependencyNode
{ {
protected: protected:
std::vector<IDependencyNode*> mChildren; std::vector<std::unique_ptr<IDependencyNode>> mChildren;
public: public:
virtual ~IDependencyNode(); virtual ~IDependencyNode();
@ -45,8 +46,8 @@ public:
static IDependencyNode* ArchiveConstructor(EDependencyNodeType Type); static IDependencyNode* ArchiveConstructor(EDependencyNodeType Type);
// Accessors // Accessors
uint NumChildren() const { return mChildren.size(); } uint32 NumChildren() const { return mChildren.size(); }
IDependencyNode* ChildByIndex(uint Index) const { return mChildren[Index]; } IDependencyNode* ChildByIndex(uint32 Index) const { return mChildren[Index].get(); }
}; };
// Basic dependency tree; this class is sufficient for most resource types. // Basic dependency tree; this class is sufficient for most resource types.
@ -58,7 +59,7 @@ public:
EDependencyNodeType Type() const override; EDependencyNodeType Type() const override;
void Serialize(IArchive& rArc) override; void Serialize(IArchive& rArc) override;
void AddChild(IDependencyNode *pNode); void AddChild(std::unique_ptr<IDependencyNode>&& pNode);
void AddDependency(const CAssetID& rkID, bool AvoidDuplicates = true); void AddDependency(const CAssetID& rkID, bool AvoidDuplicates = true);
void AddDependency(CResource *pRes, bool AvoidDuplicates = true); void AddDependency(CResource *pRes, bool AvoidDuplicates = true);
void AddCharacterDependency(const CAnimationParameters& rkAnimParams); void AddCharacterDependency(const CAnimationParameters& rkAnimParams);
@ -72,7 +73,7 @@ protected:
public: public:
CResourceDependency() = default; CResourceDependency() = default;
CResourceDependency(const CAssetID& rkID) : mID(rkID) {} explicit CResourceDependency(const CAssetID& rkID) : mID(rkID) {}
EDependencyNodeType Type() const override; EDependencyNodeType Type() const override;
void Serialize(IArchive& rArc) override; void Serialize(IArchive& rArc) override;
@ -139,7 +140,7 @@ public:
uint ObjectType() const { return mObjectType; } uint ObjectType() const { return mObjectType; }
// Static // Static
static CScriptInstanceDependency* BuildTree(CScriptObject *pInstance); static std::unique_ptr<CScriptInstanceDependency> BuildTree(CScriptObject *pInstance);
}; };
// Node representing an animset character. Indicates what index the character is within the animset. // Node representing an animset character. Indicates what index the character is within the animset.
@ -159,7 +160,7 @@ public:
uint32 CharSetIndex() const { return mCharSetIndex; } uint32 CharSetIndex() const { return mCharSetIndex; }
// Static // Static
static CSetCharacterDependency* BuildTree(const SSetCharacter& rkChar); static std::unique_ptr<CSetCharacterDependency> BuildTree(const SSetCharacter& rkChar);
}; };
// Node representing a character animation. Indicates which character indices use this animation. // Node representing a character animation. Indicates which character indices use this animation.
@ -179,7 +180,7 @@ public:
bool IsUsedByAnyCharacter() const { return !mCharacterIndices.empty(); } bool IsUsedByAnyCharacter() const { return !mCharacterIndices.empty(); }
// Static // Static
static CSetAnimationDependency* BuildTree(const CAnimSet *pkOwnerSet, uint32 AnimIndex); static std::unique_ptr<CSetAnimationDependency> BuildTree(const CAnimSet *pkOwnerSet, uint32 AnimIndex);
}; };
// Node representing an animation event. Indicates which character index uses this event. // Node representing an animation event. Indicates which character index uses this event.

View File

@ -2,6 +2,8 @@
#define CANIMEVENTDATA #define CANIMEVENTDATA
#include "Core/Resource/CResource.h" #include "Core/Resource/CResource.h"
#include <memory>
#include <vector>
class CAnimEventData : public CResource class CAnimEventData : public CResource
{ {
@ -36,8 +38,7 @@ public:
if (ID.IsValid() && !pTree->HasDependency(ID)) if (ID.IsValid() && !pTree->HasDependency(ID))
{ {
auto *pDep = new CAnimEventDependency(ID, event.mCharacterIndex); pTree->AddChild(std::make_unique<CAnimEventDependency>(ID, event.mCharacterIndex));
pTree->AddChild(pDep);
} }
} }
} }

View File

@ -124,9 +124,9 @@ public:
// Character dependencies // Character dependencies
for (const auto& character : mCharacters) for (const auto& character : mCharacters)
{ {
CSetCharacterDependency *pCharTree = CSetCharacterDependency::BuildTree(character); auto pCharTree = CSetCharacterDependency::BuildTree(character);
ASSERT(pCharTree); ASSERT(pCharTree);
pTree->AddChild(pCharTree); pTree->AddChild(std::move(pCharTree));
} }
// Animation dependencies // Animation dependencies
@ -134,9 +134,9 @@ public:
{ {
for (uint32 iAnim = 0; iAnim < mAnimations.size(); iAnim++) for (uint32 iAnim = 0; iAnim < mAnimations.size(); iAnim++)
{ {
CSetAnimationDependency *pAnimTree = CSetAnimationDependency::BuildTree(this, iAnim); auto pAnimTree = CSetAnimationDependency::BuildTree(this, iAnim);
ASSERT(pAnimTree); ASSERT(pAnimTree);
pTree->AddChild(pAnimTree); pTree->AddChild(std::move(pAnimTree));
} }
} }
else if (Game() <= EGame::Corruption) else if (Game() <= EGame::Corruption)