如何根据用户输入创建函数?
How do I create functions based on user input?
我目前正在开发 software 和 Arduino 的组合项目,该项目具有以下总体结构:
- 用户通过 CoolTerm 等终端程序输入一串命令
- 命令通过USB串口发送给Arduino
- 第一个命令连同包含的参数一起被解析
- 执行与第一个命令关联的函数
- 第二个命令连同包含的参数一起被解析
- 执行与第二个命令关联的函数
- 等直到所有命令都被解析和执行
到目前为止,所有这些都按照我的预期工作。但是,我正在从事的项目需要非常精确的时间安排,并且必须解析每个单独的命令会在每个命令之间产生大量的处理时间(不确定这是不是正确的术语)执行。
例如,在包含三个命令的用户输入字符串中,从第一个命令被解析到最后一个命令被执行,从开始到结束有额外的 5.8 毫秒处理时间。
需要说明的是,我的程序的所有部分都是函数式的, 包括用户输入、字符串解析和函数执行,如上所述。我需要改进我现有的代码,而不是纠正错误。
理想情况下,我设想程序将解析每个命令,"set aside" 与命令关联的函数,并在所有命令都被执行后按顺序执行所有命令"set aside." 这将缩短通过摆脱在每个函数执行之间继续解析命令的需要,显着处理时间。我不确定如何完成此操作,或者是否有可能。
用非常基本的 C++ 伪代码来说明我的想法:
(假设示例用户输入为 "A, B, C")
loop() {
// Example user input received: "A, B, C" corresponds to:
// functionA, functionB, functionC
String userInput = receiveInput();
// Parse user input
parse(userInput);
// Execute functions specified by user input
executeFunctions();
}
/*Parsing separates "A, B, C" to functionA, functionB, functionC
Functions are "set aside" to be executed sequentially,
the next beginning directly after the last ends*/
executeFunctions{
// Example functions to be executed
functionA();
functionB();
functionC();
}
问题:
我需要一种方法来创建基于用户输入或基于另一个函数的函数。通过我所做的广泛研究,我从未听说过这样的概念,我不确定它是否存在。如果可能的话,这是我想用来继续我的项目的方法,因为我相信它需要对我的代码进行最少的重构。
编辑:
此项目需要与 Arduino 硬件和 Arduino IDE 兼容。 标准 C++ 将不起作用。
您可以创建功能映射。像这样:
typedef void (*ftype)(void);
map<string, ftype> function_map;
现在您将所有函数映射到一个命令:
function_map["A"] = functionA;
function_map["B"] = functionB;
function_map["C"] = functionC;
现在在你接受用户输入并解析它之后,你可以这样做:
//foreach command
function_map[command]();
你可以使用 Command Pattern.
基本上,让您的解析器为每个用户输入将不同的命令对象放入某种队列中。您可以为此使用基本函数对象:
struct Command {
virtual ~Command() {}
virtual void operator()(); // this will execute the command
};
class FirstCommand : public Command {
// some private data + constructor
public:
virtual void operator()() { /* do stuff for this user input */ }
};
class SecondCommand : public Command {
// some private data + constructor
public:
virtual void operator()() { /* do stuff for this user input */ }
};
解析器会创建 FirstCommand
或 SecondCommand
,并将它们存储在 std::queue<Command*>
或更复杂的东西中。然后,您的消费者代码将通过执行以下操作来执行每个命令:
while (!q.empty() {
Command* command = q.front();
(*command)();
q.pop();
}
使用线程安全队列,消费者代码甚至可以 运行 与您的解析器并行。
您可以使用指向函数的简单指针队列而不是命令对象,但如果这样做,它们的签名必须相同,而特定命令的构造函数可以是任意的。
可能是另一种选择,而不是确切的答案。 编写一个计算机程序来解析输入并通过串行以二进制形式发送命令。这样就可以避免串行读取(即使在 115200 时也很慢)和解析。作为奖励,与终端相比,您的应用程序可能更加用户友好。
我目前正在开发 software 和 Arduino 的组合项目,该项目具有以下总体结构:
- 用户通过 CoolTerm 等终端程序输入一串命令
- 命令通过USB串口发送给Arduino
- 第一个命令连同包含的参数一起被解析
- 执行与第一个命令关联的函数
- 第二个命令连同包含的参数一起被解析
- 执行与第二个命令关联的函数
- 等直到所有命令都被解析和执行
到目前为止,所有这些都按照我的预期工作。但是,我正在从事的项目需要非常精确的时间安排,并且必须解析每个单独的命令会在每个命令之间产生大量的处理时间(不确定这是不是正确的术语)执行。
例如,在包含三个命令的用户输入字符串中,从第一个命令被解析到最后一个命令被执行,从开始到结束有额外的 5.8 毫秒处理时间。
需要说明的是,我的程序的所有部分都是函数式的, 包括用户输入、字符串解析和函数执行,如上所述。我需要改进我现有的代码,而不是纠正错误。
理想情况下,我设想程序将解析每个命令,"set aside" 与命令关联的函数,并在所有命令都被执行后按顺序执行所有命令"set aside." 这将缩短通过摆脱在每个函数执行之间继续解析命令的需要,显着处理时间。我不确定如何完成此操作,或者是否有可能。
用非常基本的 C++ 伪代码来说明我的想法:
(假设示例用户输入为 "A, B, C")
loop() {
// Example user input received: "A, B, C" corresponds to:
// functionA, functionB, functionC
String userInput = receiveInput();
// Parse user input
parse(userInput);
// Execute functions specified by user input
executeFunctions();
}
/*Parsing separates "A, B, C" to functionA, functionB, functionC
Functions are "set aside" to be executed sequentially,
the next beginning directly after the last ends*/
executeFunctions{
// Example functions to be executed
functionA();
functionB();
functionC();
}
问题:
我需要一种方法来创建基于用户输入或基于另一个函数的函数。通过我所做的广泛研究,我从未听说过这样的概念,我不确定它是否存在。如果可能的话,这是我想用来继续我的项目的方法,因为我相信它需要对我的代码进行最少的重构。
编辑:
此项目需要与 Arduino 硬件和 Arduino IDE 兼容。 标准 C++ 将不起作用。
您可以创建功能映射。像这样:
typedef void (*ftype)(void);
map<string, ftype> function_map;
现在您将所有函数映射到一个命令:
function_map["A"] = functionA;
function_map["B"] = functionB;
function_map["C"] = functionC;
现在在你接受用户输入并解析它之后,你可以这样做:
//foreach command
function_map[command]();
你可以使用 Command Pattern.
基本上,让您的解析器为每个用户输入将不同的命令对象放入某种队列中。您可以为此使用基本函数对象:
struct Command {
virtual ~Command() {}
virtual void operator()(); // this will execute the command
};
class FirstCommand : public Command {
// some private data + constructor
public:
virtual void operator()() { /* do stuff for this user input */ }
};
class SecondCommand : public Command {
// some private data + constructor
public:
virtual void operator()() { /* do stuff for this user input */ }
};
解析器会创建 FirstCommand
或 SecondCommand
,并将它们存储在 std::queue<Command*>
或更复杂的东西中。然后,您的消费者代码将通过执行以下操作来执行每个命令:
while (!q.empty() {
Command* command = q.front();
(*command)();
q.pop();
}
使用线程安全队列,消费者代码甚至可以 运行 与您的解析器并行。
您可以使用指向函数的简单指针队列而不是命令对象,但如果这样做,它们的签名必须相同,而特定命令的构造函数可以是任意的。
可能是另一种选择,而不是确切的答案。 编写一个计算机程序来解析输入并通过串行以二进制形式发送命令。这样就可以避免串行读取(即使在 115200 时也很慢)和解析。作为奖励,与终端相比,您的应用程序可能更加用户友好。