From 595c2e0a8e23391a56a2352f70e6ad739f9ce5b1 Mon Sep 17 00:00:00 2001
From: elsid <elsid.mail@gmail.com>
Date: Wed, 23 Feb 2022 00:39:30 +0100
Subject: [PATCH] Use unique_ptr to manage AiPackage lifetime

---
 apps/openmw/mwmechanics/aiactivate.cpp |  4 +--
 apps/openmw/mwmechanics/aicombat.cpp   |  4 +--
 apps/openmw/mwmechanics/aiescort.cpp   |  4 +--
 apps/openmw/mwmechanics/aifollow.cpp   |  4 +--
 apps/openmw/mwmechanics/aipursue.cpp   |  4 +--
 apps/openmw/mwmechanics/aisequence.cpp | 20 ++++++------
 apps/openmw/mwmechanics/aitravel.cpp   |  4 +--
 apps/openmw/mwmechanics/aiwander.cpp   |  4 +--
 components/esm3/aisequence.cpp         | 44 +++++++++++---------------
 components/esm3/aisequence.hpp         |  4 +--
 10 files changed, 45 insertions(+), 51 deletions(-)

diff --git a/apps/openmw/mwmechanics/aiactivate.cpp b/apps/openmw/mwmechanics/aiactivate.cpp
index 42cff3642e..c2bcab2297 100644
--- a/apps/openmw/mwmechanics/aiactivate.cpp
+++ b/apps/openmw/mwmechanics/aiactivate.cpp
@@ -52,8 +52,8 @@ namespace MWMechanics
 
         ESM::AiSequence::AiPackageContainer package;
         package.mType = ESM::AiSequence::Ai_Activate;
-        package.mPackage = activate.release();
-        sequence.mPackages.push_back(package);
+        package.mPackage = std::move(activate);
+        sequence.mPackages.push_back(std::move(package));
     }
 
     AiActivate::AiActivate(const ESM::AiSequence::AiActivate *activate)
diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp
index 83ff795545..231597f9e0 100644
--- a/apps/openmw/mwmechanics/aicombat.cpp
+++ b/apps/openmw/mwmechanics/aicombat.cpp
@@ -460,8 +460,8 @@ namespace MWMechanics
 
         ESM::AiSequence::AiPackageContainer package;
         package.mType = ESM::AiSequence::Ai_Combat;
-        package.mPackage = combat.release();
-        sequence.mPackages.push_back(package);
+        package.mPackage = std::move(combat);
+        sequence.mPackages.push_back(std::move(package));
     }
 
     void AiCombatStorage::startCombatMove(bool isDistantCombat, float distToTarget, float rangeAttack, const MWWorld::Ptr& actor, const MWWorld::Ptr& target)
diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp
index a1c0bd0471..2e7d55712f 100644
--- a/apps/openmw/mwmechanics/aiescort.cpp
+++ b/apps/openmw/mwmechanics/aiescort.cpp
@@ -109,8 +109,8 @@ namespace MWMechanics
 
         ESM::AiSequence::AiPackageContainer package;
         package.mType = ESM::AiSequence::Ai_Escort;
-        package.mPackage = escort.release();
-        sequence.mPackages.push_back(package);
+        package.mPackage = std::move(escort);
+        sequence.mPackages.push_back(std::move(package));
     }
 
     void AiEscort::fastForward(const MWWorld::Ptr& actor, AiState &state)
diff --git a/apps/openmw/mwmechanics/aifollow.cpp b/apps/openmw/mwmechanics/aifollow.cpp
index cdb8ac8c1d..9444303821 100644
--- a/apps/openmw/mwmechanics/aifollow.cpp
+++ b/apps/openmw/mwmechanics/aifollow.cpp
@@ -217,8 +217,8 @@ void AiFollow::writeState(ESM::AiSequence::AiSequence &sequence) const
 
     ESM::AiSequence::AiPackageContainer package;
     package.mType = ESM::AiSequence::Ai_Follow;
-    package.mPackage = follow.release();
-    sequence.mPackages.push_back(package);
+    package.mPackage = std::move(follow);
+    sequence.mPackages.push_back(std::move(package));
 }
 
 int AiFollow::getFollowIndex() const
diff --git a/apps/openmw/mwmechanics/aipursue.cpp b/apps/openmw/mwmechanics/aipursue.cpp
index 3343b3cec0..252bff58f8 100644
--- a/apps/openmw/mwmechanics/aipursue.cpp
+++ b/apps/openmw/mwmechanics/aipursue.cpp
@@ -81,8 +81,8 @@ void AiPursue::writeState(ESM::AiSequence::AiSequence &sequence) const
 
     ESM::AiSequence::AiPackageContainer package;
     package.mType = ESM::AiSequence::Ai_Pursue;
-    package.mPackage = pursue.release();
-    sequence.mPackages.push_back(package);
+    package.mPackage = std::move(pursue);
+    sequence.mPackages.push_back(std::move(package));
 }
 
 } // namespace MWMechanics
diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp
index bf01936f90..c59b3e39fe 100644
--- a/apps/openmw/mwmechanics/aisequence.cpp
+++ b/apps/openmw/mwmechanics/aisequence.cpp
@@ -498,41 +498,41 @@ void AiSequence::readState(const ESM::AiSequence::AiSequence &sequence)
         {
         case ESM::AiSequence::Ai_Wander:
         {
-            package.reset(new AiWander(static_cast<ESM::AiSequence::AiWander*>(container.mPackage)));
+            package.reset(new AiWander(&static_cast<const ESM::AiSequence::AiWander&>(*container.mPackage)));
             break;
         }
         case ESM::AiSequence::Ai_Travel:
         {
-            const auto source = static_cast<const ESM::AiSequence::AiTravel*>(container.mPackage);
-            if (source->mHidden)
-                package.reset(new AiInternalTravel(source));
+            const ESM::AiSequence::AiTravel& source = static_cast<const ESM::AiSequence::AiTravel&>(*container.mPackage);
+            if (source.mHidden)
+                package.reset(new AiInternalTravel(&source));
             else
-                package.reset(new AiTravel(source));
+                package.reset(new AiTravel(&source));
             break;
         }
         case ESM::AiSequence::Ai_Escort:
         {
-            package.reset(new AiEscort(static_cast<ESM::AiSequence::AiEscort*>(container.mPackage)));
+            package.reset(new AiEscort(&static_cast<const ESM::AiSequence::AiEscort&>(*container.mPackage)));
             break;
         }
         case ESM::AiSequence::Ai_Follow:
         {
-            package.reset(new AiFollow(static_cast<ESM::AiSequence::AiFollow*>(container.mPackage)));
+            package.reset(new AiFollow(&static_cast<const ESM::AiSequence::AiFollow&>(*container.mPackage)));
             break;
         }
         case ESM::AiSequence::Ai_Activate:
         {
-            package.reset(new AiActivate(static_cast<ESM::AiSequence::AiActivate*>(container.mPackage)));
+            package.reset(new AiActivate(&static_cast<const ESM::AiSequence::AiActivate&>(*container.mPackage)));
             break;
         }
         case ESM::AiSequence::Ai_Combat:
         {
-            package.reset(new AiCombat(static_cast<ESM::AiSequence::AiCombat*>(container.mPackage)));
+            package.reset(new AiCombat(&static_cast<const ESM::AiSequence::AiCombat&>(*container.mPackage)));
             break;
         }
         case ESM::AiSequence::Ai_Pursue:
         {
-            package.reset(new AiPursue(static_cast<ESM::AiSequence::AiPursue*>(container.mPackage)));
+            package.reset(new AiPursue(&static_cast<const ESM::AiSequence::AiPursue&>(*container.mPackage)));
             break;
         }
         default:
diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp
index d420771bd4..4a2df475f4 100644
--- a/apps/openmw/mwmechanics/aitravel.cpp
+++ b/apps/openmw/mwmechanics/aitravel.cpp
@@ -129,8 +129,8 @@ namespace MWMechanics
 
         ESM::AiSequence::AiPackageContainer package;
         package.mType = ESM::AiSequence::Ai_Travel;
-        package.mPackage = travel.release();
-        sequence.mPackages.push_back(package);
+        package.mPackage = std::move(travel);
+        sequence.mPackages.push_back(std::move(package));
     }
 
     AiInternalTravel::AiInternalTravel(float x, float y, float z)
diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp
index c2f0beb179..c63a4c0270 100644
--- a/apps/openmw/mwmechanics/aiwander.cpp
+++ b/apps/openmw/mwmechanics/aiwander.cpp
@@ -888,8 +888,8 @@ namespace MWMechanics
 
         ESM::AiSequence::AiPackageContainer package;
         package.mType = ESM::AiSequence::Ai_Wander;
-        package.mPackage = wander.release();
-        sequence.mPackages.push_back(package);
+        package.mPackage = std::move(wander);
+        sequence.mPackages.push_back(std::move(package));
     }
 
     AiWander::AiWander (const ESM::AiSequence::AiWander* wander)
diff --git a/components/esm3/aisequence.cpp b/components/esm3/aisequence.cpp
index b99cac3ade..a9670a598d 100644
--- a/components/esm3/aisequence.cpp
+++ b/components/esm3/aisequence.cpp
@@ -152,12 +152,6 @@ namespace AiSequence
         esm.writeHNT ("TARG", mTargetActorId);
     }
 
-    AiSequence::~AiSequence()
-    {
-        for (std::vector<AiPackageContainer>::iterator it = mPackages.begin(); it != mPackages.end(); ++it)
-            delete it->mPackage;
-    }
-
     void AiSequence::save(ESMWriter &esm) const
     {
         for (std::vector<AiPackageContainer>::const_iterator it = mPackages.begin(); it != mPackages.end(); ++it)
@@ -166,25 +160,25 @@ namespace AiSequence
             switch (it->mType)
             {
             case Ai_Wander:
-                static_cast<const AiWander*>(it->mPackage)->save(esm);
+                static_cast<const AiWander&>(*it->mPackage).save(esm);
                 break;
             case Ai_Travel:
-                static_cast<const AiTravel*>(it->mPackage)->save(esm);
+                static_cast<const AiTravel&>(*it->mPackage).save(esm);
                 break;
             case Ai_Escort:
-                static_cast<const AiEscort*>(it->mPackage)->save(esm);
+                static_cast<const AiEscort&>(*it->mPackage).save(esm);
                 break;
             case Ai_Follow:
-                static_cast<const AiFollow*>(it->mPackage)->save(esm);
+                static_cast<const AiFollow&>(*it->mPackage).save(esm);
                 break;
             case Ai_Activate:
-                static_cast<const AiActivate*>(it->mPackage)->save(esm);
+                static_cast<const AiActivate&>(*it->mPackage).save(esm);
                 break;
             case Ai_Combat:
-                static_cast<const AiCombat*>(it->mPackage)->save(esm);
+                static_cast<const AiCombat&>(*it->mPackage).save(esm);
                 break;
             case Ai_Pursue:
-                static_cast<const AiPursue*>(it->mPackage)->save(esm);
+                static_cast<const AiPursue&>(*it->mPackage).save(esm);
                 break;
 
             default:
@@ -212,7 +206,7 @@ namespace AiSequence
             {
                 std::unique_ptr<AiWander> ptr = std::make_unique<AiWander>();
                 ptr->load(esm);
-                mPackages.back().mPackage = ptr.release();
+                mPackages.back().mPackage = std::move(ptr);
                 ++count;
                 break;
             }
@@ -220,7 +214,7 @@ namespace AiSequence
             {
                 std::unique_ptr<AiTravel> ptr = std::make_unique<AiTravel>();
                 ptr->load(esm);
-                mPackages.back().mPackage = ptr.release();
+                mPackages.back().mPackage = std::move(ptr);
                 ++count;
                 break;
             }
@@ -228,7 +222,7 @@ namespace AiSequence
             {
                 std::unique_ptr<AiEscort> ptr = std::make_unique<AiEscort>();
                 ptr->load(esm);
-                mPackages.back().mPackage = ptr.release();
+                mPackages.back().mPackage = std::move(ptr);
                 ++count;
                 break;
             }
@@ -236,7 +230,7 @@ namespace AiSequence
             {
                 std::unique_ptr<AiFollow> ptr = std::make_unique<AiFollow>();
                 ptr->load(esm);
-                mPackages.back().mPackage = ptr.release();
+                mPackages.back().mPackage = std::move(ptr);
                 ++count;
                 break;
             }
@@ -244,7 +238,7 @@ namespace AiSequence
             {
                 std::unique_ptr<AiActivate> ptr = std::make_unique<AiActivate>();
                 ptr->load(esm);
-                mPackages.back().mPackage = ptr.release();
+                mPackages.back().mPackage = std::move(ptr);
                 ++count;
                 break;
             }
@@ -252,14 +246,14 @@ namespace AiSequence
             {
                 std::unique_ptr<AiCombat> ptr = std::make_unique<AiCombat>();
                 ptr->load(esm);
-                mPackages.back().mPackage = ptr.release();
+                mPackages.back().mPackage = std::move(ptr);
                 break;
             }
             case Ai_Pursue:
             {
                 std::unique_ptr<AiPursue> ptr = std::make_unique<AiPursue>();
                 ptr->load(esm);
-                mPackages.back().mPackage = ptr.release();
+                mPackages.back().mPackage = std::move(ptr);
                 break;
             }
             default:
@@ -274,15 +268,15 @@ namespace AiSequence
             for(auto& pkg : mPackages)
             {
                 if(pkg.mType == Ai_Wander)
-                    static_cast<AiWander*>(pkg.mPackage)->mData.mShouldRepeat = true;
+                    static_cast<AiWander&>(*pkg.mPackage).mData.mShouldRepeat = true;
                 else if(pkg.mType == Ai_Travel)
-                    static_cast<AiTravel*>(pkg.mPackage)->mRepeat = true;
+                    static_cast<AiTravel&>(*pkg.mPackage).mRepeat = true;
                 else if(pkg.mType == Ai_Escort)
-                    static_cast<AiEscort*>(pkg.mPackage)->mRepeat = true;
+                    static_cast<AiEscort&>(*pkg.mPackage).mRepeat = true;
                 else if(pkg.mType == Ai_Follow)
-                    static_cast<AiFollow*>(pkg.mPackage)->mRepeat = true;
+                    static_cast<AiFollow&>(*pkg.mPackage).mRepeat = true;
                 else if(pkg.mType == Ai_Activate)
-                    static_cast<AiActivate*>(pkg.mPackage)->mRepeat = true;
+                    static_cast<AiActivate&>(*pkg.mPackage).mRepeat = true;
             }
         }
     }
diff --git a/components/esm3/aisequence.hpp b/components/esm3/aisequence.hpp
index b5a003678b..3dcecc1cb0 100644
--- a/components/esm3/aisequence.hpp
+++ b/components/esm3/aisequence.hpp
@@ -3,6 +3,7 @@
 
 #include <vector>
 #include <string>
+#include <memory>
 
 #include "components/esm/defs.hpp"
 
@@ -149,7 +150,7 @@ namespace ESM
     {
         int mType;
 
-        AiPackage* mPackage;
+        std::unique_ptr<AiPackage> mPackage;
     };
 
     struct AiSequence
@@ -158,7 +159,6 @@ namespace ESM
         {
             mLastAiPackage = -1;
         }
-        ~AiSequence();
 
         std::vector<AiPackageContainer> mPackages;
         int mLastAiPackage;