我最近写了非常多的重复代码。我需要提出一个更好的解决方案。
至于我现在这样做(伪代码)
std::map<std::string/*commandname*/, commandfunction*> Commands;
void OnPlayerExecuteCommand(cplayer* player, std::string command, std::string parameters)
{
//find check blablabla yaddayadda then..
Commands[command]->execute(player, parameters);
}
//heal PlayerId/Name (float)amount
void Command_HealMe(cplayer* player, std::string parameters)
{
SomeParsingCodeA(params);//get the cplayer* from playername or id and float heal amount
}
//vehicle name color1 color2, eg /vehicle Ferrari 0xFF0000 123456
void Command_SpawnVehicle(cplayer* player, std::string parameters)
{
SomeParsingCodeB(params);//get the vehiclename, and colors
}
//kick playername/id reason, eg /kick player_a you are spamming the chat
void Command_KickSomeone(cplayer* player, std::string parameters)
{
SomeParsingCodeC(params);//get cplayer* of playername or id, and get the rest string
}
但是每个SomeParsingCode*
代码段都包含许多重复代码,例如IsValidPlayer(string)//returns Cplayer from id or name
,将字符串解析为数字或浮点数或其他任何内容。
我正在考虑通过创建通用解析函数来简化编写代码,例如:
auto result = ParseMyParameters("Player_string_or_int;int_or_hex;int_or_hex",input)
if(result.good()){ //continue
我在考虑将每个请求映射到一个字符,如:
character - expected input
u - PlayerName as String or PlayerID as integer(u as in user)
i - integer number
x - hex formatted number
f - real number
g - integer or hex
w - one worded string
r - return remaining string,
like /kick player_a you are spamming the chat
would be parsed with "ur", and the result would be a cplayer pointer and the string "you are spamming the chat"
然后创建一个循环字符串的函数,逐个解析所有请求的东西。
但我在想,C ++有很多好东西,我真的不知道在这种情况下使用什么,容器或boost / C ++包括哪些可用于此任务? C ++中有没有让我这样做的东西?建议采用什么方法?
另外,这可能需要一些可变参数,使用varargs或者我可以使用一些可变参数模板吗?像
ParseString<cplayer*,int,float,std::string>("Joe 5 5.0 hello my friend!");
与
std::string = "hello my friend!";
或
ParseString<cplayer*,int,float,std::vector<std::string>>("Joe 5 5.0 hello my friend!");
std::vector<std::string> = {"hello", "my", "friend!"};
答案 0 :(得分:0)
使用LEX(FLEX)或YACC(BISON)这种事情要容易得多。
您可以使用它们来定义命令并在遇到命令时提供操作。