worldinfo_viewer.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "worldinfo_viewer.h"
00024 #include "field_view.h"
00025
00026 #include <worldinfo_utils/data_container.h>
00027 #include <blackboard/remote.h>
00028 #include <interfaces/BatteryInterface.h>
00029
00030 #include <vector>
00031 #include <map>
00032 #include <string>
00033 #include <cstdio>
00034 #include <cstring>
00035
00036 using namespace std;
00037 using namespace fawkes;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 WorldInfoViewer::WorldInfoViewer( Glib::RefPtr<Gnome::Glade::Xml> ref_xml,
00052 WorldInfoDataContainer* data_container )
00053 {
00054 m_wnd_main = dynamic_cast<Gtk::Window*>( get_widget(ref_xml, "wndMain") );
00055 m_vbx_field = dynamic_cast<Gtk::VBox*>( get_widget(ref_xml, "vbxField") );
00056 m_trv_robots = dynamic_cast<Gtk::TreeView*>( get_widget(ref_xml, "trvRobots") );
00057 m_stb_status = dynamic_cast<Gtk::Statusbar*>( get_widget(ref_xml, "stbStatus") );
00058
00059 m_field_view = new FieldView( data_container, true, true, false );
00060 m_vbx_field->pack_start( *m_field_view );
00061 m_field_view->show();
00062
00063 m_robots_list = Gtk::ListStore::create( m_robot_record );
00064 m_trv_robots->set_model( m_robots_list );
00065 m_trv_robots->append_column( "Name", m_robot_record.hostname );
00066 m_trv_robots->append_column_editable( "Pose", m_robot_record.show_pose );
00067 m_trv_robots->append_column_editable( "Ball", m_robot_record.show_ball );
00068 m_trv_robots->append_column_editable( "Opponents", m_robot_record.show_opponents );
00069
00070 Gtk::CellRendererToggle* renderer;
00071 renderer = dynamic_cast< Gtk::CellRendererToggle* >( m_trv_robots->get_column_cell_renderer(1) );
00072 renderer->signal_toggled().connect( sigc::mem_fun( *this,
00073 &WorldInfoViewer::on_show_pose_toggled ) );
00074 renderer = dynamic_cast< Gtk::CellRendererToggle* >( m_trv_robots->get_column_cell_renderer(2) );
00075 renderer->signal_toggled().connect( sigc::mem_fun( *this,
00076 &WorldInfoViewer::on_show_ball_toggled ) );
00077 renderer = dynamic_cast< Gtk::CellRendererToggle* >( m_trv_robots->get_column_cell_renderer(3) );
00078 renderer->signal_toggled().connect( sigc::mem_fun( *this,
00079 &WorldInfoViewer::on_show_opponents_toggled ) );
00080
00081 m_data_container = data_container;
00082
00083 m_stb_message_id = m_stb_status->push( "No game state information available." );
00084
00085
00086 sigc::connection conn =
00087 Glib::signal_timeout().connect( sigc::mem_fun( *this, &WorldInfoViewer::update ), 200 );
00088 }
00089
00090
00091
00092 WorldInfoViewer::~WorldInfoViewer()
00093 {
00094 delete m_field_view;
00095 delete m_wnd_main;
00096 }
00097
00098
00099
00100
00101
00102 Gtk::Window&
00103 WorldInfoViewer::get_window() const
00104 {
00105 return *m_wnd_main;
00106 }
00107
00108 Gtk::Widget*
00109 WorldInfoViewer::get_widget(Glib::RefPtr<Gnome::Glade::Xml> ref_xml,
00110 const char* widget_name) const
00111 {
00112 Gtk::Widget* widget;
00113 ref_xml->get_widget(widget_name, widget);
00114 if ( !widget )
00115 {
00116 char* err_str;
00117 if (asprintf(&err_str, "Couldn't find widget %s", widget_name) != -1)
00118 {
00119 throw std::runtime_error(err_str);
00120 free(err_str);
00121 }
00122 else
00123 { throw std::runtime_error("Getting widget failed"); }
00124 }
00125
00126 return widget;
00127 }
00128
00129
00130
00131 bool
00132 WorldInfoViewer::update()
00133 {
00134 bool robot_removed = false;
00135
00136 if ( m_data_container->check_timeout() )
00137 {
00138 robot_removed = true;
00139 list<string> timedout_hosts = m_data_container->get_timedout_hosts();
00140
00141 #ifdef DEBUG_PRINT
00142 printf( "Removing %zu timed out host.\n", timedout_hosts.size() );
00143 #endif
00144
00145
00146 for ( list<string>::iterator hit = timedout_hosts.begin();
00147 hit != timedout_hosts.end();
00148 ++hit )
00149 {
00150 m_field_view->remove_host( Glib::ustring( *hit ) );
00151
00152 Gtk::TreeModel::Children children = m_robots_list->children();
00153 Gtk::TreeModel::iterator cit = children.begin();
00154 while ( cit != children.end() )
00155 {
00156 Gtk::TreeModel::Row row = *cit;
00157 if ( Glib::ustring( *hit ) == row[ m_robot_record.fqdn ] )
00158 { cit = m_robots_list->erase( cit ); }
00159 else
00160 { ++cit; }
00161 }
00162 }
00163 }
00164
00165
00166 if ( !m_data_container->new_data_available() )
00167 {
00168 if ( robot_removed )
00169 { m_field_view->queue_draw(); }
00170 return true;
00171 }
00172
00173 list<string> hosts = m_data_container->get_hosts();
00174
00175
00176 for ( list<string>::iterator hit = hosts.begin();
00177 hit != hosts.end();
00178 ++hit )
00179 {
00180 bool found = false;
00181
00182 Gtk::TreeModel::Children children = m_robots_list->children();
00183 for ( Gtk::TreeModel::iterator i = children.begin();
00184 i != children.end();
00185 ++i )
00186 {
00187 Gtk::TreeModel::Row row = *i;
00188 if ( Glib::ustring( *hit ) == row[ m_robot_record.fqdn ] )
00189 {
00190 found = true;
00191 break;
00192 }
00193 }
00194
00195 if ( !found )
00196 {
00197 char* fqdn;
00198 char* hostname;
00199 char delim ='.';
00200 Glib::ustring fqdn_str = Glib::ustring( *hit );
00201
00202 fqdn = strdup( hit->c_str() );
00203 hostname = strtok( fqdn, &delim );
00204 int i = atoi( hostname );
00205
00206 Gtk::TreeModel::Row row = *m_robots_list->append();
00207
00208 if ( 0 == i )
00209 { row[ m_robot_record.hostname ] = Glib::ustring( hostname ); }
00210 else
00211 { row[ m_robot_record.hostname ] = fqdn_str; }
00212 row[ m_robot_record.fqdn ] = fqdn_str;
00213 row[ m_robot_record.show_pose ] = m_field_view->toggle_show_pose( fqdn_str );
00214 row[ m_robot_record.show_ball ] = m_field_view->toggle_show_ball( fqdn_str );
00215 row[ m_robot_record.show_opponents ] = m_field_view->toggle_show_opponents( fqdn_str );
00216
00217 free(fqdn);
00218 }
00219 }
00220
00221 m_field_view->queue_draw();
00222
00223 return true;
00224 }
00225
00226
00227 void
00228 WorldInfoViewer::gamestate_changed()
00229 {
00230 char* status_string;
00231 if ( asprintf( &status_string,
00232 "Team color: %s Goal color: %s Mode: %s Score: %d:%d Half: %s",
00233 m_data_container->get_own_team_color_string().c_str(),
00234 m_data_container->get_own_goal_color_string().c_str(),
00235 m_data_container->get_game_state_string().c_str(),
00236 m_data_container->get_own_score(),
00237 m_data_container->get_other_score(),
00238 m_data_container->get_half_string().c_str() ) != -1 )
00239 {
00240 m_stb_status->remove_message(m_stb_message_id);
00241 m_stb_message_id = m_stb_status->push( Glib::ustring(status_string) );
00242
00243 free(status_string);
00244 }
00245 }
00246
00247 void
00248 WorldInfoViewer::on_show_pose_toggled( const Glib::ustring& path )
00249 {
00250 Gtk::TreeModel::Row row = *m_robots_list->get_iter( path );
00251 Glib::ustring fqdn = row[ m_robot_record.fqdn ];
00252
00253 row[ m_robot_record.show_pose ] = m_field_view->toggle_show_pose( fqdn );
00254
00255 m_field_view->queue_draw();
00256 }
00257
00258 void
00259 WorldInfoViewer::on_show_ball_toggled( const Glib::ustring& path )
00260 {
00261 Gtk::TreeModel::Row row = *m_robots_list->get_iter( path );
00262 Glib::ustring fqdn = row[ m_robot_record.fqdn ];
00263
00264 row[ m_robot_record.show_ball ] = m_field_view->toggle_show_ball( fqdn );
00265
00266 m_field_view->queue_draw();
00267 }
00268
00269 void
00270 WorldInfoViewer::on_show_opponents_toggled( const Glib::ustring& path )
00271 {
00272 Gtk::TreeModel::Row row = *m_robots_list->get_iter( path );
00273 Glib::ustring fqdn = row[ m_robot_record.fqdn ];
00274
00275 row[ m_robot_record.show_opponents ] = m_field_view->toggle_show_opponents( fqdn );
00276
00277 m_field_view->queue_draw();
00278 }