내일배움캠프 48일차 TIL : DataManager, Reflection

woollim·2024년 11월 29일
0

내일배움캠프TIL

목록 보기
41/65
post-thumbnail

■ 개요

오늘 계획

  • 오전 내 할일
    • DataManager 완성


■ DataManager

○ DataManager 내부 함수

  • Json 파일을 역직렬화 하는 함수 제작
/// <summary>
/// JSON 파일을 역직렬화 한 후 리스트에 저장시키는 함수입니다.
/// </summary>
/// <typeparam name="T1">매니저의 데이터 베이스</typeparam>
/// <typeparam name="T2">리스트의 자료형 데이터 클래스</typeparam>
public void LoadGameData<T1, T2>()
{
    string typeName = typeof(T2).ToString();
    // Json 데이터 파일 이름을 데이터 클래스로 부터 추출

    var json = Resources.Load<TextAsset>("JsonFiles/" + typeName.Replace("Data", "")).text;
    // 스크립트 이름 뒤 "Data" 제거, Data만 제거하면 둘이 이름 같음, 경로에서 json 파일 로드

    List<T2> data = JsonHelper.FromJson<T2>(json);
    // 역직렬화한 리스트 데이터
    // 이 데이터 리스트를 게임데이터 베이스의 필드에 초기화 해줘야댐

    // TODO : 제네릭 두개 써서 이프문 없애기

    // 게임데이터 베이스의 필드중 해당되는 것을 찾고 리스트 데이터를 필드에 초기화
    if (typeof(T1).ToString() == "GameDataBase")
        GetFieldFormatConvert<GameDataBase, T2>(typeName + "s", GameDataBase, data);
    else if(typeof(T1).ToString() == "PlayerDataBase")
        GetFieldFormatConvert<PlayerDataBase, T2>(typeName + "s", PlayerDataBase, data);
}

/// <summary>
/// 매개변수로 전달되는 필드 이름과 일치하는 데이터베이스 필드를 찾아 리스트 데이터값을 전달합니다. 이때 필드 형식이 딕셔너리이면 딕셔너리 형태로 변환 하는 함수입니다.
/// </summary>
/// <typeparam name="T1">매니저의 데이터 베이스</typeparam>
/// <typeparam name="T2">필드 리스트의 데이터 클래스</typeparam>
/// <param name="fieldName">데이터베이스의 필드 이름</param>
/// <param name="dataBase">매니저의 데이터 베이스</param>
/// <param name="data">데이터베이스의 필드에 들어갈 리스트</param>
public void GetFieldFormatConvert<T1, T2>(string fieldName, T1 dataBase, List<T2> data)
{
    var fieldInfo = typeof(T1).GetField(fieldName, BindingFlags.Public | BindingFlags.Instance);
    // dataBase 타입의 객체에서 fieldName과 필드이름이 일치하는 것 가져오기
    // 필드가 퍼블릭과 인스턴스여야함 (static은안댐)
    // 해당 필드 정보를 저장

    string fieldTypeName = fieldInfo.GetValue(dataBase).GetType().Name; 
    // 필드 정보를 이용해서 해당 데이터베이스 객체에서 값을 가져오고 타입 이름을 스트링에 저장
    // 데이터베이스 필드의 타입 이름 가져오기
    if (fieldTypeName.StartsWith("List")) // 타입이름이 List로 시작하면
    {
        fieldInfo.SetValue(dataBase, data); // 필드를 data 리스트로 초기화
    }
    else if (fieldTypeName.StartsWith("Dictionary")) // 타입이름이 Dictionary로 시작하면
    {
        // 딕셔너리로 변환
        var dictionary = new Dictionary<int, T2>(); // 딕셔너리로 변환된 데이터를 담을 임시그릇

        foreach (var item in data)
        {
            // 딕셔너리의 고유아이디는 _ID 고정
            // 리스트에서 _ID 란 이름을 가진 필드의 데이터를 가져와서 키에 저장
            int key = (int)item.GetType().GetField("_ID").GetValue(item);

            dictionary[key] = item; // 키에 해당 리스트 넘버의 데이터를 저장
        }

        fieldInfo.SetValue(dataBase, dictionary); // 필드에 변환된 딕셔너리 대입
    }
}

○ JsonHelper

  • Json파일을 리스트 형태로 역직렬화함
public static class JsonHelper
{
    /// <summary>
    /// 제네릭 타입을 이용하여 Json 역직렬화를 할 수 있는 함수 입니다.
    /// </summary>
    /// <typeparam name="T">타입</typeparam>
    /// <param name="json">Json 데이터</param>
    /// <returns>해당 제네릭 타입으로 역직렬화된 배열을 반환합니다.</returns>
    public static List<T> FromJson<T>(string json)
    {
        Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
        return wrapper.datas;
    }
    
    [Serializable]
	private class Wrapper<T>
	{
    	public List<T> datas;
	}
}

0개의 댓글