Fawkes API  Fawkes Development Version
qa_bb_notify.cpp
1 
2 /***************************************************************************
3  * qa_bb_notify.cpp - BlackBoard notification QA
4  *
5  * Created: Mon Nov 12 14:35:53 2007
6  * Copyright 2006-2007 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 
25 /// @cond QA
26 
27 #include <blackboard/local.h>
28 #include <blackboard/remote.h>
29 #include <blackboard/exceptions.h>
30 #include <blackboard/bbconfig.h>
31 #include <blackboard/interface_listener.h>
32 #include <blackboard/interface_observer.h>
33 
34 #include <interfaces/TestInterface.h>
35 
36 #include <core/threading/thread.h>
37 #include <core/exceptions/system.h>
38 #include <logging/liblogger.h>
39 
40 #include <signal.h>
41 #include <cstdlib>
42 #include <cstdio>
43 #include <cstring>
44 
45 #include <iostream>
46 #include <vector>
47 
48 using namespace std;
49 using namespace fawkes;
50 
51 class QaBBEventListener
54 {
55  public:
56  QaBBEventListener(BlackBoard *bb)
57  : BlackBoardInterfaceListener("QaBBEventListener"),
58  __bb(bb)
59  {
60  bbio_add_observed_create("TestInterface", "AnotherID *");
61  bbio_add_observed_destroy("TestInterface");
62  }
63 
64  virtual void bb_interface_created(const char *type, const char *id) throw()
65  {
66  printf("BBIO: Interface %s of type %s has been created\n", id, type);
67  }
68 
69  virtual void bb_interface_destroyed(const char *type, const char *id) throw()
70  {
71  printf("BBIO: Interface %s of type %s has been destroyed\n", id, type);
72  }
73 
74 
75  virtual void bb_interface_data_changed(Interface *interface) throw()
76  {
77  printf("BBIL: Data in interface %s has been modified\n", interface->uid());
78  }
79 
80  virtual bool bb_interface_message_received(Interface *interface, Message *message) throw()
81  {
82  printf("BBIL: Message of type %s for interface %s has been received\n",
83  message->type(), interface->uid());
84  // do not enqueue, then we do not have to flush it
85  if (strcmp(message->type(), "SetTestStringMessage") == 0) {
86  printf("BBIL: Received message of type %s, unregistering from inside "
87  "event handler\n", message->type());
88  bbil_remove_message_interface(interface);
89  __bb->update_listener(this);
90  }
91  return false;
92  }
93 
94  virtual void bb_interface_writer_added(Interface *interface, unsigned int instance_serial) throw()
95  {
96  printf("BBIL: Writer has been added to interface %s/%u (event serial %u)\n",
97  interface->uid(), interface->serial(), instance_serial);
98  }
99 
100  virtual void bb_interface_writer_removed(Interface *interface, unsigned int instance_serial) throw()
101  {
102  printf("BBIL: Writer has been removed from interface %s/%u (event serial %u)\n",
103  interface->uid(), interface->serial(), instance_serial);
104  }
105 
106  virtual void bb_interface_reader_added(Interface *interface, unsigned int instance_serial) throw()
107  {
108  printf("BBIL: Reader has been added to interface %s/%u (event serial %u)\n",
109  interface->uid(), interface->serial(), instance_serial);
110  }
111 
112  virtual void bb_interface_reader_removed(Interface *interface, unsigned int instance_serial) throw()
113  {
114  printf("BBIL: Reader has been removed from interface %s/%u (event serial %u)\n",
115  interface->uid(), interface->serial(), instance_serial);
116  }
117 
118  virtual void add_interface(Interface *interface) throw()
119  {
120  printf("Listener: Adding interface %s (this: %p)\n", interface->uid(), this);
121  bbil_add_data_interface(interface);
122  try {
123  if ( ! interface->is_writer() ) {
124  printf("Trying to add non-writing instance as message listener, this will fail\n");
125  }
126  bbil_add_message_interface(interface);
127  if ( ! interface->is_writer() ) {
128  printf("Did not fail!? BUG!\n");
129  }
130  } catch (Exception &e) {
131  if ( ! interface->is_writer() ) {
132  printf("Failed as expected (%s). Good.\n", e.what());
133  }
134  }
135  bbil_add_reader_interface(interface);
136  bbil_add_writer_interface(interface);
137  }
138 
139  private:
140  BlackBoard *__bb;
141 };
142 
143 
144 int
145 main(int argc, char **argv)
146 {
147  LibLogger::init();
148  Thread::init_main();
149 
150  //RemoteBlackBoard *bb = new RemoteBlackBoard("localhost", 1910);
151  BlackBoard *bb = new LocalBlackBoard(BLACKBOARD_MEMSIZE);
152 
153  QaBBEventListener qabbel(bb);
154 
155  TestInterface *ti_writer_1;
156  TestInterface *ti_writer_2;
157  TestInterface *ti_writer_3;
158  TestInterface *ti_writer_4;
159  TestInterface *ti_writer_5;
160  TestInterface *ti_writer_6;
161 
162  TestInterface *ti_reader_1;
163  TestInterface *ti_reader_2;
164 
165  try {
166  cout << "Opening interfaces.. (SomeID *)" << endl;
167  ti_writer_1 = bb->open_for_writing<TestInterface>("SomeID 1");
168  ti_reader_1 = bb->open_for_reading<TestInterface>("SomeID 1");
169  ti_writer_2 = bb->open_for_writing<TestInterface>("SomeID 2");
170  ti_reader_2 = bb->open_for_reading<TestInterface>("SomeID reader 1");
171 
172  qabbel.add_interface(ti_writer_1);
173  qabbel.add_interface(ti_writer_2);
174  qabbel.add_interface(ti_reader_2);
175  bb->register_listener(&qabbel);
176  bb->register_observer(&qabbel);
177 
178  cout << "Opening interfaces.. (SomeID 3, should NOT trigger BBIO)" << endl;
179  ti_writer_3 = bb->open_for_writing<TestInterface>("SomeID 3");
180  cout << "Opening interfaces.. (AnotherID *, SHOULD trigger BBIO)" << endl;
181  ti_writer_4 = bb->open_for_writing<TestInterface>("AnotherID 1");
182  ti_writer_5 = bb->open_for_writing<TestInterface>("AnotherID 2");
183  ti_writer_6 = bb->open_for_writing<TestInterface>("AnotherID 3");
184  cout << "success" << endl;
185  } catch (Exception &e) {
186  cout << "failed! Aborting" << endl;
187  e.print_trace();
188  exit(1);
189  }
190 
191  usleep(100000);
192 
193  std::list<TestInterface *> readers = bb->open_multiple_for_reading<TestInterface>();
194  usleep(100000);
195  for (std::list<TestInterface *>::iterator i = readers.begin(); i != readers.end(); ++i) {
196  printf("Opened reader for interface %s of type %s\n", (*i)->id(), (*i)->type());
197  bb->close(*i);
198  }
199 
200  usleep(100000);
201 
202  const char* pattern = "AnotherID *";
203  readers = bb->open_multiple_for_reading<TestInterface>(pattern);
204  printf("Found %zu interfaces with pattern \"%s\"\n", readers.size(), pattern);
205  for (std::list<TestInterface *>::iterator i = readers.begin(); i != readers.end(); ++i) {
206  printf("Opened reader for interface %s of type %s\n", (*i)->id(), (*i)->type());
207  bb->close(*i);
208  }
209 
210  usleep(100000);
211 
212  printf("Sending a message to test message received event\n");
214  unsigned int msg_id = ti_reader_1->msgq_enqueue(m);
215  printf("Message ID = %u, enqueued messages: %u\n", msg_id, ti_writer_1->msgq_size());
216 
217  printf("Sending message triggering update in event handler\n");
220  ti_reader_1->msgq_enqueue(m2);
221 
222  printf("Sending another message, should NOT trigger BBIL!\n");
224  ti_reader_1->msgq_enqueue(m3);
225  printf("Another message sent!\n");
226 
227  printf("Removing writer 1. BBIL output should appear\n");
228  bb->close(ti_writer_1);
229  printf("Removing writer 1 DONE\n");
230 
231  bb->unregister_listener(&qabbel);
232  usleep(100000);
233 
234  printf("Removing other writers. No warning should appear.\n");
235  bb->close(ti_writer_2);
236  bb->close(ti_writer_3);
237  bb->close(ti_writer_4);
238  bb->close(ti_writer_5);
239  bb->close(ti_writer_6);
240 
241  bb->close(ti_reader_1);
242  bb->close(ti_reader_2);
243 
244  usleep(100000);
245 
246  delete bb;
247  Thread::destroy_main();
248  LibLogger::finalize();
249 }
250 
251 
252 /// @endcond
virtual void register_observer(BlackBoardInterfaceObserver *observer)
Register BB interface observer.
Definition: blackboard.cpp:230
Base class for all messages passed through interfaces in Fawkes BlackBoard.
Definition: message.h:44
Fawkes library namespace.
STL namespace.
Local BlackBoard.
Definition: local.h:44
virtual const char * what() const
Get primary string.
Definition: exception.cpp:661
virtual void unregister_listener(BlackBoardInterfaceListener *listener)
Unregister BB interface listener.
Definition: blackboard.cpp:218
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:79
unsigned int msgq_size()
Get size of message queue.
Definition: interface.cpp:1032
virtual void register_listener(BlackBoardInterfaceListener *listener, ListenerRegisterFlag flag=BBIL_FLAG_ALL)
Register BB event listener.
Definition: blackboard.cpp:190
Base class for exceptions in Fawkes.
Definition: exception.h:36
SetTestIntMessage Fawkes BlackBoard Interface Message.
Definition: TestInterface.h:68
virtual std::list< Interface * > open_multiple_for_reading(const char *type_pattern, const char *id_pattern="*", const char *owner=NULL)=0
Open multiple interfaces for reading.
BlackBoard interface observer.
unsigned int msgq_enqueue(Message *message)
Enqueue message at end of queue.
Definition: interface.cpp:903
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:619
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for reading.
The BlackBoard abstract class.
Definition: blackboard.h:48
SetTestStringMessage Fawkes BlackBoard Interface Message.
Definition: TestInterface.h:94
virtual Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for writing.
BlackBoard interface listener.
TestInterface Fawkes BlackBoard Interface.
Definition: TestInterface.h:33
virtual void close(Interface *interface)=0
Close interface.