我目前正在开发一个软件和Arduino的组合项目,该项目具有以下总体结构:
- 用户通过CoolTerm等终端程序输入一串命令
- 命令通过USB串口发送给Arduino
- 第一个命令连同包含的参数被解析
- 执行与第一个命令关联的函数
- 第二个命令连同包含的参数被解析
- 执行与第二个命令关联的函数
- 等等直到所有命令都被解析和执行
到目前为止,所有这些都按我预期的那样工作。但是,我正在从事的项目需要非常精确的时间安排,并且必须解析每个单独的命令会在每个命令执行之间产生相当长的处理时间(不确定这是不是正确的术语)。
例如,在包含三个命令的用户输入字符串中,从第一个命令被解析到最后一个命令被执行,从开始到结束有额外的 5.8 毫秒处理时间。
明确地说,我的程序的所有部分都是函数式的,包括用户输入、字符串解析和函数执行,如上所述。我需要改进我现有的代码,而不是纠正错误。
理想情况下,我认为程序将解析每个命令,“搁置”与命令关联的函数,并在所有命令都“搁置”后按顺序执行所有命令。通过消除在每个函数执行之间继续解析命令的需要,这将显着缩短处理时间。我不确定如何完成此操作,或者是否有可能。
用非常基本的 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++ 将不起作用。
最佳答案
你可以使用 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();
}
使用线程安全队列,消费者代码甚至可以与您的解析器并行运行。
您可以使用指向函数的简单指针队列而不是命令对象,但如果这样做,它们的签名必须相同,而特定命令的构造函数可以是任意的。
关于c - 如何根据用户输入创建函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31881095/