From 272054ec941e7e61ab60159288c0a7e549109d2a Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Fri, 11 Dec 2015 17:24:01 -0500
Subject: [PATCH] EXI_Device: Get rid of explicit delete and new

---
 Source/Core/Core/HW/EXI_Channel.cpp | 45 +++++++++++++----------------
 Source/Core/Core/HW/EXI_Channel.h   |  2 +-
 Source/Core/Core/HW/EXI_Device.cpp  | 26 +++++++++--------
 Source/Core/Core/HW/EXI_Device.h    |  3 +-
 4 files changed, 37 insertions(+), 39 deletions(-)

diff --git a/Source/Core/Core/HW/EXI_Channel.cpp b/Source/Core/Core/HW/EXI_Channel.cpp
index 1af7476566..627eaacc1c 100644
--- a/Source/Core/Core/HW/EXI_Channel.cpp
+++ b/Source/Core/Core/HW/EXI_Channel.cpp
@@ -2,6 +2,8 @@
 // Licensed under GPLv2+
 // Refer to the license.txt file included.
 
+#include <memory>
+
 #include "Common/ChunkFile.h"
 #include "Core/ConfigManager.h"
 #include "Core/CoreTiming.h"
@@ -35,7 +37,7 @@ CEXIChannel::CEXIChannel(u32 ChannelId) :
 		m_Status.CHIP_SELECT = 1;
 
 	for (auto& device : m_pDevices)
-		device.reset(EXIDevice_Create(EXIDEVICE_NONE, m_ChannelId));
+		device = EXIDevice_Create(EXIDEVICE_NONE, m_ChannelId);
 }
 
 CEXIChannel::~CEXIChannel()
@@ -166,18 +168,17 @@ void CEXIChannel::RemoveDevices()
 
 void CEXIChannel::AddDevice(const TEXIDevices device_type, const int device_num)
 {
-	IEXIDevice* pNewDevice = EXIDevice_Create(device_type, m_ChannelId);
-	AddDevice(pNewDevice, device_num);
+	AddDevice(EXIDevice_Create(device_type, m_ChannelId), device_num);
 }
 
-void CEXIChannel::AddDevice(IEXIDevice* pDevice, const int device_num, bool notifyPresenceChanged)
+void CEXIChannel::AddDevice(std::unique_ptr<IEXIDevice> device, const int device_num, bool notify_presence_changed)
 {
 	_dbg_assert_(EXPANSIONINTERFACE, device_num < NUM_DEVICES);
 
-	// replace it with the new one
-	m_pDevices[device_num].reset(pDevice);
+	// Replace it with the new one
+	m_pDevices[device_num] = std::move(device);
 
-	if (notifyPresenceChanged)
+	if (notify_presence_changed)
 	{
 		// This means "device presence changed", software has to check
 		// m_Status.EXT to see if it is now present or not
@@ -228,27 +229,21 @@ void CEXIChannel::DoState(PointerWrap &p)
 	p.Do(m_Control);
 	p.Do(m_ImmData);
 
-	for (int d = 0; d < NUM_DEVICES; ++d)
+	for (int device_index = 0; device_index < NUM_DEVICES; ++device_index)
 	{
-		IEXIDevice* pDevice = m_pDevices[d].get();
-		TEXIDevices type = pDevice->m_deviceType;
+		std::unique_ptr<IEXIDevice>& device = m_pDevices[device_index];
+		TEXIDevices type = device->m_deviceType;
 		p.Do(type);
-		IEXIDevice* pSaveDevice = (type == pDevice->m_deviceType) ? pDevice : EXIDevice_Create(type, m_ChannelId);
-		pSaveDevice->DoState(p);
-		if (pSaveDevice != pDevice)
+
+		if (type == device->m_deviceType)
 		{
-			// if we had to create a temporary device, discard it if we're not loading.
-			// also, if no movie is active, we'll assume the user wants to keep their current devices
-			// instead of the ones they had when the savestate was created,
-			// unless the device is NONE (since ChangeDevice sets that temporarily).
-			if (p.GetMode() != PointerWrap::MODE_READ)
-			{
-				delete pSaveDevice;
-			}
-			else
-			{
-				AddDevice(pSaveDevice, d, false);
-			}
+			device->DoState(p);
+		}
+		else
+		{
+			std::unique_ptr<IEXIDevice> save_device = EXIDevice_Create(type, m_ChannelId);
+			save_device->DoState(p);
+			AddDevice(std::move(save_device), device_index, false);
 		}
 	}
 }
diff --git a/Source/Core/Core/HW/EXI_Channel.h b/Source/Core/Core/HW/EXI_Channel.h
index 0a41053eaf..4a512852fe 100644
--- a/Source/Core/Core/HW/EXI_Channel.h
+++ b/Source/Core/Core/HW/EXI_Channel.h
@@ -97,7 +97,7 @@ public:
 	void SendTransferComplete();
 
 	void AddDevice(const TEXIDevices device_type, const int device_num);
-	void AddDevice(IEXIDevice* pDevice, const int device_num, bool notifyPresenceChanged = true);
+	void AddDevice(std::unique_ptr<IEXIDevice> device, const int device_num, bool notify_presence_changed = true);
 
 	// Remove all devices
 	void RemoveDevices();
diff --git a/Source/Core/Core/HW/EXI_Device.cpp b/Source/Core/Core/HW/EXI_Device.cpp
index 80fd585f36..4a660579e7 100644
--- a/Source/Core/Core/HW/EXI_Device.cpp
+++ b/Source/Core/Core/HW/EXI_Device.cpp
@@ -2,6 +2,8 @@
 // Licensed under GPLv2+
 // Refer to the license.txt file included.
 
+#include <memory>
+
 #include "Common/ChunkFile.h"
 #include "Core/ConfigManager.h"
 #include "Core/Core.h"
@@ -89,54 +91,54 @@ public:
 
 
 // F A C T O R Y
-IEXIDevice* EXIDevice_Create(TEXIDevices device_type, const int channel_num)
+std::unique_ptr<IEXIDevice> EXIDevice_Create(TEXIDevices device_type, const int channel_num)
 {
-	IEXIDevice* result = nullptr;
+	std::unique_ptr<IEXIDevice> result;
 
 	switch (device_type)
 	{
 	case EXIDEVICE_DUMMY:
-		result = new CEXIDummy("Dummy");
+		result = std::make_unique<CEXIDummy>("Dummy");
 		break;
 
 	case EXIDEVICE_MEMORYCARD:
 	case EXIDEVICE_MEMORYCARDFOLDER:
 	{
 		bool gci_folder = (device_type == EXIDEVICE_MEMORYCARDFOLDER);
-		result = new CEXIMemoryCard(channel_num, gci_folder);
+		result = std::make_unique<CEXIMemoryCard>(channel_num, gci_folder);
 		break;
 	}
 	case EXIDEVICE_MASKROM:
-		result = new CEXIIPL();
+		result = std::make_unique<CEXIIPL>();
 		break;
 
 	case EXIDEVICE_AD16:
-		result = new CEXIAD16();
+		result = std::make_unique<CEXIAD16>();
 		break;
 
 	case EXIDEVICE_MIC:
-		result = new CEXIMic(channel_num);
+		result = std::make_unique<CEXIMic>(channel_num);
 		break;
 
 	case EXIDEVICE_ETH:
-		result = new CEXIETHERNET();
+		result = std::make_unique<CEXIETHERNET>();
 		break;
 
 	case EXIDEVICE_AM_BASEBOARD:
-		result = new CEXIAMBaseboard();
+		result = std::make_unique<CEXIAMBaseboard>();
 		break;
 
 	case EXIDEVICE_GECKO:
-		result = new CEXIGecko();
+		result = std::make_unique<CEXIGecko>();
 		break;
 
 	case EXIDEVICE_AGP:
-		result = new CEXIAgp(channel_num);
+		result = std::make_unique<CEXIAgp>(channel_num);
 		break;
 
 	case EXIDEVICE_NONE:
 	default:
-		result = new IEXIDevice();
+		result = std::make_unique<IEXIDevice>();
 		break;
 	}
 
diff --git a/Source/Core/Core/HW/EXI_Device.h b/Source/Core/Core/HW/EXI_Device.h
index 4cc547f27f..156f49edac 100644
--- a/Source/Core/Core/HW/EXI_Device.h
+++ b/Source/Core/Core/HW/EXI_Device.h
@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include <memory>
 #include "Common/CommonTypes.h"
 
 class PointerWrap;
@@ -57,4 +58,4 @@ public:
 	TEXIDevices m_deviceType;
 };
 
-IEXIDevice* EXIDevice_Create(const TEXIDevices device_type, const int channel_num);
+std::unique_ptr<IEXIDevice> EXIDevice_Create(const TEXIDevices device_type, const int channel_num);