How do I create functions based on user input?
I am currently working on a project and Arduino , which has the following general structure:
- User enters a command line through a terminal program such as CoolTerm
- Commands are sent to Arduino via USB Serial
- The first command is parsed along with the included arguments
- The function associated with the first command is being executed
- The second command is parsed along with the included arguments
- The function associated with the second command is being executed
- Etc. until all commands have been parsed and executed
So far, this all works as I expected. However, the project I'm working on requires very precise timing and the need to parse each individual command creates a significant amount of processing time (not sure if that's the right term) between each command execution.
For example, on a user input line that contains three commands, there is an additional 5.8 milliseconds of processing time from start to finish between the first command processed and the last command executed.
To be clear, all parts of my program are functional, including user input, string parsing, and function execution as described above. I need to improve my existing code, not fix bugs.
Ideally, I assume that the program will parse each command, "defer" the function associated with that command, and execute all commands in sequence once they are all "deferred". This will significantly reduce processing time by eliminating the need to continue parsing commands between each function execution. I am not sure how to do this, or if it is possible.
To illustrate my ideas in very basic C ++ pseudocode:
(assuming user input is "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();
}
Question:
I need a way to create a function based on user input or based on another function. I have never heard of such a concept thanks to the extensive research I have done and I am not sure if it exists. If possible, this is the method I would like to use to proceed with my project, as I believe it will require minimal restructuring of my code.
Edit:
This project requires compatibility with Arduino hardware and the Arduino IDE. Standard C ++ won't work.
source to share
You can use Command Template .
Basically, make your parser place a different command object for each user login to some kind of queue. The basic functional object can be used for this:
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 */ }
};
The parser will create either FirstCommand
, or SecondCommand
, and store them in std::queue<Command*>
or something more complex. Then your consumer code will execute each command by doing something like:
while (!q.empty() {
Command* command = q.front();
(*command)();
q.pop();
}
On thread safe queues, user code can be run in parallel with your parser.
You can use a queue of simple function pointers instead of command objects, but if you do, their signatures must be the same, and the constructor for a particular command can be arbitrary.
source to share
You can create a function map. Like this:
typedef void (*ftype)(void);
map<string, ftype> function_map;
Now you map all your functions to the command:
function_map["A"] = functionA;
function_map["B"] = functionB;
function_map["C"] = functionC;
Now, after user input and analysis, you can simply:
//foreach command
function_map[command]();
source to share
May be an alternative rather than an exact answer. Write a computer program that parses input and sends commands in binary over a serial port. This way serial reads (which is pretty slow even at 115200) and parsing will be prevented. As a bonus, your application has the ability to be more user-friendly than a terminal.
source to share