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
44using namespace std;
45using namespace fawkes;
46
47class QaBBEventListener : public BlackBoardInterfaceListener, public BlackBoardInterfaceObserver
48{
49public:
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) noexcept
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) noexcept
64 {
65 printf("BBIO: Interface %s of type %s has been destroyed\n", id, type);
66 }
67
68 virtual void
69 bb_interface_data_refreshed(Interface *interface) noexcept
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) noexcept
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) noexcept
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) noexcept
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) noexcept
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) noexcept
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) noexcept
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
149private:
150 BlackBoard *bb_;
151};
152
153int
154main(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
BlackBoard interface listener.
BlackBoard interface observer.
The BlackBoard abstract class.
Definition: blackboard.h:46
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for reading.
virtual void register_observer(BlackBoardInterfaceObserver *observer)
Register BB interface observer.
Definition: blackboard.cpp:225
virtual void unregister_listener(BlackBoardInterfaceListener *listener)
Unregister BB interface listener.
Definition: blackboard.cpp:212
virtual Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for writing.
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.
virtual void register_listener(BlackBoardInterfaceListener *listener, ListenerRegisterFlag flag=BBIL_FLAG_ALL)
Register BB event listener.
Definition: blackboard.cpp:185
virtual void close(Interface *interface)=0
Close interface.
Base class for exceptions in Fawkes.
Definition: exception.h:36
void print_trace() noexcept
Prints trace to stderr.
Definition: exception.cpp:601
virtual const char * what() const noexcept
Get primary string.
Definition: exception.cpp:639
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:80
unsigned int msgq_enqueue(Message *message, bool proxy=false)
Enqueue message at end of queue.
Definition: interface.cpp:915
unsigned int msgq_size()
Get size of message queue.
Definition: interface.cpp:1045
Local BlackBoard.
Definition: local.h:45
Base class for all messages passed through interfaces in Fawkes BlackBoard.
Definition: message.h:44
SetTestIntMessage Fawkes BlackBoard Interface Message.
Definition: TestInterface.h:69
SetTestStringMessage Fawkes BlackBoard Interface Message.
Definition: TestInterface.h:95
TestInterface Fawkes BlackBoard Interface.
Definition: TestInterface.h:34
Fawkes library namespace.