121 lines
3.5 KiB
C++
121 lines
3.5 KiB
C++
#ifndef PARAHELPER_H
|
||
#define PARAHELPER_H
|
||
|
||
/**
|
||
* \file ParaHelper.h
|
||
*
|
||
* \brief 定义一些帮助设置参数用的结构体,如\ref sParaRange
|
||
*
|
||
**/
|
||
|
||
#include "_nlohmann_json_wrapper.h"
|
||
#include "StringHelper.h"
|
||
#include "ParaHelper_core.h"
|
||
|
||
/** @addtogroup ksjson
|
||
* @{
|
||
* @addtogroup ParaHelper
|
||
* @brief 定义sParaRange结构体,用于设置参数的缺省值、最小值、最大值,已经步进值,小数位数等属性。
|
||
* @{ */
|
||
|
||
#ifndef ConstExpr
|
||
/// 需要在一个类/结构体内部定义静态常量表达示时,
|
||
/// 将"static constexpr auto"简写为ConstExpr
|
||
#define ConstExpr static constexpr const auto
|
||
#endif
|
||
|
||
/// 给变量添加注释的宏。
|
||
/// var是变量
|
||
/// str1、str2是变量含义和详细描述。
|
||
/// 只支持const wchar_t*类型的字符串,方便在UI显示。
|
||
#define ParaComment(var, str1, str2) \
|
||
ConstExpr var##_title = str1; \
|
||
ConstExpr var##_descr = str2;
|
||
|
||
static inline std::string combine_strs(const wchar_t* s1, const wchar_t* s2)
|
||
{
|
||
if (wcslen(s2))
|
||
return utf16_8(std::wstring(s1) + L": " + s2);
|
||
else
|
||
return utf16_8(s1);
|
||
}
|
||
|
||
// 变量转json并附加注释,适用于可以直接转json的变量
|
||
#define TO_JSON_COMMENT(j, name, var) \
|
||
j[#name##"?"] = combine_strs(var##_title, var##_descr); \
|
||
j[#name] = var;
|
||
|
||
// wstring型变量转json并附加注释
|
||
#define TO_JSON_COMMENT_WSTR(j, name, var) \
|
||
j[#name##"?"] = combine_strs(var##_title, var##_descr); \
|
||
j[#name] = utf16_8(var);
|
||
|
||
// wstring型vector变量转json并附加注释
|
||
#define TO_JSON_COMMENT_WSTRVECTOR(j, name, var) {\
|
||
j[#name##"?"] = combine_strs(var##_title, var##_descr); \
|
||
jsonobj jarr=jsonobj::array(); \
|
||
for(auto& s : var) jarr.push_back(utf16_8(s)); \
|
||
j[#name] = jarr; \
|
||
}
|
||
|
||
// 类转json并附加注释,适合自定义了to_json()函数的类或结构体
|
||
#define TO_JSON_COMMENT_CLASS(j, name, var) \
|
||
j[#name##"?"] = combine_strs(var##_title, var##_descr); \
|
||
to_json(j[#name], var);
|
||
|
||
/// sParaRange -> json
|
||
template <typename T>
|
||
void to_json(jsonobj& j, const sParaRange<T> & p) {
|
||
j["def"] = p.Def;
|
||
j["min"] = p.Min;
|
||
j["max"] = p.Max;
|
||
j["step"] = p.Step;
|
||
if(typeid (T) == typeid (float) || typeid (T) == typeid (double)){
|
||
//浮点型才保存Decimal
|
||
j["decimal"] = p.Decimal;
|
||
}
|
||
}
|
||
|
||
|
||
/// json -> sParaRange
|
||
/// 手写的json文件有两种格式:
|
||
/// 一种每一项用key:value单独设置,必须存在def,min,max;
|
||
/// 一种写成数组,必须存在3项。
|
||
/// 程序写的json见to_json()
|
||
template <typename T>
|
||
void from_json(const jsonobj& j, sParaRange<T>& p) {
|
||
if(!j.is_array()){ //key:value方式单独设置各项
|
||
//注意:def, min, max 必须存在,要不然这会抛异常的!
|
||
j["def" ].get_to<T>(p.Def);
|
||
j["min" ].get_to<T>(p.Min);
|
||
j["max" ].get_to<T>(p.Max);
|
||
|
||
// 判断step是否存在再读
|
||
auto it = j.find("step");
|
||
if(it!=j.end()) it->get_to<T>(p.Step);
|
||
|
||
// 判断decimal是否存在再读
|
||
it = j.find("decimal");
|
||
if(it!=j.end()) it->get_to<int>(p.Decimal);
|
||
}else{
|
||
//至少要有三项。TODO: 如何报错?
|
||
int size = int(j.size());
|
||
if(size<3) return;
|
||
j[0].get_to<T>(p.Def);
|
||
j[1].get_to<T>(p.Min);
|
||
j[2].get_to<T>(p.Max);
|
||
|
||
//有4项则读step
|
||
if(size >= 4) j[3].get_to<T>(p.Step);
|
||
|
||
//有5项则读decimal
|
||
if(size >= 5) p.Decimal = int(j[4].get<T>());
|
||
}
|
||
}
|
||
|
||
|
||
/** @} ParaHelper */
|
||
/** @} ksjson */
|
||
|
||
#endif // PARAHELPER_H
|