Repository: RetroAchievements/RAIntegration
Pull request #690 (2021-03-06 19:30:52)

hook up Sub Hits in the achievement editor


Patch:
diff --git a/rcheevos b/rcheevos
index 9af350e2..acd92bd0 160000
--- a/rcheevos
+++ b/rcheevos
@@ -1,1 +1,1 @@
-Subproject commit 9af350e2d54dd954070d01367b62c5da1e6e81f3
+Subproject commit acd92bd0470cc2d11041d79ef1d2b57dcf83bf26
diff --git a/src/RA_Core.cpp b/src/RA_Core.cpp
index 29f402ae..6408d846 100644
--- a/src/RA_Core.cpp
+++ b/src/RA_Core.cpp
@@ -118,6 +118,9 @@ API int CCONV _RA_Shutdown()
     // if _RA_Init wasn't called, the services won't have been registered, so there's nothing to shut down
     if (ra::services::ServiceLocator::Exists<ra::services::IThreadPool>())
     {
+        // detach any client-registered functions
+        _RA_InstallSharedFunctionsExt(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
+
         // notify the background threads as soon as possible so they start to wind down
         ra::services::ServiceLocator::GetMutable<ra::services::IThreadPool>().Shutdown(false);
 
diff --git a/src/ui/viewmodels/AssetListViewModel.cpp b/src/ui/viewmodels/AssetListViewModel.cpp
index e0a88939..0657842d 100644
--- a/src/ui/viewmodels/AssetListViewModel.cpp
+++ b/src/ui/viewmodels/AssetListViewModel.cpp
@@ -850,6 +850,8 @@ static std::wstring ValidateCondSet(const rc_condset_t* pCondSet)
             return L"ResetNextIf is pre-release functionality";
         if (pCondition->type == RC_CONDITION_TRIGGER)
             return L"Trigger is pre-release functionality";
+        if (pCondition->type == RC_CONDITION_SUB_HITS)
+            return L"Trigger is pre-release functionality";
         if (pCondition->oper == RC_OPERATOR_MULT)
             return L"Multiplication is pre-release functionality";
         if (pCondition->oper == RC_OPERATOR_DIV)
diff --git a/src/ui/viewmodels/TriggerConditionViewModel.cpp b/src/ui/viewmodels/TriggerConditionViewModel.cpp
index 0f92506a..c7974a78 100644
--- a/src/ui/viewmodels/TriggerConditionViewModel.cpp
+++ b/src/ui/viewmodels/TriggerConditionViewModel.cpp
@@ -48,6 +48,7 @@ void TriggerConditionViewModel::SerializeAppend(std::string& sBuffer) const
             case TriggerConditionType::AddSource:   sBuffer.push_back('A'); break;
             case TriggerConditionType::SubSource:   sBuffer.push_back('B'); break;
             case TriggerConditionType::AddHits:     sBuffer.push_back('C'); break;
+            case TriggerConditionType::SubHits:     sBuffer.push_back('D'); break;
             case TriggerConditionType::AndNext:     sBuffer.push_back('N'); break;
             case TriggerConditionType::OrNext:      sBuffer.push_back('O'); break;
             case TriggerConditionType::Measured:    sBuffer.push_back('M'); break;
diff --git a/src/ui/viewmodels/TriggerConditionViewModel.hh b/src/ui/viewmodels/TriggerConditionViewModel.hh
index 40a5aa23..d7e931c2 100644
--- a/src/ui/viewmodels/TriggerConditionViewModel.hh
+++ b/src/ui/viewmodels/TriggerConditionViewModel.hh
@@ -22,6 +22,7 @@ enum class TriggerConditionType : uint8_t
     AddSource = RC_CONDITION_ADD_SOURCE,
     SubSource = RC_CONDITION_SUB_SOURCE,
     AddHits = RC_CONDITION_ADD_HITS,
+    SubHits = RC_CONDITION_SUB_HITS,
     AndNext = RC_CONDITION_AND_NEXT,
     Measured = RC_CONDITION_MEASURED,
     AddAddress = RC_CONDITION_ADD_ADDRESS,
diff --git a/src/ui/viewmodels/TriggerViewModel.cpp b/src/ui/viewmodels/TriggerViewModel.cpp
index 203398df..05da5ae3 100644
--- a/src/ui/viewmodels/TriggerViewModel.cpp
+++ b/src/ui/viewmodels/TriggerViewModel.cpp
@@ -30,6 +30,7 @@ TriggerViewModel::TriggerViewModel() noexcept
     m_vConditionTypes.Add(ra::etoi(TriggerConditionType::AddSource), L"Add Source");
     m_vConditionTypes.Add(ra::etoi(TriggerConditionType::SubSource), L"Sub Source");
     m_vConditionTypes.Add(ra::etoi(TriggerConditionType::AddHits), L"Add Hits");
+    m_vConditionTypes.Add(ra::etoi(TriggerConditionType::SubHits), L"Sub Hits");
     m_vConditionTypes.Add(ra::etoi(TriggerConditionType::AddAddress), L"Add Address");
     m_vConditionTypes.Add(ra::etoi(TriggerConditionType::AndNext), L"And Next");
     m_vConditionTypes.Add(ra::etoi(TriggerConditionType::OrNext), L"Or Next");


Test patch:
diff --git a/tests/ui/viewmodels/TriggerConditionAsserts.hh b/tests/ui/viewmodels/TriggerConditionAsserts.hh
index d56344bb..a28974c7 100644
--- a/tests/ui/viewmodels/TriggerConditionAsserts.hh
+++ b/tests/ui/viewmodels/TriggerConditionAsserts.hh
@@ -31,6 +31,8 @@ std::wstring ToString<ra::ui::viewmodels::TriggerConditionType>(
             return L"SubSource";
         case ra::ui::viewmodels::TriggerConditionType::AddHits:
             return L"AddHits";
+        case ra::ui::viewmodels::TriggerConditionType::SubHits:
+            return L"SubHits";
         case ra::ui::viewmodels::TriggerConditionType::AndNext:
             return L"AndNext";
         case ra::ui::viewmodels::TriggerConditionType::Measured:
diff --git a/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp b/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp
index 202319b3..31c70149 100644
--- a/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp
+++ b/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp
@@ -267,6 +267,10 @@ public:
         Assert::AreEqual(TriggerConditionType::ResetIf, vmCondition.GetType());
         Assert::IsTrue(vmCondition.HasHits());
 
+        vmCondition.SetType(TriggerConditionType::SubHits);
+        Assert::AreEqual(TriggerConditionType::SubHits, vmCondition.GetType());
+        Assert::IsTrue(vmCondition.HasHits());
+
         vmCondition.SetType(TriggerConditionType::SubSource);
         Assert::AreEqual(TriggerConditionType::SubSource, vmCondition.GetType());
         Assert::IsFalse(vmCondition.HasHits());
@@ -327,6 +331,7 @@ public:
         ParseAndRegenerate("A:0xH1234"); // add source
         ParseAndRegenerate("B:0xH1234"); // sub source
         ParseAndRegenerate("C:0xH1234=5"); // add hits
+        ParseAndRegenerate("D:0xH1234=5"); // sub hits
         ParseAndRegenerate("N:0xH1234=5"); // and next
         ParseAndRegenerate("O:0xH1234=5"); // or next
         ParseAndRegenerate("M:0xH1234=5"); // measured
@@ -442,6 +447,9 @@ public:
         condition.SetType(TriggerConditionType::Standard);
         Assert::IsFalse(condition.IsModifying());
 
+        condition.SetType(TriggerConditionType::SubHits);
+        Assert::IsFalse(condition.IsModifying());
+
         condition.SetType(TriggerConditionType::SubSource);
         Assert::IsTrue(condition.IsModifying());
 
diff --git a/tests/ui/viewmodels/TriggerViewModel_Tests.cpp b/tests/ui/viewmodels/TriggerViewModel_Tests.cpp
index 3c2829e7..5bf85f2d 100644
--- a/tests/ui/viewmodels/TriggerViewModel_Tests.cpp
+++ b/tests/ui/viewmodels/TriggerViewModel_Tests.cpp
@@ -97,7 +97,7 @@ public:
         Assert::AreEqual({ 0U }, vmTrigger.Groups().Count());
         Assert::AreEqual(std::string(), vmTrigger.Serialize());
 
-        Assert::AreEqual({ 13U }, vmTrigger.ConditionTypes().Count());
+        Assert::AreEqual({ 14U }, vmTrigger.ConditionTypes().Count());
         Assert::AreEqual((int)TriggerConditionType::Standard, vmTrigger.ConditionTypes().GetItemAt(0)->GetId());
         Assert::AreEqual(std::wstring(L""), vmTrigger.ConditionTypes().GetItemAt(0)->GetLabel());
         Assert::AreEqual((int)TriggerConditionType::PauseIf, vmTrigger.ConditionTypes().GetItemAt(1)->GetId());
@@ -112,18 +112,20 @@ public:
         Assert::AreEqual(std::wstring(L"Sub Source"), vmTrigger.ConditionTypes().GetItemAt(5)->GetLabel());
         Assert::AreEqual((int)TriggerConditionType::AddHits, vmTrigger.ConditionTypes().GetItemAt(6)->GetId());
         Assert::AreEqual(std::wstring(L"Add Hits"), vmTrigger.ConditionTypes().GetItemAt(6)->GetLabel());
-        Assert::AreEqual((int)TriggerConditionType::AddAddress, vmTrigger.ConditionTypes().GetItemAt(7)->GetId());
-        Assert::AreEqual(std::wstring(L"Add Address"), vmTrigger.ConditionTypes().GetItemAt(7)->GetLabel());
-        Assert::AreEqual((int)TriggerConditionType::AndNext, vmTrigger.ConditionTypes().GetItemAt(8)->GetId());
-        Assert::AreEqual(std::wstring(L"And Next"), vmTrigger.ConditionTypes().GetItemAt(8)->GetLabel());
-        Assert::AreEqual((int)TriggerConditionType::OrNext, vmTrigger.ConditionTypes().GetItemAt(9)->GetId());
-        Assert::AreEqual(std::wstring(L"Or Next"), vmTrigger.ConditionTypes().GetItemAt(9)->GetLabel());
-        Assert::AreEqual((int)TriggerConditionType::Measured, vmTrigger.ConditionTypes().GetItemAt(10)->GetId());
-        Assert::AreEqual(std::wstring(L"Measured"), vmTrigger.ConditionTypes().GetItemAt(10)->GetLabel());
-        Assert::AreEqual((int)TriggerConditionType::MeasuredIf, vmTrigger.ConditionTypes().GetItemAt(11)->GetId());
-        Assert::AreEqual(std::wstring(L"Measured If"), vmTrigger.ConditionTypes().GetItemAt(11)->GetLabel());
-        Assert::AreEqual((int)TriggerConditionType::Trigger, vmTrigger.ConditionTypes().GetItemAt(12)->GetId());
-        Assert::AreEqual(std::wstring(L"Trigger"), vmTrigger.ConditionTypes().GetItemAt(12)->GetLabel());
+        Assert::AreEqual((int)TriggerConditionType::SubHits, vmTrigger.ConditionTypes().GetItemAt(7)->GetId());
+        Assert::AreEqual(std::wstring(L"Sub Hits"), vmTrigger.ConditionTypes().GetItemAt(7)->GetLabel());
+        Assert::AreEqual((int)TriggerConditionType::AddAddress, vmTrigger.ConditionTypes().GetItemAt(8)->GetId());
+        Assert::AreEqual(std::wstring(L"Add Address"), vmTrigger.ConditionTypes().GetItemAt(8)->GetLabel());
+        Assert::AreEqual((int)TriggerConditionType::AndNext, vmTrigger.ConditionTypes().GetItemAt(9)->GetId());
+        Assert::AreEqual(std::wstring(L"And Next"), vmTrigger.ConditionTypes().GetItemAt(9)->GetLabel());
+        Assert::AreEqual((int)TriggerConditionType::OrNext, vmTrigger.ConditionTypes().GetItemAt(10)->GetId());
+        Assert::AreEqual(std::wstring(L"Or Next"), vmTrigger.ConditionTypes().GetItemAt(10)->GetLabel());
+        Assert::AreEqual((int)TriggerConditionType::Measured, vmTrigger.ConditionTypes().GetItemAt(11)->GetId());
+        Assert::AreEqual(std::wstring(L"Measured"), vmTrigger.ConditionTypes().GetItemAt(11)->GetLabel());
+        Assert::AreEqual((int)TriggerConditionType::MeasuredIf, vmTrigger.ConditionTypes().GetItemAt(12)->GetId());
+        Assert::AreEqual(std::wstring(L"Measured If"), vmTrigger.ConditionTypes().GetItemAt(12)->GetLabel());
+        Assert::AreEqual((int)TriggerConditionType::Trigger, vmTrigger.ConditionTypes().GetItemAt(13)->GetId());
+        Assert::AreEqual(std::wstring(L"Trigger"), vmTrigger.ConditionTypes().GetItemAt(13)->GetLabel());
 
         Assert::AreEqual({ 5U }, vmTrigger.OperandTypes().Count());
         Assert::AreEqual((int)TriggerOperandType::Address, vmTrigger.OperandTypes().GetItemAt(0)->GetId());