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