437 lines
13 KiB
C++
437 lines
13 KiB
C++
#ifndef FUNCTION_METADATA_H
|
|
#define FUNCTION_METADATA_H
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
#include <any>
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <algorithm>
|
|
#include <cctype>
|
|
#include <sstream> // 添加这行
|
|
|
|
// 参数类型枚举
|
|
enum class ParamType
|
|
{
|
|
INT,
|
|
FLOAT,
|
|
DOUBLE,
|
|
BOOL,
|
|
STRING,
|
|
INT_ARRAY,
|
|
FLOAT_ARRAY,
|
|
VOID_PTR,
|
|
UNKNOWN
|
|
};
|
|
|
|
// 参数信息结构
|
|
struct ParamInfo
|
|
{
|
|
std::string name;
|
|
ParamType type;
|
|
std::any default_value;
|
|
bool is_optional;
|
|
|
|
ParamInfo(const std::string &n, ParamType t, std::any dv = {}, bool opt = false)
|
|
: name(n), type(t), default_value(dv), is_optional(opt) {}
|
|
|
|
// 获取类型名称
|
|
std::string getTypeName() const
|
|
{
|
|
switch (type)
|
|
{
|
|
case ParamType::INT:
|
|
return "int";
|
|
case ParamType::FLOAT:
|
|
return "float";
|
|
case ParamType::DOUBLE:
|
|
return "double";
|
|
case ParamType::BOOL:
|
|
return "bool";
|
|
case ParamType::STRING:
|
|
return "string";
|
|
case ParamType::INT_ARRAY:
|
|
return "int[]";
|
|
case ParamType::FLOAT_ARRAY:
|
|
return "float[]";
|
|
case ParamType::VOID_PTR:
|
|
return "void*";
|
|
default:
|
|
return "unknown";
|
|
}
|
|
}
|
|
|
|
// 类型转换
|
|
template <typename T>
|
|
T convert(const std::any &value) const
|
|
{
|
|
try
|
|
{
|
|
if constexpr (std::is_same_v<T, int>)
|
|
{
|
|
if (value.type() == typeid(int))
|
|
return std::any_cast<int>(value);
|
|
if (value.type() == typeid(double))
|
|
return static_cast<int>(std::any_cast<double>(value));
|
|
if (value.type() == typeid(float))
|
|
return static_cast<int>(std::any_cast<float>(value));
|
|
if (value.type() == typeid(std::string))
|
|
{
|
|
try
|
|
{
|
|
return std::stoi(std::any_cast<std::string>(value));
|
|
}
|
|
catch (...)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
return std::any_cast<T>(value);
|
|
}
|
|
else if constexpr (std::is_same_v<T, float>)
|
|
{
|
|
if (value.type() == typeid(float))
|
|
return std::any_cast<float>(value);
|
|
if (value.type() == typeid(double))
|
|
return static_cast<float>(std::any_cast<double>(value));
|
|
if (value.type() == typeid(int))
|
|
return static_cast<float>(std::any_cast<int>(value));
|
|
if (value.type() == typeid(std::string))
|
|
{
|
|
try
|
|
{
|
|
return std::stof(std::any_cast<std::string>(value));
|
|
}
|
|
catch (...)
|
|
{
|
|
return 0.0f;
|
|
}
|
|
}
|
|
return std::any_cast<T>(value);
|
|
}
|
|
else if constexpr (std::is_same_v<T, std::string>)
|
|
{
|
|
if (value.type() == typeid(std::string))
|
|
return std::any_cast<std::string>(value);
|
|
// 其他类型转换为字符串
|
|
std::stringstream ss;
|
|
if (value.type() == typeid(int))
|
|
ss << std::any_cast<int>(value);
|
|
else if (value.type() == typeid(float))
|
|
ss << std::any_cast<float>(value);
|
|
else if (value.type() == typeid(double))
|
|
ss << std::any_cast<double>(value);
|
|
else if (value.type() == typeid(bool))
|
|
ss << (std::any_cast<bool>(value) ? "true" : "false");
|
|
else
|
|
return "";
|
|
return ss.str();
|
|
}
|
|
else if constexpr (std::is_same_v<T, bool>)
|
|
{
|
|
if (value.type() == typeid(bool))
|
|
return std::any_cast<bool>(value);
|
|
if (value.type() == typeid(int))
|
|
return std::any_cast<int>(value) != 0;
|
|
if (value.type() == typeid(std::string))
|
|
{
|
|
std::string str = std::any_cast<std::string>(value);
|
|
std::string lower_str = str;
|
|
std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(),
|
|
[](unsigned char c)
|
|
{ return std::tolower(c); });
|
|
return lower_str == "true" || lower_str == "1" || lower_str == "yes" || lower_str == "on";
|
|
}
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return std::any_cast<T>(value);
|
|
}
|
|
}
|
|
catch (const std::bad_any_cast &)
|
|
{
|
|
return T();
|
|
}
|
|
}
|
|
};
|
|
|
|
// 函数信息结构
|
|
struct FunctionInfo
|
|
{
|
|
std::string name;
|
|
std::string description;
|
|
std::vector<ParamInfo> params;
|
|
std::function<std::any(const std::vector<std::any> &)> handler;
|
|
|
|
// 参数名称映射,支持多个名称
|
|
std::map<std::string, std::string> param_aliases;
|
|
|
|
FunctionInfo(const std::string &n, const std::string &desc = "")
|
|
: name(n), description(desc) {}
|
|
|
|
// 添加参数
|
|
FunctionInfo &addParam(const std::string &name, ParamType type,
|
|
std::any default_value = {}, bool optional = false)
|
|
{
|
|
params.emplace_back(name, type, default_value, optional);
|
|
return *this;
|
|
}
|
|
|
|
// 添加参数别名
|
|
FunctionInfo &addAlias(const std::string &original, const std::vector<std::string> &aliases)
|
|
{
|
|
for (const auto &alias : aliases)
|
|
{
|
|
param_aliases[alias] = original;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
// 设置处理器
|
|
template <typename Func>
|
|
FunctionInfo &setHandler(Func &&func)
|
|
{
|
|
handler = std::forward<Func>(func);
|
|
return *this;
|
|
}
|
|
|
|
// 获取规范化的参数名
|
|
std::string getCanonicalName(const std::string &input_name) const
|
|
{
|
|
// 检查别名
|
|
auto it = param_aliases.find(input_name);
|
|
if (it != param_aliases.end())
|
|
{
|
|
return it->second;
|
|
}
|
|
|
|
// 检查直接匹配(大小写不敏感)
|
|
std::string lower_input = toLower(input_name);
|
|
|
|
for (const auto ¶m : params)
|
|
{
|
|
std::string lower_param = toLower(param.name);
|
|
|
|
if (lower_param == lower_input)
|
|
{
|
|
return param.name;
|
|
}
|
|
}
|
|
|
|
return input_name; // 如果没有找到,返回原名称
|
|
}
|
|
|
|
// 验证参数
|
|
bool validateParams(const std::map<std::string, std::any> &input_params,
|
|
std::string &error_msg) const
|
|
{
|
|
// 检查必需参数
|
|
for (const auto ¶m : params)
|
|
{
|
|
if (!param.is_optional)
|
|
{
|
|
bool found = false;
|
|
for (const auto &input : input_params)
|
|
{
|
|
if (getCanonicalName(input.first) == param.name)
|
|
{
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found)
|
|
{
|
|
error_msg = "Missing required parameter: " + param.name;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
static std::string toLower(const std::string &str)
|
|
{
|
|
std::string result = str;
|
|
std::transform(result.begin(), result.end(), result.begin(),
|
|
[](unsigned char c)
|
|
{ return ::towlower(c); });
|
|
return result;
|
|
}
|
|
};
|
|
|
|
// 函数注册表
|
|
class FunctionRegistry
|
|
{
|
|
private:
|
|
std::map<std::string, std::shared_ptr<FunctionInfo>> functions_;
|
|
|
|
FunctionRegistry() = default;
|
|
|
|
public:
|
|
static FunctionRegistry &instance()
|
|
{
|
|
static FunctionRegistry instance;
|
|
return instance;
|
|
}
|
|
|
|
// 禁止复制
|
|
FunctionRegistry(const FunctionRegistry &) = delete;
|
|
FunctionRegistry &operator=(const FunctionRegistry &) = delete;
|
|
|
|
// 注册函数
|
|
void registerFunction(const std::shared_ptr<FunctionInfo> &func_info)
|
|
{
|
|
functions_[func_info->name] = func_info;
|
|
}
|
|
|
|
// 获取函数
|
|
std::shared_ptr<FunctionInfo> getFunction(const std::string &name)
|
|
{
|
|
// 直接查找
|
|
auto it = functions_.find(name);
|
|
if (it != functions_.end())
|
|
{
|
|
return it->second;
|
|
}
|
|
|
|
// 大小写不敏感查找
|
|
std::string lower_name = toLower(name);
|
|
|
|
for (const auto &[func_name, func_info] : functions_)
|
|
{
|
|
std::string lower_func = toLower(func_name);
|
|
|
|
if (lower_func == lower_name)
|
|
{
|
|
return func_info;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// 获取所有函数
|
|
const std::map<std::string, std::shared_ptr<FunctionInfo>> &getAllFunctions() const
|
|
{
|
|
return functions_;
|
|
}
|
|
|
|
// 自动推导参数类型
|
|
ParamType deduceParamType(const std::any &value)
|
|
{
|
|
if (value.type() == typeid(int))
|
|
return ParamType::INT;
|
|
if (value.type() == typeid(float))
|
|
return ParamType::FLOAT;
|
|
if (value.type() == typeid(double))
|
|
return ParamType::DOUBLE;
|
|
if (value.type() == typeid(bool))
|
|
return ParamType::BOOL;
|
|
if (value.type() == typeid(std::string))
|
|
return ParamType::STRING;
|
|
if (value.type() == typeid(std::vector<int>))
|
|
return ParamType::INT_ARRAY;
|
|
if (value.type() == typeid(std::vector<float>))
|
|
return ParamType::FLOAT_ARRAY;
|
|
if (value.type() == typeid(void *))
|
|
return ParamType::VOID_PTR;
|
|
return ParamType::UNKNOWN;
|
|
}
|
|
|
|
// 智能参数匹配
|
|
std::map<std::string, std::any> smartMatchParams(
|
|
const std::shared_ptr<FunctionInfo> &func_info,
|
|
const std::map<std::string, std::any> &input_params)
|
|
{
|
|
std::map<std::string, std::any> matched_params;
|
|
|
|
// 1. 首先处理输入参数
|
|
for (const auto &[input_name, input_value] : input_params)
|
|
{
|
|
std::string canonical_name = func_info->getCanonicalName(input_name);
|
|
|
|
// 查找对应的参数定义
|
|
auto param_it = std::find_if(func_info->params.begin(), func_info->params.end(),
|
|
[&canonical_name](const ParamInfo ¶m)
|
|
{
|
|
return param.name == canonical_name;
|
|
});
|
|
|
|
if (param_it != func_info->params.end())
|
|
{
|
|
// 类型转换
|
|
std::any converted_value;
|
|
switch (param_it->type)
|
|
{
|
|
case ParamType::INT:
|
|
converted_value = param_it->convert<int>(input_value);
|
|
break;
|
|
case ParamType::FLOAT:
|
|
converted_value = param_it->convert<float>(input_value);
|
|
break;
|
|
case ParamType::STRING:
|
|
converted_value = param_it->convert<std::string>(input_value);
|
|
break;
|
|
case ParamType::BOOL:
|
|
converted_value = param_it->convert<bool>(input_value);
|
|
break;
|
|
default:
|
|
converted_value = input_value; // 保持原类型
|
|
}
|
|
matched_params[param_it->name] = converted_value;
|
|
}
|
|
}
|
|
|
|
// 2. 填充默认值
|
|
for (const auto ¶m : func_info->params)
|
|
{
|
|
if (matched_params.find(param.name) == matched_params.end())
|
|
{
|
|
if (!param.default_value.has_value() && !param.is_optional)
|
|
{
|
|
// 必需参数没有提供值,使用类型默认值
|
|
switch (param.type)
|
|
{
|
|
case ParamType::INT:
|
|
matched_params[param.name] = 0;
|
|
break;
|
|
case ParamType::FLOAT:
|
|
matched_params[param.name] = 0.0f;
|
|
break;
|
|
case ParamType::STRING:
|
|
matched_params[param.name] = std::string();
|
|
break;
|
|
case ParamType::BOOL:
|
|
matched_params[param.name] = false;
|
|
break;
|
|
default:
|
|
// 空值
|
|
break;
|
|
}
|
|
}
|
|
else if (param.default_value.has_value())
|
|
{
|
|
matched_params[param.name] = param.default_value;
|
|
}
|
|
}
|
|
}
|
|
|
|
return matched_params;
|
|
}
|
|
|
|
private:
|
|
static std::string toLower(const std::string &str)
|
|
{
|
|
std::string result = str;
|
|
std::transform(result.begin(), result.end(), result.begin(),
|
|
[](unsigned char c)
|
|
{ return ::towlower(c); });
|
|
return result;
|
|
}
|
|
};
|
|
|
|
#endif // FUNCTION_METADATA_H
|