분산 게임 서버 프레임 워 크 sframe (5) - 설정 관리

게임 서버 를 개발 하면 틀림없이 대량의 설정 데이터, 어떤 등급 설정, 관문 설정 등 이 있 을 것 이다.이러한 정적 데이터 에 대해 우 리 는 일반적으로 파일 방식 으로 저장 합 니 다.이 데이터 파일 을 미리 설정 하고 서버 가 시작 되면 메모리 에 불 러 와 설정 관리 모듈 에서 통일 적 으로 관리 할 계획 입 니 다.프로필 에 대해 서 는 CSV, JSON, XML, LUA 등 다양한 형식 이 유행 합 니 다.그러나 프로그램 에 있어 서 우 리 는 설정 파일 이 어떤 형식 을 사용 하 든 데 이 터 를 메모리 에 불 러 온 후에 똑 같은 존재 형식 이 되 기 를 바 랍 니 다.
         sframe 은 설정 파일 의 로드, 데이터 관리 기능 을 실현 하기 위해 설정 관리 체 제 를 제공 합 니 다.이것 은 설정 파일 을 분석 하고 설정 데 이 터 를 c + + 의 대상 에 비 추 는 것 을 책임 집 니 다.개발 자 에 게 우리 가 사용 하 는 데 이 터 는 모두 이 대상 에 있 습 니 다. 설정 파일 이 어떤 형식 인지 신경 쓰 지 않 아 도 됩 니 다.현재 json, csv 두 가지 형식의 파일 분석 과 로드 만 지원 합 니 다.
         sframe 의 설정 관리 와 관련 된 코드 는 모두 sframe / sfram / conf 디 렉 터 리 에 있 습 니 다.이 글 은 sframe 의 설정 관 리 를 어떻게 사용 하 는 지 에 중심 을 두 고 있 으 며, 그 실현 에 대해 서 는 일련의 c + 템 플 릿 사용 기법 이 며, 그 원리 에 대해 서 는 앞에서 말 한 직렬 화, 메시지 맵 과 차이 가 많 지 않다.앞에서 말 한 내용 을 이해 하고 배치 관리의 소스 코드 를 보면 이해 하기 쉬 울 것 이다.그래서 여 기 는 실현 을 말 하지 않 고 관심 있 는 학생 들 은 소스 코드 를 보면 충분 합 니 다.
프로필 불 러 오기
         sframe 은 json, csv 형식의 파일 을 분석 한 다음 에 데 이 터 를 c + + 대상 에 투사 할 수 있 습 니 다.sframe 설정 데 이 터 를 불 러 오 는 절 차 는 다음 과 같 습 니 다.
        ◆ 프로필 읽 기.
        ◆ 프로필 을 해석 합 니 다.파일 을 읽 은 후 파일 의 형식 을 해석 해 야 합 니 다.csv 형식 이 간단 하기 때문에 저 는 스스로 해석 알고리즘 을 써 서 파일 내용 을 sframe: Table 대상 으로 분 석 했 습 니 다.json 파일 의 해석, 나 는 github 의 json 11 (https://github.com/dropbox/json11)。이 라 이브 러 리 는 매우 간소화 되 어 하나의 헤더 파일 에 원본 파일 만 추가 되 고 대외 인터페이스 도 제 가 좋아 하 는 스타일 이기 때문에 직접 사용 합 니 다.파일 내용 을 분석 한 후 json 11:: JSon 대상 을 출력 합 니 다.
        ◆ 데 이 터 를 대상 에 투사 한다.분석 한 후에 데 이 터 를 대상 에 투사 해 야 합 니 다.그 후에 우리 가 직접 접촉 한 것 은 바로 이 대상 이 었 다. 더 이상 구체 적 인 문서 와 는 무관 하 다.
        위의 세 단계 에서 설정 데이터 의 로드 가 완료 되 었 습 니 다.1, 2 단 계 는 모두 이해 하기 쉬 우 니 여 기 는 더 이상 말 하지 않 겠 다.다음은 세 번 째 단계 인 데 이 터 를 대상 에 비 추 는 것 이다.sframe 은 매 핑 기능 을 완성 하기 위해 비교적 편리 한 인 터 페 이 스 를 제공 합 니 다.json 과 csv 의 인터페이스 와 인용 해 야 할 헤더 파일 이 다 릅 니 다. 다음은 제 가 따로 설명 하 겠 습 니 다.
1.       json 데이터 가 c + + 대상 에 매 핑 됨
        헤더 파일 'conf / JSonReader. h' 를 참조 해 야 합 니 다.그리고 sframe:: ConfigLoader:: Load <: json > (json, obj) 을 호출 하면 json 11:: JSon 대상 의 데 이 터 를 obj 대상 에 비 추 는 것 을 완성 할 수 있 습 니 다.obj 는 모든 c + + 기본 형식, std:: string, std:: unordered 일 수 있 습 니 다.map、std::map、std::vector、std::list、std::set、std::unordered_set、std::shared_ptr, 그리고 상기 모든 유형의 배열.json 은 자신 에 게 몇 가지 데이터 형식 이 있 습 니 다. 이러한 데이터 형식 은 c + + 의 유형 과 대응 하 는 관 계 는 다음 표 와 같 습 니 다.
json 데이터 형식
 
C + + 데이터 형식
Bool、Number、String
 
bool, 임의의 수치 형식, std:: string
ARRAY
 
배열, std:: map, std:: unorderedmap、std::vector、std::list、std::set、std::unordered_set
OBJECT
 
std::map、std::unordered_map, 사용자 정의 구조 체
        여기 서 보충 설명 하고 자 하 는 것 은 JSON 의 OBJECT 가 c + + 의 사용자 정의 구조 체 대상 에 투사 되 고 구조 체 에 Fill () 구성원 함 수 를 정의 하여 채 워 야 한 다 는 것 이다.구체 적 인 뒷 설명.
        현재 예 를 들 어 JSON 데이터 {"name": "소명", "address": "} 이 있 습 니 다. 분석 한 후에 json 11:: JSon 의 대상 json 을 얻 었 습 니 다. std:: map <: string std:: string =" > obj 에 투사 하려 고 합 니 다.sframe:: ConfigLoader:: Load <: json > (json, obj) 을 직접 호출 하면 됩 니 다.
2.       csv 데이터 가 c + + 대상 에 매 핑 됨
        헤더 파일 'conf / TableReader. h' 를 참조 해 야 합 니 다.호출 방법 은 sframe:: ConfigLoader:: Load (tbl, obj) 입 니 다.
        다른 것 은 csv 는 전형 적 인 표 형식의 형식 이다.전체 시계 에 std:: unordered 를 비 출 수 있 습 니 다.map、std::map、std::vector、std::list、std::set、std::unordered_set, 그리고 상기 모든 유형의 std:: sharedptr。위의 모든 용기 의 value 는 사용자 정의 구조 체 여야 합 니 다.이 구조 체 들 은 충전 을 완성 하기 위해 Fill () 방법 을 제공 해 야 한다.
        Fill 함수 에서 표 안의 셀 을 대상 에 비 추 는 것 을 완성 해 야 합 니 다.단원 격 데 이 터 는 데이터 형식 이 없고 모두 string 입 니 다. 단원 격 데 이 터 를 대상 에 비 추 려 면 형식 을 정의 하고 문자열 을 해석 해 야 합 니 다.sframe 에서 기본 형식 을 제 공 했 습 니 다:
C + + 형식
격식.
std:: vecto, std:: list, 배열
v1 | v2 | v3 | v4
std::unordered_map、std::map
k1 \ # v1;k2#v2;k3#v3
수치
전환 요구 에 부합 하면 됩 니 다.
3.       실례 설명
(1)    단일 사용자 정의 구조 체 대상 에 설정 매 핑
        예 를 들 어 게임 을 개발 하려 면 우 리 는 각종 잡다 한 물건 을 배치 하기 위해 전체적인 배치 가 필요 하 다.프로그램 에서 그것 은 구조 체 대상 으로 나타난다.파일 형식 에 대해 서 는 json 만 지원 합 니 다.
        JSON 데이터:
{
    "num_field" : 10000,
    "str_field" : "xiaoming",
    "vec_field" : [1,2,3,4],
    "map_field" : {
        "1" : "str1",
        "2" : "str2",
        "3" : "str3",
        "4" : "str4"
    }
}
        구조 체 는 다음 과 같다.
struct GlobalConfig
{
    int num_field;
    std::string str_field;
    std::vector vec_field;
    std::map map_field;

    void Fill(const json11::Json & reader)
    {
        JSON_FILLFIELD(num_field);
        JSON_FILLFIELD(str_field);
        JSON_FILLFIELD(vec_field);
        JSON_FILLFIELD(map_field);
    }
};

Fill 함수 의 반환 값 도 bool 형식 일 수 있 으 며, 불 러 오 는 데 성공 했다 는 것 을 표시 합 니 다.JSON_FILLFIELD 는 매크로, JSONFILLFIELD (num field) 는 사실상 sframe:: JSonFillField(reader,”num_field” , this-> num_field);따라서 이 매크로 를 사용 하려 면 void Fill (const json 11:: JSon & reader) 함수 의 매개 변수 이름 은 reader 여야 하 며 이 구성원 의 변수 이름 은 파일 의 필드 이름 과 같 아야 합 니 다.프로필 을 불 러 오 는 코드:
bool LoadJson()
{
	std::string content;
	if (!sframe::FileHelper::ReadFile("global.json", content))
	{
		return false;
	}

	std::string err;
	json11::Json json = json11::Json::parse(content, err);
	if (!err.empty())
	{
		return false;
	}
	//   
	GlobalConfig global_conf;
	if (!sframe::ConfigLoader::Load(json, global_conf))
	{
		return false;
	}
	
	return true;
}
(2)    맵 에 설정 매 핑
        전역 설정 과 같은 설정 을 제외 하고 대부분의 경우 하나의 설정 파일 은 여러 항목 으로 나 뉘 어 있 습 니 다. c + 에 비 추 는 것 은 맵 이나 다른 용기 일 것 입 니 다. 여 기 는 맵 으로 만 예 를 들 수 있 습 니 다.이런 다목 적 에 대해 서 는 JSON 과 CSV 가 모두 지원 한다.예 를 들 어 우 리 는 영웅 등급 설정 이 필요 하 다.       JSON 을 사용 하면 데이터 파일 은:
{[
       {
        “level” : 1,                    //  
		“attk” : 100,                   //   
		“title” : [“  ”, “    ”]     //  
	},
	{
        “level” : 2,                    //  
		“attk” : 200,                   //   
		“title” : [“  ”, “    ”]     //  
	},
	{
        “level” : 3,                    //  
		“attk” : 300,                   //   
		“title” : [“  ”, “    ”]     //  
	}
]}

        CSV 를 사용 하면 데이터 파일 은:
사인 같은 거 쓸 수 있어 요.
 
 
level
attk
title
본 줄 에 주석 을 달다.
 
 
유형 (관찰 만 편리)
 
 
1
100
소 백 | 초급 전사
2
200
일반 | 중급 전사
3
300
대신 | 고급 전사
        구조 체:
struct LevelConfig
{
    KEY_FIELD(int32_t,level);

   int level;
    int attk;
    std::vector< std::string > title;

    void Fill(const json11::Json & reader)
    {
        JSON_FILLFIELD(level);
        JSON_FILLFIELD(attk);
        JSON_FILLFIELD(title);
    }

    void Fill(sframe::TableReader & reader)
    {
        TBL_FILLFIELD (level);
        TBL_FILLFIELD (attk);
        TBL_FILLFIELD (title);
    }
};

        그 중의 KEYFIELD 는 주로 이 구조 체 key 의 필드 를 지정 하고 map 의 key 로 사용 합 니 다.전개 란 키 를 얻 는 방법 을 정의 하 는 것 입 니 다. int 32t GetKey() const {return level;}
        설정 을 불 러 오 는 코드 는 다음 과 같 습 니 다. (CSV 형식 을 예 로 들 면)
bool LoadCsv()
{
    std::string content;
    if (!sframe::FileHelper::ReadFile("lv.csv", content))
    {
        return false;
    }

    sframe::Table tbl;
    if (!sframe::CSV::Parse(content, tbl))
    {
        return false;
    }

    if (tbl.GetRowCount() < 1)
    {
        return false;
    }

    //     
    int32_t column_count = tbl.GetColumnCount();
    for (int i = 0; i < column_count; i++)
    {
        tbl.GetColumn(i).SetName(tbl[0][i]);
    }

    //      ,        ,    
    tbl.RemoveRow(0);
    // TableReader
    sframe::TableReader reader(tbl);

    //   
    std::map lv_conf;
    if (!sframe::ConfigLoader::Load<:tablereader>(reader, lv_conf))
    {
        return false;
    }

    return true;
}

설정 관리
        실제 항목 에 서 는 프로필 이 많 습 니 다.따라서 모든 설정 을 집중 적 으로 분류 관리 하 는 것 이 필요 하 다.sframe 은 ConfigSet 클래스 를 제공 하여 모든 설정 을 통일 적 으로 불 러 오고 관리 합 니 다.그럼 어떻게 사용 하나 요?우 리 는 그래도 앞의 예 로 설명 한다.현재 위의 두 가지 설정 을 모두 ConfigSet 로 통일 적 인 로드 와 관 리 를 하려 고 합 니 다. GlobalConfig 는 JSON, LevelConfig 는 CSV 를 사용 합 니 다.우선, ConfigSet 의 관리 부 는 설정 모듈 입 니 다. 설정 모듈 을 정의 해 야 합 니 다. sframe 은 설정 모듈 을 설명 하 는 데 매크로 를 제공 합 니 다.다음 과 같다.
OBJ_CONFIG_MODULE(GlobalConfigModule, GlobalConfig, 1);  
MAP_CONFIG_MODULE(LevelConfigModule, int32_t, LevelConfig, 2);

        OBJ_CONFIG_MODULE 은 모듈 이름 이 GlobalConfigModule 이 고 설정 대상 은 GlobalConfig 의 대상 이 며 설정 ID 는 1 인 단일 대상 설정 모듈 을 설명 합 니 다.
        MAP_CONFIG_MODULE 은 LevelConfigModule 이라는 맵 형식의 설정 모듈 을 설명 합 니 다. 설정 대상 은 key 는 int 이 고 value 는 LevelConfig 대상 의 map 이 며 설정 ID 는 2 입 니 다.        사용 한 코드 는 다음 과 같 습 니 다:
sframe::ConfigSet conf_set;
conf_set.RegistConfig< JsonLoader, GlobalConfigModule >("global.json");   //       
conf_set.RegistConfig, LevelConfigModule >("level.csv");
std::vector vec_err_info; //     
conf_set->Load(“/data/conf”, &vec_err_info); //             

//         
std::shard_ptr global_conf = conf_set. GetConfigModule< GlobalConfigModule >();
//       
std::shard_ptr global_conf = conf_set. GetConfig< GlobalConfigModule >();
//         
std::shard_ptr global_conf = conf_set. GetConfigModule< LevelConfigModule >();
//       
std::shard_ptr> map_lv_conf = conf_set. GetConfig< LevelConfigModule >();
//         
std::shard_ptr lv_conf = conf_set. GetMapConfigItem(1);

        상기 기본 기능 을 제외 하고 sframe 의 설정 관리 모듈 은 다음 과 같은 기능 이 있 습 니 다. 
        (1)  설정 모듈 초기 화        어떤 때 는 설정 을 불 러 온 후에 추가 처리 가 필요 할 수도 있 습 니 다.sframe 은 이 기능 을 지원 하기 위해 초기 화 메커니즘 을 제공 합 니 다.이 때 우 리 는 스스로 설정 모듈 을 성명 해 야 한다.
struct GlobalConfigModule : public sframe::ObjectConfigModule  
{  
    void Initialize(sframe::ConfigSet & conf_set)  
    {  
        //Obj()    std::shared_ptr    
   }  
};  
  
struct LevelConfigModule : public sframe::MapConfigModule  
{  
    void Initialize(sframe::ConfigSet & conf_set)  
    {   
         //Obj()    std::shared_ptr<:map std::shared_ptr="">>    
     }
}; 

        Initialize 함수 도 bool 형식 으로 돌아 가 는 형식 을 지원 합 니 다. bool 로 돌아 가 려 면 void 를 bool 로 바 꾸 면 됩 니 다.ConfigSet 는 모든 설정 을 불 러 온 후 초기 화 함 수 를 호출 합 니 다.
        (2) 사용자 정의 용기 삽입 설정
        때때로 우 리 는 설정 을 불 러 온 후에 단순히 대상 을 용기 에 삽입 하 는 것 을 원 하지 않 을 수도 있다.대상 을 몇 개의 대상 으로 나 누 어 용기 에 저장 해 야 할 수도 있 습 니 다.혹은 우리 가 판단 을 해 야 용기 에 넣 을 수 있다.sframe 은 대상 을 용기 에 삽입 하 는 방법 을 사용자 정의 할 수 있 습 니 다.사용 하기 도 간단 합 니 다. 우 리 는 구조 체 에 PutIn 멤버 함 수 를 추가 하기 만 하면 됩 니 다.예 를 들 어 LevelConfig:
struct LevelConfig
{
	bool PutIn(std::map> & m)
	{
		m[level] = *this;
		return true;
}
}

         본 고 는 대략 을 말 하 였 으 니, 더 많은 내용 은 소스 코드 를 참고 하 시기 바 랍 니 다.

좋은 웹페이지 즐겨찾기