Phoenix2D-Library  0.10
Parser.cpp
Go to the documentation of this file.
1 /*
2  * Phoenix2D (RoboCup Soccer Simulation 2D League)
3  * Copyright (c) 2013 Ivan Gonzalez
4  *
5  * This file is part of Phoenix2D.
6  *
7  * Phoenix2D is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * Phoenix2D is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Phoenix2D. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <iostream>
22 #include <cstdlib>
23 #include <boost/regex.hpp>
24 #include <pthread.h>
25 #include <list>
26 #include <unistd.h>
27 #include "Parser.h"
28 #include "Game.h"
29 #include "Self.h"
30 #include "Flag.h"
31 #include "Player.h"
32 #include "Server.h"
33 #include "Position.h"
34 #include "World.h"
35 #include "Ball.h"
36 #include "PlayMode.h"
37 #include "Vector2D.h"
38 #include "Trainer.h"
39 #include "Config.h"
40 #include "Logger.h"
41 namespace Phoenix
42 {
43 static std::string sense_body_message = "";
44 static std::string see_message = "";
45 static bool see_received = false;
46 static bool processing_body = false;
47 static bool processing_see = false;
48 static Self* self_ptr = 0;
49 static Game* game_ptr = 0;
50 static World* world_ptr = 0;
51 static PlayMode* play_mode_ptr = 0;
52 static Trainer* trainer_ptr = 0;
53 static boost::regex see_regex("\\(([^()]+)\\)\\s*([\\d\\.\\-etk\\s]*)");
54 boost::regex hear_referee_regex("\\(hear\\s+(\\d+)\\s+referee\\s+([\\\"\\w\\s]*)\\)");
55 boost::regex hear_coach_regex("\\(hear\\s+(\\d+)\\s+(online_coach_left|online_coach_right)\\s+([\\\"\\w\\s]*)\\)");
56 boost::regex hear_trainer_regex("\\(hear\\s+(\\d+)\\s+coach\\s+([\\\"\\w\\s]*)\\)");
57 boost::regex hear_player_regex("\\(hear\\s+(\\d+)\\s+([\\d\\.\\-e]+)\\s+our\\s+(\\d+)\\s+([\\\"\\w\\s]+)\\)");
58 static pthread_cond_t see_cond = PTHREAD_COND_INITIALIZER;
59 static pthread_mutex_t see_mutex = PTHREAD_MUTEX_INITIALIZER;
60 static pthread_cond_t sense_body_cond = PTHREAD_COND_INITIALIZER;
61 static pthread_mutex_t sense_body_mutex = PTHREAD_MUTEX_INITIALIZER;
62 pthread_t thread_sense_body = 0;
63 pthread_t thread_see = 0;
64 pthread_attr_t attr;
65 
66 bool compareFlags(Flag f0, Flag f1) {
67  return f0.getDistance() > f1.getDistance(); // decreasing order
68 }
69 
70 void *process_sense_body(void *arg) {
71  int success = pthread_mutex_lock(&sense_body_mutex);
72  if (success) {
73  std::cerr << "Parser::process_sense_body(void*) -> cannot lock sense body mutex" << std::endl;
74  return 0;
75  }
77  processing_body = false;
78  success = pthread_cond_signal(&sense_body_cond);
79  if (success) {
80  std::cerr << "Parser::process_see(void*) -> cannot signal to blocked threads" << std::endl;
81  }
82  success = pthread_mutex_unlock(&sense_body_mutex);
83  if (success) {
84  std::cerr << "Parser::process_sense_body(void*) -> cannot unlock sense body mutex" << std::endl;
85  return 0;
86  }
87  usleep(1000 * Server::SYNCH_SEE_OFFSET);
88  success = pthread_mutex_lock(&see_mutex);
89  if (success) {
90  std::cerr << "Parser::process_sense_body(void*) -> cannot lock mutex" << std::endl;
91  return 0;
92  }
93  while (processing_see) {
94  success = pthread_cond_wait(&see_cond, &see_mutex);
95  if (success) {
96  std::cerr << "Parser::process_sense_body(void*) -> cannot wait for condition" << std::endl;
97  return 0;
98  }
99  }
100  success = pthread_mutex_unlock(&see_mutex);
101  if (success) {
102  std::cerr << "Parser::process_sense_body(void*) -> cannot unlock mutex" << std::endl;
103  }
104  if (!see_received) {
105  self_ptr->localize();
107  }
108  size_t found = sense_body_message.find(" ", 12);
109  game_ptr->updateTime(atoi(sense_body_message.substr(12, found - 12).c_str()));
110  return 0;
111 }
112 
113 void *process_see(void *arg) {
114  int success = pthread_mutex_lock(&sense_body_mutex);
115  if (success) {
116  std::cerr << "Parser::process_sense_body(void*) -> cannot lock sense body mutex" << std::endl;
117  return 0;
118  }
119  while (processing_body) {
120  success = pthread_cond_wait(&sense_body_cond, &sense_body_mutex);
121  if (success) {
122  std::cerr << "Parser::process_sense_body(void*) -> cannot wait for condition" << std::endl;
123  return 0;
124  }
125  }
126  success = pthread_mutex_unlock(&sense_body_mutex);
127  if (success) {
128  std::cerr << "Parser::process_sense_body(void*) -> cannot unlock sense body mutex" << std::endl;
129  return 0;
130  }
131  success = pthread_mutex_lock(&see_mutex);
132  if (success) {
133  std::cerr << "Parser::process_see(void*) -> cannot lock mutex" << std::endl;
134  return 0;
135  }
136  int simulation_time = Game::SIMULATION_TIME;
137  Position player_position = Self::getPosition();
138  Vector2D player_velocity = Self::getVelocity();
139  std::vector<Flag> flags;
140  std::list<Player> players;
142  std::string::const_iterator start, end;
143  start = see_message.begin();
144  end = see_message.end();
145  boost::match_results<std::string::const_iterator> match;
146  boost::match_flag_type search_flags = boost::match_default;
147  while (boost::regex_search(start, end, match, see_regex, search_flags)) {
148  std::string name = std::string() + match[1];
149  std::string data = std::string() + match[2];
150  switch (name[0]) {
151  case 'g':
152  break;
153  case 'f':
154  flags.push_back(Flag(name, data, simulation_time));
155  break;
156  case 'p':
157  players.push_back(Player(name, data, simulation_time, player_position, player_velocity));
158  break;
159  case 'b':
160  ball = Ball(data, simulation_time, player_position, player_velocity);
161  break;
162  default:
163  break;
164  }
165  start = match[0].second;
166  search_flags |= boost::match_prev_avail;
167  search_flags |= boost::match_not_bob;
168  }
169  self_ptr->localize(flags);
170  world_ptr->updateWorld(players, ball);
171  processing_see = false;
172  success = pthread_cond_signal(&see_cond);
173  if (success) {
174  std::cerr << "Parser::process_see(void*) -> cannot signal to blocked threads" << std::endl;
175  }
176  success = pthread_mutex_unlock(&see_mutex);
177  if (success) {
178  std::cerr << "Parser::process_see(void*) -> cannot unlock mutex" << std::endl;
179  }
180  return 0;
181 }
182 
183 Parser::Parser(Self *self, World *world) {
184  self_ptr = self;
185  world_ptr = world;
186  game_ptr = new Game();
187  pthread_attr_init(&attr);
188  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
189 }
190 
192  pthread_attr_destroy(&attr);
193  if (game_ptr) delete game_ptr;
194  if (Config::VERBOSE) std::cout << "Parser out" << std::endl;
195 }
196 
197 void Parser::parseMessage(std::string message) {
198  size_t found = message.find_first_of(" ");
199  std::string message_type = message.substr(1, found - 1);
200  if (message_type.compare("sense_body") == 0 && !processing_body) {
201  processing_body = true;
202  see_received = false; //we restart this variable here because the sense_body means a new cycle
203  sense_body_message = message;
204  int success = pthread_create(&thread_sense_body, &attr, process_sense_body, 0);
205  if (success) {
206  std::cerr << "Parser::parseMessage(string) -> error creating sense_body thread" << std::endl;
207  }
208  } else if (message_type.compare("see") == 0 && !processing_see) {
209  processing_see = true;
210  see_received = true;
211  see_message = message;
212  int success = pthread_create(&thread_see, &attr, process_see, 0);
213  if (success) {
214  std::cerr << "Parser::parseMessage(string) -> error creating see thread" << std::endl;
215  }
216  } else if (message_type.compare("hear") == 0) {
217  boost::cmatch match;
218  if (boost::regex_match(message.c_str(), match, hear_referee_regex)) { //referee
219  game_ptr->updatePlayMode(std::string() + match[2]);
220  } else if (boost::regex_match(message.c_str(), match, hear_player_regex)) { //player
221  int unum = atoi((std::string() + match[3]).c_str());
222  std::string message = std::string() + match[4];
223  play_mode_ptr->onMessageReceived(message, unum);
224  } else if (boost::regex_match(message.c_str(), match, hear_coach_regex)) { //coach
225  std::string coach = std::string() + match[2];
226  if (Self::SIDE[0] == coach[13]) {
227 
228  }
229  } else if (boost::regex_match(message.c_str(), match, hear_trainer_regex)) { //trainer
230 
231  } else {
232  std::cerr << Game::SIMULATION_TIME << ": message not supported " << message << std::endl;
233  }
234  } else if (message_type.compare("change_player_type") == 0) {
235 
236  } else if (message_type.compare("see_global") == 0){
237  int simulation_time = Game::SIMULATION_TIME;
238  std::list<Player> players;
239  Ball ball;
240  std::string::const_iterator start, end;
241  start = message.begin();
242  end = message.end();
243  boost::match_results<std::string::const_iterator> match;
244  boost::match_flag_type search_flags = boost::match_default;
245  while (boost::regex_search(start, end, match, see_regex, search_flags)) {
246  std::string name = std::string() + match[1];
247  std::string data = std::string() + match[2];
248  switch (name[0]) {
249  case 'g':
250  break;
251  case 'p':
252  players.push_back(Player(name, data, simulation_time));
253  break;
254  case 'b':
255  ball = Ball(data, simulation_time);
256  break;
257  default:
258  break;
259  }
260  start = match[0].second;
261  search_flags |= boost::match_prev_avail;
262  search_flags |= boost::match_not_bob;
263  }
264  world_ptr->updateObserverWorld(players, ball);
265  size_t found = message.find(" ", 12);
266  game_ptr->updateTime(atoi(message.substr(12, found - 12).c_str()));
267  } else if (message_type.compare("ok") == 0) {
268  if (Config::VERBOSE) std::cout << Game::SIMULATION_TIME << ": " << message << std::endl;
269  } else if (message_type.compare("error") == 0) {
270  std::cerr << Game::SIMULATION_TIME << ": " << message << std::endl;
271  } else {
272  std::cerr << "Parse::parseMessage(string) -> message " << message << " not recognized" << std::endl;
273  }
274 }
275 
277  play_mode_ptr = play_mode;
278 }
279 
281  trainer_ptr = trainer;
282 }
283 }
double getDistance()
Definition: Flag.cpp:128
void updatePlayMode(std::string play_mode)
Definition: Game.cpp:70
Player The Player lorem Ipsum
Definition: Player.h:39
pthread_attr_t attr
Definition: Parser.cpp:64
Ball The Ball lorem Ipsum
Definition: Ball.h:38
static PlayMode * play_mode_ptr
Definition: Parser.cpp:51
Position The Position lorem Ipsum
Definition: Position.h:50
Ball ball
Definition: World.cpp:31
void parseMessage(std::string message)
Definition: Parser.cpp:197
Trainer The Trainer lorem Ipsum
Definition: Trainer.h:39
void * process_see(void *arg)
Definition: Parser.cpp:113
static Vector2D getVelocity()
Definition: Self.cpp:718
static Position getPosition()
Definition: Self.cpp:714
static pthread_mutex_t see_mutex
Definition: Parser.cpp:59
static bool processing_see
Definition: Parser.cpp:47
static bool see_received
Definition: Parser.cpp:45
static pthread_cond_t sense_body_cond
Definition: Parser.cpp:60
bool compareFlags(Flag f0, Flag f1)
Definition: Parser.cpp:66
static Game * game_ptr
Definition: Parser.cpp:49
static pthread_cond_t see_cond
Definition: Parser.cpp:58
boost::regex hear_coach_regex("\\(hear\\s+(\\d+)\\s+(online_coach_left|online_coach_right)\\s+([\\\"\\w\\s]*)\\)")
void localize(std::vector< Flag > flags)
Definition: Self.cpp:624
void updateObserverWorld(std::list< Player > players, Ball ball)
Definition: World.cpp:99
boost::regex hear_referee_regex("\\(hear\\s+(\\d+)\\s+referee\\s+([\\\"\\w\\s]*)\\)")
pthread_t thread_sense_body
Definition: Parser.cpp:62
static Trainer * trainer_ptr
Definition: Parser.cpp:52
Parser(Self *self, World *world)
Definition: Parser.cpp:183
static std::string SIDE
Definition: Self.h:50
Self The Self lorem Ipsum
Definition: Self.h:45
boost::regex hear_trainer_regex("\\(hear\\s+(\\d+)\\s+coach\\s+([\\\"\\w\\s]*)\\)")
static bool VERBOSE
Definition: Config.h:38
static int SYNCH_SEE_OFFSET
Definition: Server.h:203
static std::string see_message
Definition: Parser.cpp:44
World The World lorem Ipsum
Definition: World.h:41
static void registerPlayMode(PlayMode *play_mode)
Definition: Parser.cpp:276
static std::string sense_body_message
Definition: Parser.cpp:43
Flag The Flag lorem Ipsum
Definition: Flag.h:45
void * process_sense_body(void *arg)
Definition: Parser.cpp:70
static bool processing_body
Definition: Parser.cpp:46
static pthread_mutex_t sense_body_mutex
Definition: Parser.cpp:61
void updateWorld()
Definition: World.cpp:41
static unsigned int SIMULATION_TIME
Definition: Game.h:38
static World * world_ptr
Definition: Parser.cpp:50
PlayMode The PlayMode lorem Ipsum
Definition: PlayMode.h:59
Game The Game lorem Ipsum
Definition: Game.h:36
boost::regex hear_player_regex("\\(hear\\s+(\\d+)\\s+([\\d\\.\\-e]+)\\s+our\\s+(\\d+)\\s+([\\\"\\w\\s]+)\\)")
virtual void onMessageReceived(std::string message, int sender)=0
void updateTime(int game_time)
Definition: Game.cpp:51
std::list< Player > players
Definition: World.cpp:30
pthread_t thread_see
Definition: Parser.cpp:63
static void registerTrainer(Trainer *trainer)
Definition: Parser.cpp:280
static Self * self_ptr
Definition: Parser.cpp:48
Vector2D The Vector2D lorem Ipsum
Definition: Vector2D.h:45
void processSenseBody(std::string sense_body)
Definition: Self.cpp:317
static boost::regex see_regex("\\(([^()]+)\\)\\s*([\\d\\.\\-etk\\s]*)")