virtual void print(std::ostream &os) const { os << m_from << " " << to_node() << " " << get_max_steps() << " " << get_step() << " " << static_cast<unsigned int>(get_type()) << " " << get_num_captured_gangsters() << " " << m_name; }
void justine::robocar::Traffic::cmd_session ( boost::asio::ip::tcp::socket client_socket ) { const int network_buffer_size = 524288; char data[network_buffer_size]; // TODO buffered write... try { for ( ;; ) { CarLexer cl; boost::system::error_code err; size_t length = client_socket.read_some ( boost::asio::buffer ( data ), err ); if ( err == boost::asio::error::eof ) { break; } else if ( err ) { throw boost::system::system_error ( err ); } std::istringstream pdata ( data ); cl.switch_streams ( &pdata ); cl.yylex(); length = 0; int resp_code = cl.get_errnumber(); int num = cl.get_num(); int id {0}; if ( cl.get_cmd() == 0 ) { for ( ;; ) { std::vector<std::shared_ptr<Car>> cars_copy; { std::lock_guard<std::mutex> lock ( cars_mutex ); cars_copy = cars; } std::stringstream ss; ss << m_time << " " << m_minutes << " " << cars_copy.size() << std::endl; /*for ( auto car:cars_copy ) { car->step(); ss << *car << " " << std::endl; }*/ //atirva for ( std::vector<std::shared_ptr<Car>>::iterator it=cars_copy.begin(); it != cars_copy.end(); ++it ) { auto car = *it; car->step(); ss << *car << " " << std::endl; } boost::asio::write ( client_socket, boost::asio::buffer ( data, length ) ); length = std::sprintf ( data, "%s", ss.str().c_str() ); boost::asio::write ( client_socket, boost::asio::buffer ( data, length ) ); std::this_thread::sleep_for ( std::chrono::milliseconds ( 200 ) ); } } else if ( cl.get_cmd() <100 ) { std::lock_guard<std::mutex> lock ( cars_mutex ); for ( int i {0}; i<cl.get_num(); ++i ) { if ( cl.get_role() =='c' ) id = addCop ( cl ); else id = addGangster ( cl ); if ( !resp_code ) length += std::sprintf ( data+length, "<OK %d %d/%d %c>", id, num, i+1, cl.get_role() ); else length += std::sprintf ( data+length, "<WARN %d %d/%d %c>", id, num, i+1, cl.get_role() ); } } // cmd 100 else if ( cl.get_cmd() == 101 ) { if ( m_smart_cars_map.find ( cl.get_id() ) != m_smart_cars_map.end() ) { std::shared_ptr<SmartCar> c = m_smart_cars_map[cl.get_id()]; if ( c->set_route ( cl.get_route() ) ) length += std::sprintf ( data+length, "<OK %d>", cl.get_id() ); else length += std::sprintf ( data+length, "<ERR bad routing vector>" ); } else length += std::sprintf ( data+length, "<ERR unknown car id>" ); } else if ( cl.get_cmd() == 1001 ) { if ( m_smart_cars_map.find ( cl.get_id() ) != m_smart_cars_map.end() ) { std::shared_ptr<SmartCar> c = m_smart_cars_map[cl.get_id()]; length += std::sprintf ( data+length, "<OK %d %u %u %u>", cl.get_id(), c->from(), c->to_node(), c->get_step() ); } else length += std::sprintf ( data+length, "<ERR unknown car id>" ); } else if ( cl.get_cmd() == 1002 ) { std::lock_guard<std::mutex> lock ( cars_mutex ); if ( m_smart_cars_map.find ( cl.get_id() ) != m_smart_cars_map.end() ) { bool hasGangsters {false}; /*for ( auto c:m_smart_cars ) { if ( c->get_type() == CarType::GANGSTER ) { length += std::sprintf ( data+length, "<OK %d %u %u %u>", cl.get_id(), c->from(), c->to_node(), c->get_step() ); if ( length > network_buffer_size - 512 ) { length += std::sprintf ( data+length, "<WARN too many gangsters to send through this implementation...>" ); break; } hasGangsters = true; } } */ //atirva for ( std::vector<std::shared_ptr<SmartCar>>::iterator it = m_smart_cars.begin(); it != m_smart_cars.end(); ++it ) { auto c = *it; if ( c->get_type() == CarType::GANGSTER ) { length += std::sprintf ( data+length, "<OK %d %u %u %u>", cl.get_id(), c->from(), c->to_node(), c->get_step() ); if ( length > network_buffer_size - 512 ) { length += std::sprintf ( data+length, "<WARN too many gangsters to send through this implementation...>" ); break; } hasGangsters = true; } } if ( !hasGangsters ) length += std::sprintf ( data+length, "<WARN there is no gangsters>" ); } else length += std::sprintf ( data+length, "<ERR unknown car id>" ); } else if ( cl.get_cmd() == 1003 ) { std::lock_guard<std::mutex> lock ( cars_mutex ); if ( m_smart_cars_map.find ( cl.get_id() ) != m_smart_cars_map.end() ) { bool hasCops {false}; /* for ( auto c:m_cop_cars ) { length += std::sprintf ( data+length, "<OK %d %u %u %u %d>", cl.get_id(), c->from(), c->to_node(), c->get_step(), c->get_num_captured_gangsters() ); if ( length > network_buffer_size - 512 ) { length += std::sprintf ( data+length, "<WARN too many cops to send through this implementation...>" ); break; } hasCops = true; }*/ //atirva for ( std::vector<std::shared_ptr<CopCar>>::iterator it = m_cop_cars.begin(); it != m_cop_cars.end(); ++it ) { auto c = *it; length += std::sprintf ( data+length, "<OK %d %u %u %u %d>", cl.get_id(), c->from(), c->to_node(), c->get_step(), c->get_num_captured_gangsters() ); if ( length > network_buffer_size - 512 ) { length += std::sprintf ( data+length, "<WARN too many cops to send through this implementation...>" ); break; } hasCops = true; } if ( !hasCops ) length += std::sprintf ( data+length, "<WARN there is no cops>" ); } else length += std::sprintf ( data+length, "<ERR unknown car id>" ); } else if ( cl.get_cmd() == 10001 ) { if ( m_smart_cars_map.find ( cl.get_id() ) != m_smart_cars_map.end() ) { std::shared_ptr<SmartCar> c = m_smart_cars_map[cl.get_id()]; if ( c->set_fromto ( cl.get_from(), cl.get_to() ) ) length += std::sprintf ( data+length, "<OK %d>", cl.get_id() ); else length += std::sprintf ( data+length, "<ERR cannot set>" ); } else length += std::sprintf ( data+length, "<ERR unknown car id>" ); } else { length += std::sprintf ( data+length, "<ERR unknown proto command>" ); } boost::asio::write ( client_socket, boost::asio::buffer ( data, length ) ); } } catch ( std::exception& e ) { std::cerr << "Ooops: " << e.what() << std::endl; } }