Fawkes API  Fawkes Development Version
remotebb.cpp
00001 
00002 /***************************************************************************
00003  *  remotebb.cpp - Fawkes remote blackboard processor
00004  *
00005  *  Created: Wed Apr 09 10:38:16 2008
00006  *  Copyright  2010  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022 
00023 #include "remotebb.h"
00024 #include <logging/logger.h>
00025 
00026 #include <blackboard/remote.h>
00027 #include <interfaces/GameStateInterface.h>
00028 
00029 #include <cstring>
00030 #include <cstdlib>
00031 
00032 using namespace fawkes;
00033 
00034 /** @class RemoteBlackBoardRefBoxProcessor "processor/remotebb.h"
00035  * Remote BlackBoard refbox repeater.
00036  * This class will establish the connection to a remote blackboard and copy
00037  * the refbox information from there to the local state handler.
00038  * It can be used as a fallback for unicast communcation to a central
00039  * repeater host.
00040  * @author Tim Niemueller
00041  */
00042 
00043 /** Constructor.
00044  * @param logger logger for output
00045  * @param bb_host remote blackboard host
00046  * @param bb_port remote blackboard port
00047  * @param iface_id ID of the GameStateInterface on the remote blackboard
00048  */
00049 RemoteBlackBoardRefBoxProcessor::RemoteBlackBoardRefBoxProcessor(
00050                                    Logger *logger,
00051                                    const char *bb_host,
00052                                    unsigned short int bb_port,
00053                                    const char *iface_id)
00054   : __name("RBBRefBoxRep")
00055 {
00056   __logger = logger;
00057   __rbb = NULL;
00058   __gamestate_if = NULL;
00059 
00060   __message_shown = false;
00061 
00062   __bb_host  = strdup(bb_host);
00063   __bb_port  = bb_port;
00064   __iface_id = strdup(iface_id);
00065 
00066   try {
00067     reconnect();
00068   } catch (Exception &e) {
00069     __logger->log_warn(__name, "Could not connect to remote blackboard, "
00070                        "will keep trying");
00071   }
00072 }
00073 
00074 
00075 /** Destructor. */
00076 RemoteBlackBoardRefBoxProcessor::~RemoteBlackBoardRefBoxProcessor()
00077 {
00078   free(__bb_host);
00079   free(__iface_id);
00080   if (__rbb) {
00081     __rbb->close(__gamestate_if);
00082     delete __rbb;
00083   }
00084 }
00085 
00086 
00087 /** Reconnect to refbox. */
00088 void
00089 RemoteBlackBoardRefBoxProcessor::reconnect()
00090 {
00091   if ( __rbb ) {
00092     __rbb->close(__gamestate_if);
00093     delete __rbb;
00094   }
00095   __rbb = NULL;
00096 
00097   //  __logger->log_info(__name, "Trying to connect to blackboard at %s:%u",
00098   //                 __bb_host, __bb_port);
00099   try {
00100     __rbb = new RemoteBlackBoard(__bb_host, __bb_port);
00101     __gamestate_if = __rbb->open_for_reading<GameStateInterface>(__iface_id);
00102   } catch (Exception &e) {
00103     delete __rbb;
00104     __rbb = NULL;
00105     throw;
00106   }
00107 }
00108 
00109 void
00110 RemoteBlackBoardRefBoxProcessor::refbox_process()
00111 {
00112   if (__rbb && __rbb->is_alive() && __gamestate_if->is_valid()) {
00113     try {
00114       __gamestate_if->read();
00115       _rsh->set_gamestate(__gamestate_if->game_state(),
00116                           (worldinfo_gamestate_team_t)__gamestate_if->state_team());
00117       _rsh->set_score(__gamestate_if->score_cyan(),
00118                       __gamestate_if->score_magenta());
00119       _rsh->set_team_goal((worldinfo_gamestate_team_t)__gamestate_if->our_team(),
00120                           (worldinfo_gamestate_goalcolor_t)__gamestate_if->our_goal_color());
00121       _rsh->set_half((worldinfo_gamestate_half_t)__gamestate_if->half(),
00122                      __gamestate_if->is_kickoff());
00123 
00124     } catch (Exception &e) {
00125       __logger->log_warn(__name, "Processing BB data failed, exception follows");
00126       __logger->log_warn(__name, e);
00127     }
00128   }
00129 }
00130 
00131 bool
00132 RemoteBlackBoardRefBoxProcessor::check_connection()
00133 {
00134   if (! (__rbb && __rbb->is_alive() && __gamestate_if->is_valid())) {
00135     try {
00136       reconnect();
00137       __message_shown = false;
00138     } catch (Exception &e) {
00139       if (! __message_shown) {
00140         __logger->log_warn(__name, "Reconnect failed, exception follows");
00141         __logger->log_warn(__name, e);
00142         __message_shown = true;
00143       }
00144       return false;
00145     }
00146   }
00147   return true;
00148 }