c++ 表格配置加载方案

c++ 表格配置加载方案

C/C++ 其它杂项

详细介绍

dawn-info

c++ 表格配置加载方案

1. 说明

  • 策划表格配置数据加载解决方案
  • 支持配置文件格式(json, csv, xls), xls待支持
  • 基本步骤
1. 配置表格(xls), 配置表头结构
2. 根据使用方式,转换成对应的数据文件(xls不需要,csv, json需要)
3. json需要对应工具生成,csv直接导出csv格式即可
4. 使用工具info_code工具生成对应的代码,根据需求修改
5. 使用新生成的配置INFO代码管理配置数据

2. 构建

cd dawn-info;
mkdir packages;
cd packages; git clone https://github.com/gejingguo/dawn-base.git
cd dawn-fino; 
mkdir build
cd build
cmake ..
make -j4

3. 使用

3.1. CSV,XLS格式规范
  • 表头使用3行标识,至少3行
  • 第一行,字段名称,英文,最好跟代码字段变量名称相同,方便自动生成代码模版
  • 第二行,字段类型,目前支持(Int, String)
  • 第三行,字段标记,可以标记客户端,服务器使用,以及是否是Key(client|server|key)
  • key最多支持3个字段,类型必须是Int

  • 实例如下

petId name level
Int String Int
server#client#key server#client server#client
宠物编号 名称 等级
1001 "熊猫宝宝" 1
1002 黄金游龙 2
3.2. JSON格式规范
  • 格式跟CSV不同,都是有效数据,没有无效列(需要工具转换xls生成)
  • 有头部结构标识字段原始信息

  • 实例如下

{
  "header": [
    {
      "name": "id",
      "flag": "key",
      "type": "Int"
    },
    {
      "name": "name",
      "flag": "",
      "type": "String"
    },
    {
      "name": "level",
      "flag": "",
      "type": "Int"
    }
  ],
  "rows": [
    {
      "id": 1001,
      "name": "熊抱宝宝",
      "level": 1
    },
    {
      "id": 1002,
      "name": "幼龙",
      "level": 2
    }
  ]
}
3.3. 编写对应的代码
  • 可以手写,也可以通过工具自动生成代码
  • 选择修改生成代码,提交
  • 代码模版如下
#ifndef __PetInfo__
#define __PetInfo__


#include "InfoRecord.h"
#include "InfoMgr.h"
#include <string>
#include <sstream>

struct PetInfo {
    int id = 0;
    std::string name;
    int level = 0;

    InfoKey GetKey()const {
        return InfoKey(id);
    }

    ErrorPtr Load(const InfoRecord& record) {
        ErrorPtr err = NULL;
        err = record.GetIntField(this->id, "id");
        CHECK_ERROR(err);
        err = record.GetStringField(this->name, "name");
        CHECK_ERROR(err);
        err = record.GetIntField(this->level, "level");
        CHECK_ERROR(err);

        return NULL;
    }

    std::string GetMsg()const {
        std::ostringstream oss;
        oss<<"("<<"id:"<<this->id<<","<<"name:"<<this->name<<","<<"level:"<<this->level<<")";
        return oss.str();
    }

    ErrorPtr Check() {
        // todo...;
        return NULL;
    }
};
#endif
3.4. 代码生成工具
  • 根据配置文件,生成代码
  • 使用方式
//info_code data_file file_type(json/csv) target_class target_file
./info_code ../test/petinfo.csv csv PetInfo ../test/PetInfo.h
3.5. 代码使用
InfoMgr<PetInfo>& petMgr = InfoMgr<PetInfo>::Instance();

    auto err = petMgr.Init(provider);
    if(err) {
        std::cerr<<"petinfo init failed, err:"<<err->GetCode()<<", msg:"<<err->GetMsg()<<std::endl;
        return err->GetCode();
    }

    int count = petMgr.GetCount();
    for(int i = 0; i < count; ++i) {
        const PetInfo* info = petMgr.GetByIndex(i);
        if(info != NULL) {
            std::cout<<"info "<<i<<":\n"<<info->GetMsg()<<std::endl;
        }
    }
    std::cout<<std::endl;

    const PetInfo* info = petMgr.GetById(1001);
    if(info == NULL) {
        std::cerr<<"info 1001 not found."<<std::endl;
        return -1;
    }
    //assert(info1 != NULL);
    //assert(info1->id == 1001);
    //assert(info1->name == "")
    std::cout<<"info:\n"<<info->GetMsg()<<std::endl;
    std::cout<<std::endl;

    info = petMgr.GetById(1003);
    if(info != NULL) {
        std::cerr<<"info 1003 found.."<<std::endl;
        return -1;
    }

    InfoHandle handle;
    handle.key.id1 = 1002;
    info = petMgr.GetByHandle(handle);
    if(info == NULL) {
        std::cerr<<"info 1002 not found."<<std::endl;
        return -1;
    }