Resource Manager

CJB_ny·2022년 9월 7일
0

WinAPI

목록 보기
23/79
post-thumbnail

먼저 include 해준다 맵을

지금 해당 부분을 주석처리를 하면 에러가 뜨는데

using을 알아보도록 하자.

std

std

표준 라이브러리에 있는 함수들(기능들) std 라는 네임 스페이스 안에 포함되어 있다.

std::cout <<, std::cin >> 이런식으로 사용했는데 std::붙이기가 귀찮다.

그래서 우리는 using namespcae std;선언을 통해 std:: 안 붙여도 된다.


http://www.tcpschool.com/cpp/cpp_scope_namespace
**

우리는 성능을 위해서 using napescape std;로 모든 표준 라이브러리 다 쓰는게 아니라

딱 원하는 것만 사용하기 위해서

이렇게 명시적으로 잡아준 것이다.

LoadTexture

key값은 언제든지 ResourceManager로 부터 로드가 가능한 키값이다.

path는 '상대적인 경로'가 될 것이다.

상대적인 경로?

게임이 실제 존재하는 폴더 경로로 부터 '상대적인 경로'를 넣어줄 것이다.

상대적인 경로 이전에 있는 '절대적인 경로'는 PathManager가 해결해 줄 것이다.

이런식으로 += path를 해주어서 filePath를 PathManager를 통해 로드할 것이다.

생성자 부분

생성자에서 이제 이렇게 로드를 하는 것이 아니라

이렇게 LoadTextur함수를 호출을 하면은

ResourceManager의 맵에서는 해당 정보를 저장하고 있어야한다.

ResourceManager의 멤버 변수인 맵에 make_pair로 key, 와 로드가 완료된 객체를 넘겨주도록 한다.

그리고 Resources를 상속받은 Texture의 경로도 설정을 해주어야한다.

이렇게 해주는데 map에 동일한 키값이 있다면은??

동일한 키값있을 경우

FindTexture를 먼저 수행하고 있으면 주고 없으면 로딩해서 준다.

이게 지금 C# ObjectPooling이랑 개념이 똑같다 현재.

#region Pool
	class Pool
    {
        public GameObject Original { get; private set; }
        public Transform Root { get; set; }

        Stack<Poolable> _poolStack = new Stack<Poolable>();

        public void Init(GameObject original, int count = 100)
        {
            Original = original;
            Root = new GameObject().transform;
            Root.name = $"{original.name}_Root";

            for (int i = 0; i < count; i++)
                Push(Create());
        }

        Poolable Create()
        {
            GameObject go = Object.Instantiate<GameObject>(Original);
            go.name = Original.name;
            return go.GetOrAddComponent<Poolable>();
        }

        public void Push(Poolable poolable)
        {
            if (poolable == null)
                return;

            poolable.transform.parent = Root;
            poolable.gameObject.SetActive(false);
            poolable.IsUsing = false;

            _poolStack.Push(poolable);
        }

        public Poolable Pop(Transform parent)
        {
            Poolable poolable;

            if (_poolStack.Count > 0)
                poolable = _poolStack.Pop();
            else
                poolable = Create();

            poolable.gameObject.SetActive(true);

            // DontDestroyOnLoad 해제 용도
            if (parent == null)
                poolable.transform.parent = Managers.Scene.CurrentScene.transform;

            poolable.transform.parent = parent;
            poolable.IsUsing = true;

            return poolable;
        }
    }
	#endregion

	Dictionary<string, Pool> _pool = new Dictionary<string, Pool>();
    Transform _root;

    public void Init()
    {
        if (_root == null)
        {
            _root = new GameObject { name = "@Pool_Root" }.transform;
            Object.DontDestroyOnLoad(_root);
        }
    }

    public void CreatePool(GameObject original, int count = 100)
    {
        Pool pool = new Pool();
        pool.Init(original, count);
        pool.Root.parent = _root;

        _pool.Add(original.name, pool);
    }

    public void Push(Poolable poolable)
    {
        string name = poolable.gameObject.name;
        if (_pool.ContainsKey(name) == false)
        {
            GameObject.Destroy(poolable.gameObject);
            return;
        }

        _pool[name].Push(poolable);
    }

    public Poolable Pop(GameObject original, Transform parent = null)
    {
        if (_pool.ContainsKey(original.name) == false)
            CreatePool(original);

        return _pool[original.name].Pop(parent);
    }

    public GameObject GetOriginal(string name)
    {
        if (_pool.ContainsKey(name) == false)
            return null;
        return _pool[name].Original;
    }

    // 이거는 컨텐츠 영역이다.
    public void Clear()
    {
        foreach (Transform child in _root)
            GameObject.Destroy(child.gameObject);

        _pool.Clear();
    }
}

현재 맵 대신 딕셔너리 사용해서 딕셔너리가 키값으로 문자열, value값으로 클래스를 물고있는 형태이다.

메모리 해제

이렇게 텍스쳐들을 리소스 매니저에서 관리를 하니까 이런 메모리 해제도 리소스 매니저가 해야한다.

현재로써는 memory leak을 체크할 방법이 없다

(C++11 스마트 포인터 사용하면 되기는 한다.)

일단 main.cpp 이부분에 메모리 릭 부분 체크를 해주도록 하겠다.

https://docs.microsoft.com/ko-kr/visualstudio/debugger/finding-memory-leaks-using-the-crt-library?view=vs-2022

CRT 라이브러리로 메모리 누수 찾기 씹가능!

_crtBreakAlloc

new int 해버리면 그냥 정수형 임시객체 동적할당 해버리고 끝나버림.

4바이트 낭비됨. => 이런거 잡아준다는 것이다.

Player의 소멸자에서도 자기 자신을 delete한다는 것도 문제이다.

다른데서 사용할 수도 있기 때문에 없어져야함.


algorithm 사용하기

Fuctor사용하거나 함수포인터 사용하자.

메모리 누수

지금 215라 되어있는데

지금 내가 안 지운 부분 엄청나게 많다.

그럴때 번호를 이렇게 넣어준다.

생성자 private

public -> private으로 바꿔 준다.

아무데서나 생성못함.

그리고 친구선언 하면 ResourceManager에서만 Texture의 멤버 변수에 접근이 가능하다.

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글