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 /// @cond QA
25 
26 #include <blackboard/bbconfig.h>
27 #include <blackboard/exceptions.h>
28 #include <blackboard/interface_listener.h>
29 #include <blackboard/interface_observer.h>
30 #include <blackboard/local.h>
31 #include <blackboard/remote.h>
32 #include <core/exceptions/system.h>
33 #include <core/threading/thread.h>
34 #include <interfaces/TestInterface.h>
35 #include <logging/liblogger.h>
36 
37 #include <cstdio>
38 #include <cstdlib>
39 #include <cstring>
40 #include <iostream>
41 #include <signal.h>
42 #include <vector>
43 
44 using namespace std;
45 using namespace fawkes;
46 
47 class QaBBEventListener : public BlackBoardInterfaceListener, public BlackBoardInterfaceObserver
48 {
49 public:
50  QaBBEventListener(BlackBoard *bb) : BlackBoardInterfaceListener("QaBBEventListener"), bb_(bb)
51  {
52  bbio_add_observed_create("TestInterface", "AnotherID *");
53  bbio_add_observed_destroy("TestInterface");
54  }
55 
56  virtual void
57  bb_interface_created(const char *type, const char *id) throw()
58  {
59  printf("BBIO: Interface %s of type %s has been created\n", id, type);
60  }
61 
62  virtual void
63  bb_interface_destroyed(const char *type, const char *id) throw()
64  {
65  printf("BBIO: Interface %s of type %s has been destroyed\n", id, type);
66  }
67 
68  virtual void
69  bb_interface_data_changed(Interface *interface) throw()
70  {
71  printf("BBIL: Data in interface %s has been modified\n", interface->uid());
72  }
73 
74  virtual bool
75  bb_interface_message_received(Interface *interface, Message *message) throw()
76  {
77  printf("BBIL: Message of type %s for interface %s has been received\n",
78  message->type(),
79  interface->uid());
80  // do not enqueue, then we do not have to flush it
81  if (strcmp(message->type(), "SetTestStringMessage") == 0) {
82  printf("BBIL: Received message of type %s, unregistering from inside "
83  "event handler\n",
84  message->type());
85  bbil_remove_message_interface(interface);
86  bb_->update_listener(this);
87  }
88  return false;
89  }
90 
91  virtual void
92  bb_interface_writer_added(Interface *interface, unsigned int instance_serial) throw()
93  {
94  printf("BBIL: Writer has been added to interface %s/%u (event serial %u)\n",
95  interface->uid(),
96  interface->serial(),
97  instance_serial);
98  }
99 
100  virtual void
101  bb_interface_writer_removed(Interface *interface, unsigned int instance_serial) throw()
102  {
103  printf("BBIL: Writer has been removed from interface %s/%u (event serial %u)\n",
104  interface->uid(),
105  interface->serial(),
106  instance_serial);
107  }
108 
109  virtual void
110  bb_interface_reader_added(Interface *interface, unsigned int instance_serial) throw()
111  {
112  printf("BBIL: Reader has been added to interface %s/%u (event serial %u)\n",
113  interface->uid(),
114  interface->serial(),
115  instance_serial);
116  }
117 
118  virtual void
119  bb_interface_reader_removed(Interface *interface, unsigned int instance_serial) throw()
120  {
121  printf("BBIL: Reader has been removed from interface %s/%u (event serial %u)\n",
122  interface->uid(),
123  interface->serial(),
124  instance_serial);
125  }
126 
127  virtual void
128  add_interface(Interface *interface) throw()
129  {
130  printf("Listener: Adding interface %s (this: %p)\n", interface->uid(), this);
131  bbil_add_data_interface(interface);
132  try {
133  if (!interface->is_writer()) {
134  printf("Trying to add non-writing instance as message listener, this will fail\n");
135  }
136  bbil_add_message_interface(interface);
137  if (!interface->is_writer()) {
138  printf("Did not fail!? BUG!\n");
139  }
140  } catch (Exception &e) {
141  if (!interface->is_writer()) {
142  printf("Failed as expected (%s). Good.\n", e.what());
143  }
144  }
145  bbil_add_reader_interface(interface);
146  bbil_add_writer_interface(interface);
147  }
148 
149 private:
150  BlackBoard *bb_;
151 };
152 
153 int
154 main(int argc, char **argv)
155 {
156  LibLogger::init();
157  Thread::init_main();
158 
159  //RemoteBlackBoard *bb = new RemoteBlackBoard("localhost", 1910);
160  BlackBoard *bb = new LocalBlackBoard(BLACKBOARD_MEMSIZE);
161 
162  QaBBEventListener qabbel(bb);
163 
164  TestInterface *ti_writer_1;
165  TestInterface *ti_writer_2;
166  TestInterface *ti_writer_3;
167  TestInterface *ti_writer_4;
168  TestInterface *ti_writer_5;
169  TestInterface *ti_writer_6;
170 
171  TestInterface *ti_reader_1;
172  TestInterface *ti_reader_2;
173 
174  try {
175  cout << "Opening interfaces.. (SomeID *)" << endl;
176  ti_writer_1 = bb->open_for_writing<TestInterface>("SomeID 1");
177  ti_reader_1 = bb->open_for_reading<TestInterface>("SomeID 1");
178  ti_writer_2 = bb->open_for_writing<TestInterface>("SomeID 2");
179  ti_reader_2 = bb->open_for_reading<TestInterface>("SomeID reader 1");
180 
181  qabbel.add_interface(ti_writer_1);
182  qabbel.add_interface(ti_writer_2);
183  qabbel.add_interface(ti_reader_2);
184  bb->register_listener(&qabbel);
185  bb->register_observer(&qabbel);
186 
187  cout << "Opening interfaces.. (SomeID 3, should NOT trigger BBIO)" << endl;
188  ti_writer_3 = bb->open_for_writing<TestInterface>("SomeID 3");
189  cout << "Opening interfaces.. (AnotherID *, SHOULD trigger BBIO)" << endl;
190  ti_writer_4 = bb->open_for_writing<TestInterface>("AnotherID 1");
191  ti_writer_5 = bb->open_for_writing<TestInterface>("AnotherID 2");
192  ti_writer_6 = bb->open_for_writing<TestInterface>("AnotherID 3");
193  cout << "success" << endl;
194  } catch (Exception &e) {
195  cout << "failed! Aborting" << endl;
196  e.print_trace();
197  exit(1);
198  }
199 
200  usleep(100000);
201 
202  std::list<TestInterface *> readers = bb->open_multiple_for_reading<TestInterface>();
203  usleep(100000);
204  for (std::list<TestInterface *>::iterator i = readers.begin(); i != readers.end(); ++i) {
205  printf("Opened reader for interface %s of type %s\n", (*i)->id(), (*i)->type());
206  bb->close(*i);
207  }
208 
209  usleep(100000);
210 
211  const char *pattern = "AnotherID *";
212  readers = bb->open_multiple_for_reading<TestInterface>(pattern);
213  printf("Found %zu interfaces with pattern \"%s\"\n", readers.size(), pattern);
214  for (std::list<TestInterface *>::iterator i = readers.begin(); i != readers.end(); ++i) {
215  printf("Opened reader for interface %s of type %s\n", (*i)->id(), (*i)->type());
216  bb->close(*i);
217  }
218 
219  usleep(100000);
220 
221  printf("Sending a message to test message received event\n");
223  unsigned int msg_id = ti_reader_1->msgq_enqueue(m);
224  printf("Message ID = %u, enqueued messages: %u\n", msg_id, ti_writer_1->msgq_size());
225 
226  printf("Sending message triggering update in event handler\n");
228  ti_reader_1->msgq_enqueue(m2);
229 
230  printf("Sending another message, should NOT trigger BBIL!\n");
232  ti_reader_1->msgq_enqueue(m3);
233  printf("Another message sent!\n");
234 
235  printf("Removing writer 1. BBIL output should appear\n");
236  bb->close(ti_writer_1);
237  printf("Removing writer 1 DONE\n");
238 
239  bb->unregister_listener(&qabbel);
240  usleep(100000);
241 
242  printf("Removing other writers. No warning should appear.\n");
243  bb->close(ti_writer_2);
244  bb->close(ti_writer_3);
245  bb->close(ti_writer_4);
246  bb->close(ti_writer_5);
247  bb->close(ti_writer_6);
248 
249  bb->close(ti_reader_1);
250  bb->close(ti_reader_2);
251 
252  usleep(100000);
253 
254  delete bb;
255  Thread::destroy_main();
256  LibLogger::finalize();
257 }
258 
259 /// @endcond
fawkes::BlackBoard::register_listener
virtual void register_listener(BlackBoardInterfaceListener *listener, ListenerRegisterFlag flag=BBIL_FLAG_ALL)
Register BB event listener.
Definition: blackboard.cpp:185
fawkes::Message
Base class for all messages passed through interfaces in Fawkes BlackBoard.
Definition: message.h:45
fawkes::LocalBlackBoard
Local BlackBoard.
Definition: local.h:45
fawkes::BlackBoard::unregister_listener
virtual void unregister_listener(BlackBoardInterfaceListener *listener)
Unregister BB interface listener.
Definition: blackboard.cpp:212
fawkes::BlackBoardInterfaceListener
BlackBoard interface listener.
Definition: interface_listener.h:42
fawkes::BlackBoard
The BlackBoard abstract class.
Definition: blackboard.h:46
fawkes::TestInterface::SetTestIntMessage
SetTestIntMessage Fawkes BlackBoard Interface Message.
Definition: TestInterface.h:69
fawkes::BlackBoard::close
virtual void close(Interface *interface)=0
Close interface.
fawkes
Fawkes library namespace.
fawkes::BlackBoard::register_observer
virtual void register_observer(BlackBoardInterfaceObserver *observer)
Register BB interface observer.
Definition: blackboard.cpp:225
fawkes::BlackBoardInterfaceObserver
BlackBoard interface observer.
Definition: interface_observer.h:37
fawkes::Interface
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:79
fawkes::Exception::print_trace
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:601
fawkes::Exception::what
virtual const char * what() const
Get primary string.
Definition: exception.cpp:639
fawkes::Interface::msgq_size
unsigned int msgq_size()
Get size of message queue.
Definition: interface.cpp:1012
fawkes::BlackBoard::open_for_reading
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for reading.
fawkes::Interface::msgq_enqueue
unsigned int msgq_enqueue(Message *message)
Enqueue message at end of queue.
Definition: interface.cpp:882
fawkes::BlackBoard::open_multiple_for_reading
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.
fawkes::TestInterface
TestInterface Fawkes BlackBoard Interface.
Definition: TestInterface.h:34
fawkes::BlackBoard::open_for_writing
virtual Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for writing.
fawkes::TestInterface::SetTestStringMessage
SetTestStringMessage Fawkes BlackBoard Interface Message.
Definition: TestInterface.h:95
fawkes::Exception
Base class for exceptions in Fawkes.
Definition: exception.h:36