Fawkes API Fawkes Development Version
blackboard_adapter.cpp
1
2/***************************************************************************
3 * blackboard_adapter.cpp - PLEXIL adapter for Fawkes' blackboard
4 *
5 * Created: Sun Feb 17 12:52:45 2019 +0100
6 * Copyright 2006-2019 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.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * Read the full text in the LICENSE.GPL file in the doc directory.
21 */
22
23#include "blackboard_adapter.h"
24
25#include "utils.h"
26
27#include <utils/misc/string_conversions.h>
28#include <utils/time/time.h>
29
30#include <AdapterConfiguration.hh>
31#include <AdapterExecInterface.hh>
32#include <AdapterFactory.hh>
33#include <CachedValue.hh>
34#include <Command.hh>
35#include <Error.hh>
36#include <State.hh>
37#include <StateCacheEntry.hh>
38
39using namespace fawkes;
40
41/** @class BlackboardPlexilAdapter "blackboard_adapter.h"
42 * Plexil adapter to provide access to Fawkes blackboard
43 * @author Tim Niemueller
44 */
45
46/** Constructor.
47 * @param execInterface Reference to the parent AdapterExecInterface object.
48 */
49BlackboardPlexilAdapter::BlackboardPlexilAdapter(PLEXIL::AdapterExecInterface &execInterface)
50: InterfaceAdapter(execInterface), BlackBoardInterfaceListener("PlexilBB")
51{
52}
53
54/** Constructor from configuration XML.
55 * @param execInterface Reference to the parent AdapterExecInterface object.
56 * @param xml A const reference to the XML element describing this adapter
57 * @note The instance maintains a shared pointer to the XML.
58 */
59BlackboardPlexilAdapter::BlackboardPlexilAdapter(PLEXIL::AdapterExecInterface &execInterface,
60 pugi::xml_node const xml)
61: InterfaceAdapter(execInterface, xml), BlackBoardInterfaceListener("PlexilBB")
62{
63}
64
65/** Destructor. */
67{
68}
69
70/** Initialize adapter.
71 * @return true if initialization was successful, false otherwise.
72 */
73bool
75{
76 logger_ = reinterpret_cast<fawkes::Logger *>(m_execInterface.getProperty("::Fawkes::Logger"));
77 blackboard_ =
78 reinterpret_cast<fawkes::BlackBoard *>(m_execInterface.getProperty("::Fawkes::BlackBoard"));
79
80 namespace p = std::placeholders;
81 commands_ = {{"BB_open_for_reading",
82 std::bind(&BlackboardPlexilAdapter::bb_open_for_reading, this, p::_1)},
83 {"BB_close", std::bind(&BlackboardPlexilAdapter::bb_close, this, p::_1)},
84 {"BB_read", std::bind(&BlackboardPlexilAdapter::bb_read, this, p::_1)},
85 {"BB_read_all", std::bind(&BlackboardPlexilAdapter::bb_read_all, this, p::_1)},
86 {"BB_print", std::bind(&BlackboardPlexilAdapter::bb_print, this, p::_1)}};
87
88 std::vector<std::string> lookups = {"BB_changed",
89 "BB_int",
90 "BB_real",
91 "BB_bool",
92 "BB_string",
93 "BB_field_length",
94 "BB_int_at",
95 "BB_real_at",
96 "BB_bool_at"};
97
98 for (const auto &c : commands_) {
99 PLEXIL::g_configuration->registerCommandInterface(c.first, this);
100 }
101
102 for (const auto &l : lookups) {
103 PLEXIL::g_configuration->registerLookupInterface(l, this);
104 }
105
106 blackboard_->register_listener(this, BlackBoard::BBIL_FLAG_DATA);
107
108 return true;
109}
110
111/** Start adapter.
112 * @return true if starting was successful, false otherwise.
113 */
114bool
116{
117 return true;
118}
119
120/** Stop adapter.
121 * @return true if successful, false otherwise.
122 */
123bool
125{
126 return true;
127}
128
129/** Reset adapter.
130 * @return true if successful, false otherwise.
131 */
132bool
134{
135 return true;
136}
137
138/** Shut adapter down.
139 * @return true if successful, false otherwise.
140 */
141bool
143{
144 blackboard_->unregister_listener(this);
145
146 for (const auto &if_entry : ifs_read_) {
147 debugMsg("BlackboardAdapter:close",
148 "Closing " << if_entry.second->type() << "::" << if_entry.second->id());
149 blackboard_->close(if_entry.second);
150 }
151 ifs_read_.clear();
152 return true;
153}
154
155/** Immediate lookup of value.
156 * @param state state variable to lookup
157 * @param cache_entry cache entry for retrieved value
158 */
159void
160BlackboardPlexilAdapter::lookupNow(PLEXIL::State const &state, PLEXIL::StateCacheEntry &cache_entry)
161{
162 std::vector<PLEXIL::Value> const &params = state.parameters();
163 if (state.name() == "BB_changed") {
164 if (!verify_args(params, "BlackboardAdapter:BB_changed", {{"uid", PLEXIL::STRING_TYPE}})) {
165 cache_entry.setUnknown();
166 return;
167 }
168 std::string uid;
169 params[0].getValue(uid);
170
171 std::unique_lock<std::mutex> lock(ifs_read_mutex_);
172 if (ifs_read_.find(uid) == ifs_read_.end()) {
173 logger_->log_warn("PlexilBB",
174 "BB_changed: unknown interface %s, forgot to open?",
175 uid.c_str());
176 cache_entry.setUnknown();
177 return;
178 }
179 cache_entry.update(ifs_read_[uid]->refreshed());
180 } else if (state.name() == "BB_int" || state.name() == "BB_int_at" || state.name() == "BB_real"
181 || state.name() == "BB_real_at" || state.name() == "BB_bool"
182 || state.name() == "BB_bool_at" || state.name() == "BB_string"
183 || state.name() == "BB_field_length") {
184 bool is_indexed_version = false;
185 if (state.name() == "BB_int" || state.name() == "BB_real" || state.name() == "BB_bool"
186 || state.name() == "BB_string" || state.name() == "BB_field_length") {
187 if (!verify_args(params,
188 "BlackboardAdapter:" + state.name(),
189 {{"uid", PLEXIL::STRING_TYPE}, {"field", PLEXIL::STRING_TYPE}})) {
190 cache_entry.setUnknown();
191 return;
192 }
193 } else {
194 is_indexed_version = true;
195 if (!verify_args(params,
196 "BlackboardAdapter:" + state.name(),
197 {{"uid", PLEXIL::STRING_TYPE},
198 {"field", PLEXIL::STRING_TYPE},
199 {"index", PLEXIL::INTEGER_TYPE}})) {
200 cache_entry.setUnknown();
201 return;
202 }
203 }
204 std::string uid;
205 std::string field;
206 int index = 0;
207 params[0].getValue(uid);
208 params[1].getValue(field);
209
210 if (is_indexed_version) {
211 params[2].getValue(index);
212 }
213
214 std::unique_lock<std::mutex> lock(ifs_read_mutex_);
215 if (ifs_read_.find(uid) == ifs_read_.end()) {
216 logger_->log_warn("PlexilBB",
217 "%s: unknown interface %s, forgot to open?",
218 state.name().c_str(),
219 uid.c_str());
220 cache_entry.setUnknown();
221 return;
222 }
223 bool found = false;
224 if (state.name().compare(0, 6, "BB_int") == 0) {
225 for (auto f = ifs_read_[uid]->fields(); f != ifs_read_[uid]->fields_end(); ++f) {
226 if (field == f.get_name()) {
227 found = true;
228 bool valid = true;
229 PLEXIL::Integer value;
230 switch (f.get_type()) {
231 case IFT_INT8: value = f.get_int8(index); break;
232 case IFT_UINT8: value = f.get_uint8(index); break;
233 case IFT_INT16: value = f.get_int16(index); break;
234 case IFT_UINT16: value = f.get_uint16(index); break;
235 case IFT_INT32: value = f.get_int32(index); break;
236 case IFT_UINT32: value = f.get_uint32(index); break;
237 case IFT_INT64: value = f.get_int64(index); break;
238 case IFT_UINT64: value = f.get_uint64(index); break;
239 default: valid = false; break;
240 }
241 if (valid) {
242 cache_entry.update(value);
243 } else {
244 logger_->log_warn("PlexilBB",
245 "BB_int: field '%s' of %s of type %s",
246 field.c_str(),
247 uid.c_str(),
248 f.get_typename());
249 cache_entry.setUnknown();
250 }
251 }
252 break;
253 }
254 } else if (state.name().compare(0, 7, "BB_real") == 0) {
255 for (auto f = ifs_read_[uid]->fields(); f != ifs_read_[uid]->fields_end(); ++f) {
256 if (field == f.get_name()) {
257 found = true;
258 bool valid = true;
259 PLEXIL::Real value;
260 switch (f.get_type()) {
261 case IFT_FLOAT: value = f.get_float(index); break;
262 case IFT_DOUBLE: value = f.get_double(index); break;
263 case IFT_INT8: value = f.get_int8(index); break;
264 case IFT_UINT8: value = f.get_uint8(index); break;
265 case IFT_INT16: value = f.get_int16(index); break;
266 case IFT_UINT16: value = f.get_uint16(index); break;
267 case IFT_INT32: value = f.get_int32(index); break;
268 case IFT_UINT32: value = f.get_uint32(index); break;
269 case IFT_INT64: value = f.get_int64(index); break;
270 case IFT_UINT64: value = f.get_uint64(index); break;
271 default: valid = false; break;
272 }
273 if (valid) {
274 cache_entry.update(value);
275 } else {
276 logger_->log_warn("PlexilBB",
277 "BB_int: field %s of %s of type %s",
278 field.c_str(),
279 uid.c_str(),
280 f.get_typename());
281 cache_entry.setUnknown();
282 }
283 }
284 break;
285 }
286 } else if (state.name().compare(0, 7, "BB_bool") == 0) {
287 for (auto f = ifs_read_[uid]->fields(); f != ifs_read_[uid]->fields_end(); ++f) {
288 if (field == f.get_name()) {
289 found = true;
290 PLEXIL::Boolean value;
291 if (f.get_type() == IFT_BOOL) {
292 value = f.get_bool(index);
293 cache_entry.update(value);
294 } else {
295 logger_->log_warn("PlexilBB",
296 "BB_int: field %s of %s of type %s",
297 field.c_str(),
298 uid.c_str(),
299 f.get_typename());
300 cache_entry.setUnknown();
301 }
302 }
303 break;
304 }
305 } else if (state.name() == "BB_string") {
306 for (auto f = ifs_read_[uid]->fields(); f != ifs_read_[uid]->fields_end(); ++f) {
307 if (field == f.get_name()) {
308 found = true;
309 PLEXIL::String value;
310 value = f.get_value_string();
311 cache_entry.update(value);
312 }
313 break;
314 }
315 } else if (state.name() == "BB_field_length") {
316 for (auto f = ifs_read_[uid]->fields(); f != ifs_read_[uid]->fields_end(); ++f) {
317 if (field == f.get_name()) {
318 found = true;
319 PLEXIL::Integer value;
320 value = f.get_length();
321 cache_entry.update(value);
322 }
323 break;
324 }
325 }
326 if (!found) {
327 logger_->log_warn("PlexilBB",
328 "%s: unknown field '%s' for interface %s",
329 state.name().c_str(),
330 field.c_str(),
331 uid.c_str());
332 cache_entry.setUnknown();
333 return;
334 }
335
336 } else {
337 logger_->log_warn("PlexilBB", "unknown lookup '%s'", state.name().c_str());
338 cache_entry.setUnknown();
339 return;
340 }
341}
342
343/** Subscribe to updates for given state.
344 * @param state state variable to subscribe for
345 */
346void
347BlackboardPlexilAdapter::subscribe(const PLEXIL::State &state)
348{
349 std::vector<PLEXIL::Value> const &params = state.parameters();
350 if (params.size() == 0 || params[0].valueType() != PLEXIL::STRING_TYPE) {
351 logger_->log_error("PlexilBB", "Invalid asynchronous lookup for %s", state.name().c_str());
352 return;
353 }
354 std::string uid;
355 params[0].getValue(uid);
356
357 std::unique_lock<std::mutex> lock(ifs_read_mutex_);
358 if (ifs_read_.find(uid) == ifs_read_.end()) {
359 logger_->log_warn("PlexilBB",
360 "Invalid asynchronous lookup %s for unknown interface %s",
361 state.name().c_str(),
362 uid.c_str());
363 } else {
364 if (subscribed_states_.count(uid) == 0) {
365 //logger_->log_debug("PlexilBB", "Updating listener for %s", uid.c_str());
366 bbil_add_data_interface(ifs_read_[uid]);
367 blackboard_->update_listener(this, BlackBoard::BBIL_FLAG_DATA);
368 }
369 //logger_->log_debug("PlexilBB", "Subscribe for %s", state.toString().c_str());
370 debugMsg("BlackboardAdapter:subscribe", "Subscribe for " << state.toString());
371 subscribed_states_.insert({uid, state});
372 }
373}
374
375/** Unsubscribe from updates.
376 * @param state state variable to unsubscribe from
377 */
378void
379BlackboardPlexilAdapter::unsubscribe(const PLEXIL::State &state)
380{
381 std::vector<PLEXIL::Value> const &params = state.parameters();
382 if (params.size() == 0 || params[0].valueType() != PLEXIL::STRING_TYPE) {
383 logger_->log_error("PlexilBB", "Invalid asynchronous lookup for %s", state.name().c_str());
384 return;
385 }
386 std::string uid;
387 params[0].getValue(uid);
388
389 std::unique_lock<std::mutex> lock(ifs_read_mutex_);
390 if (ifs_read_.find(uid) == ifs_read_.end()) {
391 logger_->log_warn("PlexilBB",
392 "Invalid lookup %s unsubscribe for "
393 "unknown interface %s",
394 state.name().c_str(),
395 uid.c_str());
396 } else {
397 //logger_->log_debug("PlexilBB", "Unsubscribe for %s", state.toString().c_str());
398 debugMsg("BlackboardAdapter:unsubscribe", "Unsubscribe for " << state.toString());
399 auto range = subscribed_states_.equal_range(uid);
400 for (auto i = range.first; i != range.second; ++i) {
401 if (i->second == state) {
402 subscribed_states_.erase(i);
403 break;
404 }
405 }
406 if (subscribed_states_.count(uid) == 0) {
407 bbil_remove_data_interface(ifs_read_[uid]);
408 blackboard_->update_listener(this, BlackBoard::BBIL_FLAG_DATA);
409 }
410 }
411}
412
413void
414BlackboardPlexilAdapter::bb_interface_data_refreshed(fawkes::Interface *interface) noexcept
415{
416 //logger_->log_debug("PlexilBB", "Event for %s", interface->uid());
417 interface->read();
418 auto range = subscribed_states_.equal_range(interface->uid());
419 for (auto i = range.first; i != range.second; ++i) {
420 if (i->second.name() == "BB_changed") {
421 // we need to issue a read call above (otherwise we would handle the
422 // value change with the old value) but this will cause Interface::changed()
423 // to always return false. However, since this is the handler for the
424 // data changed event, we feel confident to return true as value
425 m_execInterface.handleValueChange(i->second, PLEXIL::Value(true));
426 } else {
427 PLEXIL::StateCacheEntry entry;
428 lookupNow(i->second, entry);
429 m_execInterface.handleValueChange(i->second, entry.cachedValue()->toValue());
430 }
431 }
432 m_execInterface.notifyOfExternalEvent();
433}
434
435/** Perform given command.
436 * @param cmd command to execute
437 */
438void
440{
441 std::string const &name = cmd->getName();
442
443 auto c = commands_.find(name);
444 if (c != commands_.end()) {
445 c->second(cmd);
446 } else {
447 warn("NavGraphAdapter:executeCommand: called for unknown"
448 " command "
449 << name);
450 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
451 m_execInterface.notifyOfExternalEvent();
452 }
453}
454
455void
456BlackboardPlexilAdapter::bb_open_for_reading(PLEXIL::Command *cmd)
457{
458 std::vector<PLEXIL::Value> const &args = cmd->getArgValues();
459 if (!verify_args(args,
460 "BlackboardAdapter:bb_open_for_reading",
461 {{"type", PLEXIL::STRING_TYPE}, {"id", PLEXIL::STRING_TYPE}})) {
462 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
463 m_execInterface.notifyOfExternalEvent();
464 return;
465 }
466
467 std::string if_type;
468 std::string if_id;
469 args[0].getValue(if_type);
470 args[1].getValue(if_id);
471
472 std::string uid{if_type + "::" + if_id};
473
474 //logger_->log_debug("PlexilBB", "Opening %s for reading", uid.c_str());
475 debugMsg("BlackboardAdapter:open", "Open for reading " << uid);
476
477 if (ifs_read_.find(uid) == ifs_read_.end()) {
478 try {
479 ifs_read_[uid] = blackboard_->open_for_reading(if_type.c_str(), if_id.c_str());
480 PLEXIL::g_configuration->registerLookupInterface(uid + ".changed", this);
481 } catch (Exception &e) {
482 logger_->log_warn("PlexilBB",
483 "Failed to open interface %s:%s: %s",
484 if_type.c_str(),
485 if_id.c_str(),
487 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
488 m_execInterface.notifyOfExternalEvent();
489 return;
490 }
491 }
492
493 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(true));
494 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
495 m_execInterface.notifyOfExternalEvent();
496}
497
498void
499BlackboardPlexilAdapter::bb_close(PLEXIL::Command *cmd)
500{
501 std::vector<PLEXIL::Value> const &args = cmd->getArgValues();
502 if (!verify_args(args, "BlackboardAdapter:bb_close", {{"uid", PLEXIL::STRING_TYPE}})) {
503 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
504 m_execInterface.notifyOfExternalEvent();
505 return;
506 }
507
508 std::string uid;
509 args[0].getValue(uid);
510
511 //logger_->log_debug("PlexilBB", "Closing %s", uid.c_str());
512 debugMsg("BlackboardAdapter:close", "Close " << uid);
513
514 std::unique_lock<std::mutex> lock(ifs_read_mutex_);
515 if (ifs_read_.find(uid) == ifs_read_.end()) {
516 logger_->log_warn("PlexilBB", "Interface '%s' has not been opened", uid.c_str());
517 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
518 m_execInterface.notifyOfExternalEvent();
519 return;
520 }
521
522 blackboard_->close(ifs_read_[uid]);
523 ifs_read_.erase(uid);
524
525 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
526 m_execInterface.notifyOfExternalEvent();
527}
528
529void
530BlackboardPlexilAdapter::bb_read(PLEXIL::Command *cmd)
531{
532 std::vector<PLEXIL::Value> const &args = cmd->getArgValues();
533 if (!verify_args(args, "BlackboardAdapter:bb_read", {{"uid", PLEXIL::STRING_TYPE}})) {
534 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
535 m_execInterface.notifyOfExternalEvent();
536 return;
537 }
538
539 std::string uid;
540 args[0].getValue(uid);
541
542 //logger_->log_debug("PlexilBB", "Reading %s", uid.c_str());
543 debugMsg("BlackboardAdapter:read", "Reading " << uid.c_str());
544
545 std::unique_lock<std::mutex> lock(ifs_read_mutex_);
546 if (ifs_read_.find(uid) == ifs_read_.end()) {
547 logger_->log_warn("PlexilBB", "Interface '%s' has not been opened for reading", uid.c_str());
548 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
549 m_execInterface.notifyOfExternalEvent();
550 return;
551 }
552
553 ifs_read_[uid]->read();
554
555 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
556 m_execInterface.notifyOfExternalEvent();
557}
558
559void
560BlackboardPlexilAdapter::bb_read_all(PLEXIL::Command *cmd)
561{
562 //logger_->log_debug("PlexilBB", "Reading all interfaces");
563 debugMsg("BlackboardAdapter:read", "Reading all interfaces");
564
565 std::unique_lock<std::mutex> lock(ifs_read_mutex_);
566 for (auto &i : ifs_read_) {
567 i.second->read();
568 }
569
570 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
571 m_execInterface.notifyOfExternalEvent();
572}
573
574void
575BlackboardPlexilAdapter::bb_print(PLEXIL::Command *cmd)
576{
577 std::vector<PLEXIL::Value> const &args = cmd->getArgValues();
578 if (!verify_args(args, "BlackboardAdapter:bb_print", {{"uid", PLEXIL::STRING_TYPE}})) {
579 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
580 m_execInterface.notifyOfExternalEvent();
581 return;
582 }
583
584 std::string uid;
585 args[0].getValue(uid);
586
587 std::unique_lock<std::mutex> lock(ifs_read_mutex_);
588 if (ifs_read_.find(uid) == ifs_read_.end()) {
589 logger_->log_warn("PlexilBB", "Interface '%s' has not been opened for reading", uid.c_str());
590 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
591 m_execInterface.notifyOfExternalEvent();
592 return;
593 }
594
595 try {
596 Interface *i = ifs_read_[uid];
597
598 i->read();
599 const Time *t = i->timestamp();
600
601 std::string fact = std::string("(bb-data \"type\" \"") + i->type() + "\"" + " \"id\" \""
602 + i->id() + "\"" + " \"time\" " + StringConversions::to_string(t->get_sec())
603 + " " + StringConversions::to_string(t->get_usec()) + "" + " (. ";
604
605 InterfaceFieldIterator f, f_end = i->fields_end();
606 for (f = i->fields(); f != f_end; ++f) {
607 std::string value;
608 if (f.get_type() == IFT_STRING) {
609 value = f.get_value_string();
610 std::string::size_type pos = 0;
611 while ((pos = value.find("\"", pos)) != std::string::npos) {
612 value.replace(pos, 1, "\\\"");
613 pos += 2;
614 }
615 value = std::string("\"") + value + "\"";
616 } else if (f.get_type() == IFT_ENUM) {
617 value = std::string("\"") + f.get_value_string(" ") + "\"";
618 } else {
619 value = f.get_value_string(" ");
620 std::string::size_type pos;
621 while ((pos = value.find(",")) != std::string::npos) {
622 value = value.erase(pos, 1);
623 }
624 }
625 if (f.get_length() > 1) {
626 fact += std::string(" \"") + f.get_name() + "\" [ " + value + " ]";
627 } else {
628 fact += std::string(" \"") + f.get_name() + "\" " + value;
629 }
630 }
631 fact += " .))";
632 logger_->log_info("PlexilBB", "%s", fact.c_str());
633 } catch (Exception &e) {
634 logger_->log_warn("PlexilBB",
635 "Failed to print interface '%s': %s",
636 uid.c_str(),
638 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
639 m_execInterface.notifyOfExternalEvent();
640 return;
641 }
642
643 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
644 m_execInterface.notifyOfExternalEvent();
645}
646
647extern "C" {
648void
649initFawkesBlackboardAdapter()
650{
651 REGISTER_ADAPTER(BlackboardPlexilAdapter, "FawkesBlackboardAdapter");
652}
653}
An interface adapter using standard POSIX time facilities to implement LookupNow and LookupOnChange.
virtual void executeCommand(PLEXIL::Command *cmd)
Perform given command.
virtual void unsubscribe(const PLEXIL::State &state)
Unsubscribe from updates.
virtual bool shutdown()
Shut adapter down.
virtual bool start()
Start adapter.
virtual void subscribe(const PLEXIL::State &state)
Subscribe to updates for given state.
virtual bool initialize()
Initialize adapter.
virtual void lookupNow(PLEXIL::State const &state, PLEXIL::StateCacheEntry &cacheEntry)
Immediate lookup of value.
virtual bool reset()
Reset adapter.
virtual ~BlackboardPlexilAdapter()
Destructor.
BlackboardPlexilAdapter(PLEXIL::AdapterExecInterface &execInterface)
Constructor.
virtual bool stop()
Stop adapter.
BlackBoard interface listener.
void bbil_remove_data_interface(Interface *interface)
Remove an interface to the data modification watch list.
void bbil_add_data_interface(Interface *interface)
Add an interface to the data modification watch list.
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 update_listener(BlackBoardInterfaceListener *listener, ListenerRegisterFlag flag=BBIL_FLAG_ALL)
Update BB event listener.
Definition: blackboard.cpp:197
virtual void unregister_listener(BlackBoardInterfaceListener *listener)
Unregister BB interface listener.
Definition: blackboard.cpp:212
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
virtual const char * what_no_backtrace() const noexcept
Get primary string (does not implicitly print the back trace).
Definition: exception.cpp:663
Interface field iterator.
size_t get_length() const
Get length of current field.
interface_fieldtype_t get_type() const
Get type of current field.
const char * get_name() const
Get name of current field.
const char * get_value_string(const char *array_sep=", ")
Get value of current field as string.
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:80
const char * type() const
Get type of interface.
Definition: interface.cpp:652
const Time * timestamp() const
Get timestamp of last write.
Definition: interface.cpp:714
InterfaceFieldIterator fields_end()
Invalid iterator.
Definition: interface.cpp:1240
const char * id() const
Get identifier of interface.
Definition: interface.cpp:661
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
Definition: interface.cpp:1231
void read()
Read from BlackBoard into local copy.
Definition: interface.cpp:479
Interface for logging.
Definition: logger.h:42
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
virtual void log_error(const char *component, const char *format,...)=0
Log error message.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
A class for handling time.
Definition: time.h:93
long get_usec() const
Get microseconds.
Definition: time.h:127
long get_sec() const
Get seconds.
Definition: time.h:117
Fawkes library namespace.
@ IFT_INT8
8 bit integer field
Definition: types.h:38
@ IFT_UINT32
32 bit unsigned integer field
Definition: types.h:43
@ IFT_FLOAT
float field
Definition: types.h:46
@ IFT_UINT64
64 bit unsigned integer field
Definition: types.h:45
@ IFT_UINT16
16 bit unsigned integer field
Definition: types.h:41
@ IFT_INT32
32 bit integer field
Definition: types.h:42
@ IFT_INT64
64 bit integer field
Definition: types.h:44
@ IFT_DOUBLE
double field
Definition: types.h:47
@ IFT_INT16
16 bit integer field
Definition: types.h:40
@ IFT_UINT8
8 bit unsigned integer field
Definition: types.h:39