-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCommandLineInterface.cpp
121 lines (100 loc) · 4.8 KB
/
CommandLineInterface.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "CommandLineInterface.h"
CommandLineInterface::CommandLineInterface(void *work_data, void (*startingAction)()) {
processing_struct = work_data;
m_current_node_ID = SpecialNodeStatements::primal_executable_node;
m_main_frame = startingAction;
}
void CommandLineInterface::addCommand(int new_node_ID,
int executable_node_ID,
const std::string & syntax,
void(*commandRealization)(void*, const std::vector<std::string>&)){
CommandPool.insert({syntax, Command(new_node_ID, executable_node_ID, commandRealization)});
}
void CommandLineInterface::commandPolling() {
std::string console_input, current_command, arg;
std::map<std::string, Command> LocalCommandPool;
std::map<std::string, Command> ElderLocalCommandPool;
m_current_node_ID = primal_executable_node;
while (true) {
try {
if(m_current_node_ID == SpecialNodeStatements::final_executable_node){
return;
}
Args = std::vector<std::string>();
LocalCommandPool.clear();
ElderLocalCommandPool.clear();
if(m_current_node_ID == primal_executable_node)
m_main_frame();
console_input = std::string();
current_command = std::string();
arg = std::string();
std::getline(std::cin, console_input);
console_input.push_back(' ');
// input parser
for (bool break_symbol = false; auto e: console_input) {
if ((e == '\n' || e == ' ') && break_symbol) {
Args.emplace_back(arg);
arg = std::string();
continue;
}
if (e == ' ') { break_symbol = true; continue;}
if (!break_symbol) current_command.push_back(e);
else {
arg.push_back(e);
}
}
for(auto const &e : CommandPool){
if(e.second.executable_node_ID == m_current_node_ID
|| e.second.executable_node_ID == SpecialNodeStatements::any_executable_node)
LocalCommandPool.insert(e);
}
if(current_command == "help" && Args.empty()){
for(auto const &e : LocalCommandPool){
std::cout << e.first << '\t';
}
std::cout << std::endl;
continue;
}
for(auto const &e : CommandPool){
if(e.second.new_node_ID == m_current_node_ID)
ElderLocalCommandPool.insert(e);
}
if(!LocalCommandPool.contains(current_command)){
Args = std::vector<std::string>();
LocalCommandPool.clear();
throw std::invalid_argument("Нет такой команды");
}
auto executableStatement = LocalCommandPool.at(current_command);
if(executableStatement.new_node_ID == SpecialNodeStatements::previous_executable_node){
if(ElderLocalCommandPool.empty()) m_current_node_ID = final_executable_node;
for(auto const &e : ElderLocalCommandPool){
if(m_current_node_ID == primal_executable_node) {
m_current_node_ID = final_executable_node;
break;
}
if(e.second.new_node_ID == m_current_node_ID
&& e.second.new_node_ID != e.second.executable_node_ID
&& e.second.new_node_ID != SpecialNodeStatements::same_executable_node) {
executableStatement.callback(processing_struct,Args);
m_current_node_ID = e.second.executable_node_ID;
break;
}
throw std::invalid_argument("Предыдущая команда не найдена");
}
continue;
}
executableStatement.callback(processing_struct,Args);
if(executableStatement.new_node_ID != SpecialNodeStatements::same_executable_node)
m_current_node_ID = executableStatement.new_node_ID;
}
catch(std::exception& e){
std::cout << COMMAND_ERROR << e.what() << std::endl;
}
}
}
CommandLineInterface::Command::Command(int new_node_ID, int executable_node_ID,
void (*commandRealization)(void *, const std::vector<std::string> &)) {
this->new_node_ID = new_node_ID;
this->executable_node_ID = executable_node_ID;
this->callback = commandRealization;
}