comparison dep/animia/src/player.cc @ 156:cdf79282d647

dep/animia: add VERY early x11 window stuff
author Paper <mrpapersonic@gmail.com>
date Wed, 15 Nov 2023 18:04:04 -0500
parents d8a61e7e2a36
children
comparison
equal deleted inserted replaced
155:d2bbb5773616 156:cdf79282d647
1 #include "animia/player.h"
2 #include "animia/util.h"
3
1 #include <map> 4 #include <map>
2 #include <sstream> 5 #include <sstream>
3 #include <string> 6 #include <string>
4 #include <vector> 7 #include <vector>
5
6 #include "animia/player.h"
7 #include "animia/util.h"
8 8
9 namespace animia { 9 namespace animia {
10 10
11 namespace internal::parser { 11 namespace internal::parser {
12 12
22 22
23 size_t GetIndentation(const std::string& line) { 23 size_t GetIndentation(const std::string& line) {
24 return line.find_first_not_of('\t'); 24 return line.find_first_not_of('\t');
25 } 25 }
26 26
27 bool HandleIndentation(const size_t current, 27 bool HandleIndentation(const size_t current, const std::vector<Player>& players, State& state) {
28 const std::vector<Player>& players,
29 State& state) {
30 // Each state has a definitive expected indentation 28 // Each state has a definitive expected indentation
31 const auto expected = [&state]() -> size_t { 29 const auto expected = [&state]() -> size_t {
32 switch (state) { 30 switch (state) {
33 default: 31 default:
34 case State::ExpectPlayerName: 32 case State::ExpectPlayerName: return 0;
35 return 0; 33 case State::ExpectSection: return 1;
36 case State::ExpectSection:
37 return 1;
38 case State::ExpectWindow: 34 case State::ExpectWindow:
39 case State::ExpectExecutable: 35 case State::ExpectExecutable:
40 case State::ExpectStrategy: 36 case State::ExpectStrategy:
41 case State::ExpectType: 37 case State::ExpectType: return 2;
42 return 2; 38 case State::ExpectWindowTitle: return 3;
43 case State::ExpectWindowTitle:
44 return 3;
45 } 39 }
46 }(); 40 }();
47 41
48 if (current > expected) 42 if (current > expected)
49 return false; // Disallow excessive indentation 43 return false; // Disallow excessive indentation
50 44
51 if (current < expected) { 45 if (current < expected) {
52 auto fix_state = [&]() { 46 auto fix_state = [&]() { state = !current ? State::ExpectPlayerName : State::ExpectSection; };
53 state = !current ? State::ExpectPlayerName : State::ExpectSection;
54 };
55 switch (state) { 47 switch (state) {
56 case State::ExpectWindow: 48 case State::ExpectWindow:
57 if (players.back().windows.empty()) 49 if (players.back().windows.empty())
58 return false; 50 return false;
59 fix_state(); 51 fix_state();
66 case State::ExpectStrategy: 58 case State::ExpectStrategy:
67 if (players.back().strategies.empty()) 59 if (players.back().strategies.empty())
68 return false; 60 return false;
69 fix_state(); 61 fix_state();
70 break; 62 break;
71 case State::ExpectType: 63 case State::ExpectType: fix_state(); break;
72 fix_state(); 64 case State::ExpectWindowTitle: return false;
73 break;
74 case State::ExpectWindowTitle:
75 return false;
76 } 65 }
77 } 66 }
78 67
79 return true; 68 return true;
80 } 69 }
87 state = State::ExpectSection; 76 state = State::ExpectSection;
88 break; 77 break;
89 78
90 case State::ExpectSection: { 79 case State::ExpectSection: {
91 static const std::map<std::string, State> sections = { 80 static const std::map<std::string, State> sections = {
92 {"windows", State::ExpectWindow}, 81 {"windows", State::ExpectWindow },
93 {"executables", State::ExpectExecutable}, 82 {"executables", State::ExpectExecutable},
94 {"strategies", State::ExpectStrategy}, 83 {"strategies", State::ExpectStrategy },
95 {"type", State::ExpectType}, 84 {"type", State::ExpectType },
96 }; 85 };
97 util::TrimRight(line, ":"); 86 util::TrimRight(line, ":");
98 const auto it = sections.find(line); 87 const auto it = sections.find(line);
99 if (it == sections.end()) 88 if (it == sections.end())
100 return false; 89 return false;
101 state = it->second; 90 state = it->second;
102 break; 91 break;
103 } 92 }
104 93
105 case State::ExpectWindow: 94 case State::ExpectWindow: players.back().windows.push_back(line); break;
106 players.back().windows.push_back(line);
107 break;
108 95
109 case State::ExpectExecutable: 96 case State::ExpectExecutable: players.back().executables.push_back(line); break;
110 players.back().executables.push_back(line);
111 break;
112 97
113 case State::ExpectStrategy: { 98 case State::ExpectStrategy: {
114 static const std::map<std::string, Strategy> strategies = { 99 static const std::map<std::string, Strategy> strategies = {
115 {"window_title", Strategy::WindowTitle}, 100 {"window_title", Strategy::WindowTitle },
116 {"open_files", Strategy::OpenFiles}, 101 {"open_files", Strategy::OpenFiles },
117 {"ui_automation", Strategy::UiAutomation}, 102 {"ui_automation", Strategy::UiAutomation},
118 }; 103 };
119 util::TrimRight(line, ":"); 104 util::TrimRight(line, ":");
120 const auto it = strategies.find(line); 105 const auto it = strategies.find(line);
121 if (it == strategies.end()) 106 if (it == strategies.end())
122 return false; 107 return false;
123 const auto strategy = it->second; 108 const auto strategy = it->second;
124 players.back().strategies.push_back(strategy); 109 players.back().strategies.push_back(strategy);
125 switch (strategy) { 110 switch (strategy) {
126 case Strategy::WindowTitle: 111 case Strategy::WindowTitle: state = State::ExpectWindowTitle; break;
127 state = State::ExpectWindowTitle;
128 break;
129 } 112 }
130 break; 113 break;
131 } 114 }
132 115
133 case State::ExpectType: { 116 case State::ExpectType: {
134 static const std::map<std::string, PlayerType> types = { 117 static const std::map<std::string, PlayerType> types = {
135 {"default", PlayerType::Default}, 118 {"default", PlayerType::Default },
136 {"web_browser", PlayerType::WebBrowser}, 119 {"web_browser", PlayerType::WebBrowser},
137 }; 120 };
138 const auto it = types.find(line); 121 const auto it = types.find(line);
139 if (it == types.end()) 122 if (it == types.end())
140 return false; 123 return false;
141 players.back().type = it->second; 124 players.back().type = it->second;
149 } 132 }
150 133
151 return true; 134 return true;
152 } 135 }
153 136
154 } // namespace internal::parser 137 } // namespace internal::parser
155 138
156 //////////////////////////////////////////////////////////////////////////////// 139 ////////////////////////////////////////////////////////////////////////////////
157 140
158 bool ParsePlayersData(const std::string& data, std::vector<Player>& players) { 141 bool ParsePlayersData(const std::string& data, std::vector<Player>& players) {
159 if (data.empty()) 142 if (data.empty())
164 size_t indentation = 0; 147 size_t indentation = 0;
165 auto state = internal::parser::State::ExpectPlayerName; 148 auto state = internal::parser::State::ExpectPlayerName;
166 149
167 while (std::getline(stream, line, '\n')) { 150 while (std::getline(stream, line, '\n')) {
168 if (line.empty()) 151 if (line.empty())
169 continue; // Ignore empty lines 152 continue; // Ignore empty lines
170 153
171 indentation = internal::parser::GetIndentation(line); 154 indentation = internal::parser::GetIndentation(line);
172 155
173 internal::util::TrimLeft(line, "\t"); 156 internal::util::TrimLeft(line, "\t");
174 internal::util::TrimRight(line, "\n\r"); 157 internal::util::TrimRight(line, "\n\r");
175 158
176 if (line.empty() || line.front() == '#') 159 if (line.empty() || line.front() == '#')
177 continue; // Ignore empty lines and comments 160 continue; // Ignore empty lines and comments
178 161
179 if (!internal::parser::HandleIndentation(indentation, players, state)) 162 if (!internal::parser::HandleIndentation(indentation, players, state))
180 return false; 163 return false;
181 164
182 if (!internal::parser::HandleState(line, players, state)) 165 if (!internal::parser::HandleState(line, players, state))
193 return false; 176 return false;
194 177
195 return ParsePlayersData(data, players); 178 return ParsePlayersData(data, players);
196 } 179 }
197 180
198 } // namespace animia 181 } // namespace animia