Fawkes API  Fawkes Development Version
sync_listener.cpp
00001 
00002 /***************************************************************************
00003  *  sync_listener.cpp - Sync Interface Listener
00004  *
00005  *  Created: Fri Jun 05 11:01:23 2009
00006  *  Copyright  2006-2009  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 "sync_listener.h"
00024 
00025 #include <blackboard/blackboard.h>
00026 #include <utils/logging/logger.h>
00027 
00028 using namespace fawkes;
00029 
00030 /** @class SyncInterfaceListener "sync_listener.h"
00031  * Synchronize two interfaces.
00032  * This class synchronizes two interfaces, a reading and a writing instance
00033  * of the same type. To accomplish this it listens for data changed and message
00034  * events and forwards them as appropriate to "the other side".
00035  * @author Tim Niemueller
00036  */
00037 
00038 /** Constructor.
00039  * Automatically registers the listener with the (two) blackboards as
00040  * appropriate. It also automatically unregisters in the destructor.
00041  * @param logger logger to write informational output to
00042  * @param reader reading interface instance
00043  * @param writer writing interface instance of the same type as \p reader
00044  * @param reader_bb the BlackBoard instance the reading instance has been
00045  * created on
00046  * @param writer_bb the BlackBoard instance the writing instance has been
00047  * created on
00048  */
00049 SyncInterfaceListener::SyncInterfaceListener(fawkes::Logger *logger,
00050                                              fawkes::Interface *reader,
00051                                              fawkes::Interface *writer,
00052                                              fawkes::BlackBoard *reader_bb,
00053                                              fawkes::BlackBoard *writer_bb)
00054   : BlackBoardInterfaceListener("SyncInterfaceListener(%s-%s)", writer->uid(), reader->id())
00055 {
00056   __logger    = logger;
00057   __reader    = reader;
00058   __writer    = writer;
00059   __reader_bb = reader_bb;
00060   __writer_bb = writer_bb;
00061 
00062   bbil_add_data_interface(__reader);
00063   bbil_add_message_interface(__writer);
00064 
00065   __reader_bb->register_listener(this, BlackBoard::BBIL_FLAG_DATA);
00066   __writer_bb->register_listener(this, BlackBoard::BBIL_FLAG_MESSAGES);
00067 }
00068 
00069 
00070 /** Destructor. */
00071 SyncInterfaceListener::~SyncInterfaceListener()
00072 {
00073   __reader_bb->unregister_listener(this);
00074   __writer_bb->unregister_listener(this);
00075 }
00076 
00077 
00078 bool
00079 SyncInterfaceListener::bb_interface_message_received(Interface *interface,
00080                                                      Message *message) throw()
00081 {
00082   try {
00083     if ( interface == __writer ) {
00084       __logger->log_debug(bbil_name(), "Forwarding message");
00085       Message *m = message->clone();
00086       m->set_hops(message->hops());
00087       m->ref();
00088       __reader->msgq_enqueue(m);
00089       message->set_id(m->id());
00090       m->unref();
00091       return false;
00092     } else {
00093       // Don't know why we were called, let 'em enqueue
00094         __logger->log_error(bbil_name(), "Message received for unknown interface");
00095       return true;
00096     }
00097   } catch (Exception &e) {
00098       __logger->log_error(bbil_name(), "Exception when message received");
00099     __logger->log_error("SyncInterfaceListener", e);
00100     return false;
00101   }
00102 }
00103 
00104 
00105 void
00106 SyncInterfaceListener::bb_interface_data_changed(Interface *interface) throw()
00107 {
00108   try {
00109     if ( interface == __reader ) {
00110       //__logger->log_debug(bbil_name(), "Copying data");
00111       __reader->read();
00112       __writer->copy_values(__reader);
00113       __writer->write();
00114     } else {
00115       // Don't know why we were called, let 'em enqueue
00116       __logger->log_error(bbil_name(), "Data changed for unknown interface");
00117     }
00118   } catch (Exception &e) {
00119     __logger->log_error(bbil_name(), "Exception when data changed");
00120     __logger->log_error(bbil_name(), e);
00121   }
00122 }