游戏中读取物品,各种资源配置,用于各种配置

#ifndef _XLSX_CLASS_
#define _XLSX_CLASS_
/*
* 代码整理:
* 工作中实现的一个读取配置的工具,Any.hpp未提供
* 通过闭包擦除类型,让容器包罗万象
* 提供类型转换,得益于模板编译期特性因此拥有强大的纠错能力
* 框架之上,寸草不生,框架之下,芸芸众生;
*/
#include<string>
#include"../Auxiliary/Any.hpp"
//#include"../Auxiliary/Result.hpp"
#include<assert.h>
#include<map>
#include<vector>
#include<fstream>
#include<algorithm>
#include<vector>

struct ParseCls
{
    static bool isInMask(const int& index, const std::vector<std::pair<int, int> >& vec_mask)
    {
        for (auto& t : vec_mask)
        {
            if (index > t.first && index < t.second)
            {
                return true;
            }
        }
        return false;
    }

    static bool split_string(const std::string& str, const std::string& delim, std::vector<std::string>& vecret)
    {
        size_t start = 0;
        size_t index = str.find_first_of(delim, start);
        while (index != std::string::npos)
        {
            vecret.push_back(str.substr(start, index - start));
            start = index + 1;
            index = str.find_first_of(delim, start);
        }
        if (index - start > 0)
        {
            vecret.push_back(str.substr(start, index - start));
        }
        return true;
    }

    static bool split_value(const std::string& str, const std::string& delim, const std::string& startdelim, const std::string& enddelim, std::vector<std::string>& vecret)
    {
        std::vector<std::pair<int, int> > vec_mask;
        size_t mask_start = 0;
        size_t mask_index = 0;
        while (true)
        {
            mask_start = str.find_first_of(startdelim, mask_start);
            if (mask_start != std::string::npos)
            {
                mask_index = str.find_first_of(enddelim, mask_start + 1);
                if (mask_index == std::string::npos)
                {
                    std::cout << "err: split_value -> Missing match character  " << startdelim << std::endl;
                    assert(false);
                    //符号不匹配
                }
                vec_mask.push_back(std::make_pair(mask_start, mask_index));
                mask_start = mask_index + 1;
            }
            else
            {
                break;
            }
        }

        size_t start = 0;
        size_t index = str.find_first_of(delim, start);
        while (isInMask(index, vec_mask))
        {
            index = str.find_first_of(delim, index + 1);
        }
        while (index != std::string::npos)
        {
            vecret.push_back(str.substr(start, index - start));
            start = index + 1;
            index = str.find_first_of(delim, start);
            while (isInMask(index, vec_mask))
            {
                index = str.find_first_of(delim, index + 1);
            }
        }
        if (index - start > 0)
        {
            vecret.push_back(str.substr(start, index - start));
        }
        return true;
    }

    static bool inner_split_value(const std::string& str, const std::string& startdelim, const std::string& enddelim, std::vector<std::string>& vecret)
    {
        std::vector<std::pair<int, int> > vec_mask;
        size_t mask_start = 0;
        size_t mask_index = 0;
        while (true)
        {
            mask_start = str.find_first_of(startdelim, mask_start);
            if (mask_start != std::string::npos)
            {
                mask_index = str.find_first_of(enddelim, mask_start + 1);
                if (mask_index == std::string::npos)
                {
                    std::cout << "err: inner_split_value -> Missing match character  " << startdelim << std::endl;
                    assert(false);
                    //符号不匹配
                }
                vec_mask.push_back(std::make_pair(mask_start + 1, mask_index));
                mask_start = mask_index + 1;
            }
            else
            {
                break;
            }
        }
        for (auto& v : vec_mask)
        {
            vecret.push_back(str.substr(v.first, v.second - v.first));
        }
        return true;
    }
};

template<class T> 
struct DataType
{
    static Any value(const std::string& va)
    {
        std::cout << "err: Unsupported data type -> " << va << std::endl;
        assert(false);
        return Any();
    }
};

template<> struct DataType<int>
{
    static  Any value(const std::string& va)
    {
        return Any(std::stoi(va));
    }
};

template<> struct DataType<std::string>
{
    static Any value(const std::string& va)
    {
        return Any(va);
    }
};

template<> struct DataType<double>
{
    static Any value(const std::string& va)
    {
        return Any(std::stod(va));
    }
};
template<> struct DataType<float>
{
    static Any value(const std::string& va)
    {
        return Any(std::stof(va));
    }
};


template<> struct DataType<std::vector<std::vector<int> > >
{
    static Any value(const std::string& va)
    {
        std::vector<std::string>		vec_point_str;
        std::vector<std::vector<int> >	vec_point_value;
        if (ParseCls::inner_split_value(va, "{", "}", vec_point_str))
        {
            for (auto& vp : vec_point_str)
            {
                std::vector<std::string>	vec_value_str;
                std::vector<int>			vec_value;
                if (ParseCls::split_string(vp, ",", vec_value_str))
                {
                    for (auto& v : vec_value_str)
                    {
                        vec_value.push_back(std::stoi(v));
                    }
                    vec_point_value.push_back(vec_value);
                }
            }
            return Any(vec_point_value);
        }
        else
        {
            assert(false);
            return Any();
        }
    }
};
template<>
struct DataType<std::vector<std::vector<double> > >
{
    static Any value(const std::string& va)
    {
        std::vector<std::string>		vec_point_str;
        std::vector<std::vector<double> >	vec_point_value;
        if (ParseCls::inner_split_value(va, "{", "}", vec_point_str))
        {
            for (auto& vp : vec_point_str)
            {
                std::vector<std::string>	vec_value_str;
                std::vector<double>			vec_value;
                if (ParseCls::split_string(vp, ",", vec_value_str))
                {
                    for (auto& v : vec_value_str)
                    {
                        vec_value.push_back(std::stod(v));
                    }
                    vec_point_value.push_back(vec_value);
                }
            }
            return Any(vec_point_value);
        }
        else
        {
            assert(false);
            return Any();
        }
    }
};



class Object
{
private:
    int Parse(std::vector<std::string>& vecType, std::vector<std::string> vecVaribl,
        std::vector<std::string>& vec_value, std::map<std::string, Any>& map_varible)
    {
        int index = 0;
        int key = -1;
        for (auto& t : vecType)
        {
            if (t == "int")
            {
                map_varible.insert(std::make_pair(vecVaribl[index], DataType<int>::value(vec_value[index])));
            }
            else if (t == "string")
            {
                map_varible.insert(std::make_pair(vecVaribl[index], DataType<std::string>::value(vec_value[index])));
            }
            else if (t == "double")
            {
                map_varible.insert(std::make_pair(vecVaribl[index], DataType<double>::value(vec_value[index])));
            }
            else if (t == "float")
            {
                map_varible.insert(std::make_pair(vecVaribl[index], DataType<float>::value(vec_value[index])));
            }
            else if (t == "list<list<int>>")
            {
                map_varible.insert(std::make_pair(vecVaribl[index], DataType<std::vector<std::vector<int> > >::value(vec_value[index])));
            }
            else if (t == "vector<vector<int>>")
            {
                map_varible.insert(std::make_pair(vecVaribl[index], DataType<std::vector<std::vector<int> > >::value(vec_value[index])));
            }
            else if (t == "vector<vector<double>>")
            {
                map_varible.insert(std::make_pair(vecVaribl[index], DataType<std::vector<std::vector<double> > >::value(vec_value[index])));
            }
            else if (t == "list<list<double>>")
            {
                map_varible.insert(std::make_pair(vecVaribl[index], DataType<std::vector<std::vector<double> > >::value(vec_value[index])));
            }

            else
            {
                std::cout << "err: Unsupported data type -> " << t << std::endl;
                assert(false);
            }
            index++;
        }

        return map_varible["index"].AnyCast<int>();
    }
public:
    bool ParseType(const std::string& type)
    {
        ParseCls::split_string(type, ",", vecType);
        for (auto& v : vecType)
        {
            std::transform(v.begin(), v.end(), v.begin(), ::tolower);
        }

        return true;
    }
    bool ParseVriable(const std::string& varible)
    {
        ParseCls::split_string(varible, ",", vecVarible);
        return true;
    }
    bool ParseValue(const int& row, const std::string& value)
    {
        std::vector<std::string> vec_value;
        ParseCls::split_value(value, ",", "\"", "\"", vec_value);
        if (verifyValue(vec_value))
        {

            std::map<std::string, Any> vec_varible;
            int key = Parse(vecType, vecVarible, vec_value, vec_varible);
            vec_Value.insert(std::make_pair(key, vec_varible));
            rowkey.insert(std::make_pair(row,key));
            return true;
        }
        std::cout << "err->" << value.c_str() << std::endl;
        return false;
    }
    bool verifyValue(std::vector<std::string>& vec_value)
    {
        assert(vec_value.size() == vecType.size());
        assert(vecVarible.size() == vecType.size());
        for (auto& var : vec_value)
        {
            if (var.empty())
            {
                return false;
            }
        }
        return true;
    }
    template<class _Ty>
    _Ty& getValue(const int&id, const std::string& varName)
    {
        return (vec_Value[id])[varName].AnyCast<_Ty>();
    }

    template<class _Ty>
    _Ty& getValue(const int& row, const int& col)
    {
        return (vec_Value[rowkey[row]])[vecVarible[col]].AnyCast<_Ty>();
    }
    template<class _Ty>
    bool getWholeValueByColumu(std::vector<_Ty>& value,const std::string& varName)
    {
        for (auto& var : vec_Value)
        {
            value.push_back(var.second[varName].AnyCast<_Ty>());
        }
        return true;
    }
    template<class _Ty>
    bool getWholeValueByColumu(std::vector<_Ty>& value, const int& col)
    {
        const std::string& varname = vecVarible[col];
        for (auto& var : vec_Value)
        {
           value.push_back(var.second[varname].AnyCast<_Ty>());
        }
        return true;
    }
    size_t getRowCount()
    {
        return vec_Value.size();
    }
    size_t getColumuCount()
    {
        return vecVarible.size();
    }
private:
    std::vector<std::string> vecType;
    std::vector<std::string> vecVarible;
    std::map<int, std::map<std::string, Any> > vec_Value;
    std::map<int, int> rowkey;
};



class XlsxClass
{
public:
    bool registerClass(const std::string& clsName)
    {
        if (!_map_class.insert(std::map<std::string, std::shared_ptr<Object>>::value_type(clsName, std::shared_ptr<Object>(new Object()))).second)
        {
            std::cout << "err: registerClass Failed  -> " << clsName << "Maybe the category already exists " << std::endl;
            assert(false);
            return false;
        }
        return true;
    }
    std::shared_ptr<Object> operator[](const std::string& clsName)
    {
        std::shared_ptr<Object> p = _map_class[clsName];
        if (!p)
        {
            std::cout << "err: operator[] Failed  -> " << clsName << "Maybe the clsName does not exists " << std::endl;
            assert(false);
            return NULL;
        }
        return p;
    }
    void clear()
    {
        _map_class.clear();
    }
private:
    std::map<std::string, std::shared_ptr<Object> > _map_class;
};



class XlsxClassReader
{
public:
    void AddCsvFile(const std::string& ClassName, const std::string& file)
    {
        xls.registerClass(ClassName);
        std::ifstream    csvFile(file);
        std::shared_ptr<Object> ptrObj = xls[ClassName];
        if (!ptrObj)
        {
            std::cout << "err: AddCsvFile Failed  -> " << file.c_str() << std::endl;
            assert(false);
        }
        char  str[360];
        int index = 0;
        int row   = 3;
        while (csvFile.getline(str, 360))
        {
            std::string value(str);
            value.erase(std::remove(value.begin(), value.end(), ' '), value.end());
            value.erase(std::remove(value.begin(), value.end(), '	'), value.end());
            if (value.empty())
            {
                index++;
                continue;
            }
            if (index == 0)
            {
            }
            else if (index == 1)
            {
                xls[ClassName]->ParseVriable(value);
            }
            else if (index == 2)
            {
                xls[ClassName]->ParseType(value);
            }
            else
            {
                xls[ClassName]->ParseValue(row,value);
                row++;
            }
            index++;
        }
    }
public:
    template<typename _Ty>
    _Ty& getValue(const std::string& clsName, const int& objid, const std::string& varName)
    {
        return xls[clsName]->getValue<_Ty>(objid, varName);
    }
    template<typename _Ty>
    _Ty& getValue(const std::string& clsName, const int& row, const int& col)
    {
        return xls[clsName]->getValue<_Ty>(row + 3, col);
    }
    template<typename _Ty>
    void getWholeListListValueByColumu(const std::string& clsName, std::vector<_Ty>& value, const int& col)
    {
         xls[clsName]->getWholeValueByColumu<_Ty>(value, col);
        
    }
    template<typename _Ty>
    void getWholeListListValueByColumu(const std::string& clsName, std::vector<_Ty>& value, const std::string& varName)
    {
         xls[clsName]->getWholeValueByColumu<_Ty>(value, varName);
    }
    size_t getRowCount(const std::string& clsName)
    {
        return xls[clsName]->getRowCount();
    }
    size_t getColumuCount(const std::string& clsName)
    {
        return xls[clsName]->getColumuCount();
    }
private:
    XlsxClass			xls;
};





class SingleXlsxClass
{
public:
    bool registerClass(const std::string& clsName)
    {
        if (!_map_class.insert(std::map<std::string, std::shared_ptr<Object>>::value_type(clsName, std::shared_ptr<Object>(new Object()))).second)
        {
            std::cout << "err: registerClass Failed  -> " << clsName << "Maybe the category already exists " << std::endl;
            assert(false);
            return false;
        }
        return true;
    }
    std::shared_ptr<Object> operator[](const std::string& clsName)
    {
        std::shared_ptr<Object> p = _map_class[clsName];
        if (!p)
        {
            std::cout << "err: operator[] Failed  -> " << clsName << "Maybe the clsName does not exists " << std::endl;
            assert(false);
            return NULL;
        }
        return p;
    }
private:
    std::map<std::string, std::shared_ptr<Object> > _map_class;
};

class SingleXlsxClassReader
{
public:
    SingleXlsxClassReader()
    {
    }
    SingleXlsxClassReader(const std::string& file)
    {
        SetCsvFile(file);
    }
    void SetCsvFile(const std::string& file)
    {
        xls.clear();
        xls.registerClass("default");
        std::ifstream    csvFile(file);
        std::shared_ptr<Object> ptrObj = xls["default"];
        if (!ptrObj)
        {
            std::cout << "err: AddCsvFile Failed  -> " << file.c_str() << std::endl;
            assert(false);
        }
        char  str[360];
        int index = 0;
        int row = 3;
        while (csvFile.getline(str, 360))
        {
            std::string value(str);
            value.erase(std::remove(value.begin(), value.end(), ' '), value.end());
            value.erase(std::remove(value.begin(), value.end(), '	'), value.end());
            if (value.empty())
            {
                index++;
                continue;
            }
            if (index == 0)
            {
            }
            else if (index == 1)
            {
                xls["default"]->ParseVriable(value);
            }
            else if (index == 2)
            {
                xls["default"]->ParseType(value);
            }
            else
            {
                xls["default"]->ParseValue(row, value);
                row++;
            }
            index++;
        }
    }
public:
    template<typename _Ty>
    _Ty& getValue( const int& objid, const std::string& varName)
    {
        return xls["default"]->getValue<_Ty>(objid, varName);
    }
    template<typename _Ty>
    _Ty& getValue(const int& row, const int& col)
    {
        return xls["default"]->getValue<_Ty>(row + 3, col);
    }
    template<typename _Ty>
    void getWholeListListValueByColumu( std::vector<_Ty>& value, const int& col)
    {
        xls["default"]->getWholeValueByColumu<_Ty>(value, col);
    }
    template<typename _Ty>
    void getWholeListListValueByColumu(std::vector<_Ty>& value, const std::string& varName)
    {
        xls["default"]->getWholeValueByColumu<_Ty>(value, varName);
    }
    size_t getRowCount()
    {
        return xls["default"]->getRowCount();
    }
    size_t getColumuCount()
    {
        return xls["default"]->getColumuCount();
    }
private:
    XlsxClass			xls;
};



#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值