Fawkes API  Fawkes Development Version
qa_bb_notify.cpp
00001 
00002 /***************************************************************************
00003  *  qa_bb_notify.cpp - BlackBoard notification QA
00004  *
00005  *  Created: Mon Nov 12 14:35:53 2007
00006  *  Copyright  2006-2007  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. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 
00025 /// @cond QA
00026 
00027 #include <blackboard/local.h>
00028 #include <blackboard/remote.h>
00029 #include <blackboard/exceptions.h>
00030 #include <blackboard/bbconfig.h>
00031 #include <blackboard/interface_listener.h>
00032 #include <blackboard/interface_observer.h>
00033 
00034 #include <interfaces/TestInterface.h>
00035 
00036 #include <core/threading/thread.h>
00037 #include <core/exceptions/system.h>
00038 #include <logging/liblogger.h>
00039 
00040 #include <signal.h>
00041 #include <cstdlib>
00042 #include <cstdio>
00043 #include <cstring>
00044 
00045 #include <iostream>
00046 #include <vector>
00047 
00048 using namespace std;
00049 using namespace fawkes;
00050 
00051 class QaBBEventListener
00052   : public BlackBoardInterfaceListener,
00053     public BlackBoardInterfaceObserver
00054 {
00055  public:
00056   QaBBEventListener(BlackBoard *bb)
00057     : BlackBoardInterfaceListener("QaBBEventListener"),
00058       __bb(bb)
00059   {
00060     bbio_add_observed_create("TestInterface", "AnotherID *");
00061     bbio_add_observed_destroy("TestInterface");
00062   }
00063 
00064   virtual void bb_interface_created(const char *type, const char *id) throw()
00065   {
00066     printf("BBIO: Interface %s of type %s has been created\n", id, type);
00067   }
00068 
00069   virtual void bb_interface_destroyed(const char *type, const char *id) throw()
00070   {
00071     printf("BBIO: Interface %s of type %s has been destroyed\n", id, type);
00072   }
00073 
00074 
00075   virtual void bb_interface_data_changed(Interface *interface) throw()
00076   {
00077     printf("BBIL: Data in interface %s has been modified\n", interface->uid());
00078   }
00079 
00080   virtual bool bb_interface_message_received(Interface *interface, Message *message) throw()
00081   {
00082     printf("BBIL: Message of type %s for interface %s has been received\n",
00083            message->type(), interface->uid());
00084     // do not enqueue, then we do not have to flush it
00085     if (strcmp(message->type(), "SetTestStringMessage") == 0) {
00086       printf("BBIL: Received message of type %s, unregistering from inside "
00087              "event handler\n", message->type());
00088       bbil_remove_message_interface(interface);
00089       __bb->update_listener(this);
00090     }
00091     return false;
00092   }
00093 
00094   virtual void bb_interface_writer_added(Interface *interface, unsigned int instance_serial) throw()
00095   {
00096     printf("BBIL: Writer has been added to interface %s/%u (event serial %u)\n",
00097            interface->uid(), interface->serial(), instance_serial);
00098   }
00099 
00100   virtual void bb_interface_writer_removed(Interface *interface, unsigned int instance_serial) throw()
00101   {
00102     printf("BBIL: Writer has been removed from interface %s/%u (event serial %u)\n",
00103            interface->uid(), interface->serial(), instance_serial);
00104   }
00105 
00106   virtual void bb_interface_reader_added(Interface *interface, unsigned int instance_serial) throw()
00107   {
00108     printf("BBIL: Reader has been added to interface %s/%u (event serial %u)\n",
00109            interface->uid(), interface->serial(), instance_serial);
00110   }
00111 
00112   virtual void bb_interface_reader_removed(Interface *interface, unsigned int instance_serial) throw()
00113   {
00114     printf("BBIL: Reader has been removed from interface %s/%u (event serial %u)\n",
00115            interface->uid(), interface->serial(), instance_serial);
00116   }
00117 
00118   virtual void add_interface(Interface *interface) throw()
00119   {
00120     printf("Listener: Adding interface %s (this: %p)\n", interface->uid(), this);
00121     bbil_add_data_interface(interface);
00122     try {
00123       if ( ! interface->is_writer() ) {
00124         printf("Trying to add non-writing instance as message listener, this will fail\n");
00125       }
00126       bbil_add_message_interface(interface);
00127       if ( ! interface->is_writer() ) {
00128         printf("Did not fail!? BUG!\n");
00129       }
00130     } catch (Exception &e) {
00131       if ( ! interface->is_writer() ) {
00132         printf("Failed as expected (%s). Good.\n", e.what());
00133       }
00134     }
00135     bbil_add_reader_interface(interface);
00136     bbil_add_writer_interface(interface);
00137   }
00138 
00139  private:
00140   BlackBoard *__bb;
00141 };
00142 
00143 
00144 int
00145 main(int argc, char **argv)
00146 {
00147   LibLogger::init();
00148   Thread::init_main();
00149 
00150   //RemoteBlackBoard *bb = new RemoteBlackBoard("localhost", 1910);
00151   BlackBoard *bb = new LocalBlackBoard(BLACKBOARD_MEMSIZE);
00152 
00153   QaBBEventListener qabbel(bb);
00154 
00155   TestInterface *ti_writer_1;
00156   TestInterface *ti_writer_2;
00157   TestInterface *ti_writer_3;
00158   TestInterface *ti_writer_4;
00159   TestInterface *ti_writer_5;
00160   TestInterface *ti_writer_6;
00161 
00162   TestInterface *ti_reader_1;
00163   TestInterface *ti_reader_2;
00164 
00165   try {
00166     cout << "Opening interfaces.. (SomeID *)" << endl;
00167     ti_writer_1 = bb->open_for_writing<TestInterface>("SomeID 1");
00168     ti_reader_1 = bb->open_for_reading<TestInterface>("SomeID 1");
00169     ti_writer_2 = bb->open_for_writing<TestInterface>("SomeID 2");
00170     ti_reader_2 = bb->open_for_reading<TestInterface>("SomeID reader 1");
00171 
00172     qabbel.add_interface(ti_writer_1);
00173     qabbel.add_interface(ti_writer_2);
00174     qabbel.add_interface(ti_reader_2);
00175     bb->register_listener(&qabbel);
00176     bb->register_observer(&qabbel);
00177 
00178     cout << "Opening interfaces.. (SomeID 3, should NOT trigger BBIO)" << endl;
00179     ti_writer_3 = bb->open_for_writing<TestInterface>("SomeID 3");
00180     cout << "Opening interfaces.. (AnotherID *, SHOULD trigger BBIO)" << endl;
00181     ti_writer_4 = bb->open_for_writing<TestInterface>("AnotherID 1");
00182     ti_writer_5 = bb->open_for_writing<TestInterface>("AnotherID 2");
00183     ti_writer_6 = bb->open_for_writing<TestInterface>("AnotherID 3");
00184     cout << "success" << endl;
00185   } catch (Exception &e) {
00186     cout << "failed! Aborting" << endl;
00187     e.print_trace();
00188     exit(1);
00189   }
00190 
00191   usleep(100000);
00192 
00193   std::list<TestInterface *> readers = bb->open_multiple_for_reading<TestInterface>();
00194   usleep(100000);
00195   for (std::list<TestInterface *>::iterator i = readers.begin(); i != readers.end(); ++i) {
00196     printf("Opened reader for interface %s of type %s\n", (*i)->id(), (*i)->type());
00197     bb->close(*i);
00198   }
00199 
00200   usleep(100000);
00201 
00202   const char* pattern = "AnotherID *";
00203   readers = bb->open_multiple_for_reading<TestInterface>(pattern);
00204   printf("Found %zu interfaces with pattern \"%s\"\n", readers.size(), pattern);
00205   for (std::list<TestInterface *>::iterator i = readers.begin(); i != readers.end(); ++i) {
00206     printf("Opened reader for interface %s of type %s\n", (*i)->id(), (*i)->type());
00207     bb->close(*i);
00208   }
00209 
00210   usleep(100000);
00211 
00212   printf("Sending a message to test message received event\n");
00213   TestInterface::SetTestIntMessage *m = new TestInterface::SetTestIntMessage(27);
00214   unsigned int msg_id = ti_reader_1->msgq_enqueue(m);
00215   printf("Message ID = %u, enqueued messages: %u\n", msg_id, ti_writer_1->msgq_size());
00216 
00217   printf("Sending message triggering update in event handler\n");
00218   TestInterface::SetTestStringMessage *m2 =
00219     new TestInterface::SetTestStringMessage("Foo");
00220   ti_reader_1->msgq_enqueue(m2);
00221 
00222   printf("Sending another message, should NOT trigger BBIL!\n");
00223   TestInterface::SetTestIntMessage *m3 = new TestInterface::SetTestIntMessage(27);
00224   ti_reader_1->msgq_enqueue(m3);
00225   printf("Another message sent!\n");
00226 
00227   printf("Removing writer 1. BBIL output should appear\n");
00228   bb->close(ti_writer_1);
00229   printf("Removing writer 1 DONE\n");
00230 
00231   bb->unregister_listener(&qabbel);
00232   usleep(100000);
00233 
00234   printf("Removing other writers. No warning should appear.\n");
00235   bb->close(ti_writer_2);
00236   bb->close(ti_writer_3);
00237   bb->close(ti_writer_4);
00238   bb->close(ti_writer_5);
00239   bb->close(ti_writer_6);
00240 
00241   bb->close(ti_reader_1);
00242   bb->close(ti_reader_2);
00243 
00244   usleep(100000);
00245 
00246   delete bb;
00247   Thread::destroy_main();
00248   LibLogger::finalize();
00249 }
00250 
00251 
00252 /// @endcond