Project

ResourceManager 구성(2)

RuNaPi 2022. 6. 29. 11:25

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를 참고함

문제점

- 안전하지 않음 (임시 객체 관련하여 대입 문제가 많이 발생)

shader_ptr - msdn

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