ResoureManager
문제점
- 매번 Resource를 쓰는곳에서 ReleaseRef를 호출해주어야함
bool ReleaseRef()
{
	m_RefCnt--;
	cout << "ReleaseRef : " << m_Name << " RefCnt : " << m_RefCnt << '\n';
	if (m_RefCnt == 0)
	{
		Release();
		return true;
	}
	return false;
}
ResourcePtr
- Comptr 처럼 변수 라이프 사이클에 따라 ReleaseRef를 해주는 기능 필요
- shared_ptr를 참고함
문제점
- 안전하지 않음 (임시 객체 관련하여 대입 문제가 많이 발생)
template<class Resource>
class ResourcePTR
{
	static_assert(std::is_base_of<ResourceBase, Resource>::value, "Error : 리소스 타입 포인터가 아닙니다.");
public:
	ResourcePTR() {}
	ResourcePTR(_In_opt_ Resource* ptr) throw() : m_Ptr(ptr)
	{
		InternalAddRef();
	}
	~ResourcePTR()
	{
		InternalRelease();
	}
private:
	Resource* m_Ptr = nullptr;
public:
	Resource* Get() const noexcept
	{
		return m_Ptr;
	}
	Resource* const* GetAddressOf() const noexcept
	{
		return &m_Ptr;
	}
	Resource** GetAddressOf() noexcept
	{
		return &m_Ptr;
	}
	void InternalAddRef() const noexcept
	{
		if (m_Ptr != nullptr)
		{
			m_Ptr->AddRef();
		}
	}
	bool InternalRelease() noexcept
	{
		bool ret = false;
		if (m_Ptr != nullptr)
		{
			ret = m_Ptr->ReleaseRef();
		}
		return ret;
	}
	Resource* operator->() const throw()
	{
		return m_Ptr;
	}
};
- ResourceManager에서 리소스를 가지고올때 ResourcePtr<Resource> 를 반환 시킴
class ResourceManager
{
public:
	ResourceManager() {}
	~ResourceManager() {}
public:
	std::unordered_map<std::string, ResourceBase*> m_ResourceMap;
public:
	ResourceBase* LoadResource(std::string name)
	{
		if (m_ResourceMap.find(name) != m_ResourceMap.end())
			return nullptr;
		ResourceBase* newR = new ResourceBase(name);
		m_ResourceMap.insert(make_pair(name, newR));
		return newR;
	}
	ResourcePTR<ResourceBase> GetResource(std::string name)
	{
		auto r = m_ResourceMap.find(name);
		ResourceBase* ret = nullptr;
		if (r != m_ResourceMap.end())
		{
			ret = r->second;
		}
		else
		{
			ret = LoadResource(name);
		}
		return ResourcePTR<ResourceBase>(ret);
	}
};
int main()
{
	ResourceManager manager;
	{
		ResourcePTR<ResourceBase> mesh11 = manager.GetResource("Mesh1");
		{
			{
				ResourcePTR<ResourceBase> mesh21 = manager.GetResource("Mesh2");
			}
			ResourcePTR<ResourceBase> mesh12 = manager.GetResource("Mesh1");
			ResourcePTR<ResourceBase> mesh13 = manager.GetResource("Mesh1");
		}
	}
	return 0;
}

- 라이프 사이클에 따라 RefCnt를 해줌
'Project' 카테고리의 다른 글
| Resource Manager 구성(1) (0) | 2022.06.28 | 
|---|