23 #include <blackboard/blackboard.h>
24 #include <config/config.h>
25 #include <interface/interface.h>
26 #include <logging/logger.h>
27 #include <lua/context.h>
28 #include <lua/interface_importer.h>
53 BlackBoard * blackboard,
54 Configuration *config,
58 blackboard_ = blackboard;
64 interfaces_pushed_ =
false;
83 LuaInterfaceImporter::open_interfaces(std::string &prefix, InterfaceMap &imap,
bool write)
90 if (strcmp(vi->
type(),
"string") != 0) {
92 "but found value of type %s",
100 if (uid.find(
"::") == std::string::npos) {
102 throw Exception(
"Interface UID '%s' at %s is not valid, missing double colon",
106 std::string varname = std::string(vi->
path()).substr(prefix.length());
107 std::string iftype = uid.substr(0, uid.find(
"::"));
108 std::string ifname = uid.substr(uid.find(
"::") + 2);
110 if (reading_ifs_.find(varname) != reading_ifs_.end()) {
112 throw Exception(
"Reading interface with varname %s already opened", varname.c_str());
114 if (reading_multi_ifs_.find(varname) != reading_multi_ifs_.end()) {
116 throw Exception(
"Reading multi interface with varname %s already opened", varname.c_str());
118 if (writing_ifs_.find(varname) != writing_ifs_.end()) {
120 throw Exception(
"Writing interface with varname %s already opened", varname.c_str());
123 if (ifname.find_first_of(
"*?[") == std::string::npos) {
124 logger_->
log_info(
"LuaInterfaceImporter",
125 "Adding %s interface %s::%s with name %s",
126 write ?
"writing" :
"reading",
140 imap[varname] = iface;
148 throw Exception(
"Illegal config entry %s=%s, multiple interfaces can "
149 "only be opened for reading",
153 logger_->
log_info(
"LuaInterfaceImporter",
154 "Adding multiple %s interfaces %s::%s with in table %s",
155 write ?
"writing" :
"reading",
160 std::list<Interface *> interfaces =
162 reading_multi_ifs_[varname] = interfaces;
163 InterfaceObserver *observer =
164 new InterfaceObserver(
this, varname, iftype.c_str(), ifname.c_str());
165 observers_[varname] = observer;
178 open_interfaces(prefix, reading_ifs_,
false);
187 open_interfaces(prefix, writing_ifs_,
true);
203 ext_wifs_[varname] = interface;
205 ext_rifs_[varname] = interface;
210 LuaInterfaceImporter::add_observed_interface(std::string varname,
const char *type,
const char *
id)
213 if (reading_multi_ifs_.find(varname) == reading_multi_ifs_.end()) {
214 throw Exception(
"Notified about unknown interface varname %s", varname.c_str());
217 context_->
add_package((std::string(
"interfaces.") + iface->type()).c_str());
218 reading_multi_ifs_[varname].push_back(iface);
221 context_->
get_field(-1, varname.c_str());
223 context_->
raw_seti(-2, reading_multi_ifs_[varname].size());
227 }
catch (Exception &e) {
228 logger_->
log_warn(
"LuaInterfaceImporter",
229 "Failed to add observed interface "
230 "%s:%s, exception follows",
233 logger_->
log_warn(
"LuaInterfaceImporter", e);
241 for (InterfaceMap::iterator i = reading_ifs_.begin(); i != reading_ifs_.end(); ++i) {
242 blackboard_->
close(i->second);
244 reading_ifs_.clear();
246 for (ObserverMap::iterator o = observers_.begin(); o != observers_.end(); ++o) {
252 for (InterfaceListMap::iterator i = reading_multi_ifs_.begin(); i != reading_multi_ifs_.end();
254 for (std::list<Interface *>::iterator j = i->second.begin(); j != i->second.end(); ++j) {
255 blackboard_->
close(*j);
258 reading_multi_ifs_.clear();
265 for (InterfaceMap::iterator i = writing_ifs_.begin(); i != writing_ifs_.end(); ++i) {
266 blackboard_->
close(i->second);
268 writing_ifs_.clear();
293 for (InterfaceMap::iterator i = reading_ifs_.begin(); i != reading_ifs_.end(); ++i) {
303 InterfaceMap::iterator i;
305 for (i = reading_ifs_.begin(); i != reading_ifs_.end(); ++i) {
306 i->second->resize_buffers(1);
310 for (i = reading_ifs_.begin(); i != reading_ifs_.end(); ++i) {
311 i->second->copy_shared_to_buffer(0);
323 throw Exception(
"LuaInterfaceImporter: trying to read buffer witout "
324 "previous read_to_buffer()");
326 InterfaceMap::iterator i;
327 for (i = reading_ifs_.begin(); i != reading_ifs_.end(); ++i) {
328 i->second->read_from_buffer(0);
336 for (InterfaceMap::iterator i = writing_ifs_.begin(); i != writing_ifs_.end(); ++i) {
339 }
catch (Exception &e) {
340 e.append(
"Failed to write interface %s, ignoring.", i->second->uid());
347 LuaInterfaceImporter::push_interfaces_varname(LuaContext *context, InterfaceMap &imap)
349 InterfaceMap::iterator imi;
350 for (imi = imap.begin(); imi != imap.end(); ++imi) {
351 context->add_package((std::string(
"interfaces.") + imi->second->type()).c_str());
352 context->push_usertype(imi->second, imi->second->type(),
"fawkes");
353 context->set_field(imi->first.c_str());
358 LuaInterfaceImporter::push_multi_interfaces_varname(LuaContext *context, InterfaceListMap &imap)
360 InterfaceListMap::iterator imi;
361 for (imi = imap.begin(); imi != imap.end(); ++imi) {
362 context->create_table(0, imi->second.size());
364 for (std::list<Interface *>::iterator i = imi->second.begin(); i != imi->second.end(); ++i) {
365 context->add_package((std::string(
"interfaces.") + (*i)->type()).c_str());
366 context->push_usertype(*i, (*i)->type(),
"fawkes");
367 context->raw_seti(-2, ++idx);
368 context->push_usertype(*i, (*i)->type(),
"fawkes");
369 context->set_field((*i)->uid(), -2);
371 context->set_field(imi->first.c_str());
376 LuaInterfaceImporter::push_interfaces_uid(LuaContext *context, InterfaceMap &imap)
378 InterfaceMap::iterator imi;
379 for (imi = imap.begin(); imi != imap.end(); ++imi) {
380 context->add_package((std::string(
"interfaces.") + imi->second->type()).c_str());
381 context->push_usertype(imi->second, imi->second->type(),
"fawkes");
382 context->set_field(imi->second->uid());
390 context->create_table(0, 4);
392 context->create_table(0, reading_ifs_.size() + ext_rifs_.size());
393 push_interfaces_varname(context, reading_ifs_);
394 push_interfaces_varname(context, ext_rifs_);
395 push_multi_interfaces_varname(context, reading_multi_ifs_);
396 context->set_field(
"reading");
398 context->create_table(0, reading_ifs_.size() + ext_rifs_.size());
399 push_interfaces_uid(context, reading_ifs_);
400 push_interfaces_uid(context, ext_rifs_);
401 context->set_field(
"reading_by_uid");
403 context->create_table(0, writing_ifs_.size() + ext_wifs_.size());
404 push_interfaces_varname(context, writing_ifs_);
405 push_interfaces_varname(context, ext_wifs_);
406 context->set_field(
"writing");
408 context->create_table(0, writing_ifs_.size());
409 push_interfaces_uid(context, writing_ifs_);
410 push_interfaces_uid(context, ext_wifs_);
411 context->set_field(
"writing_by_uid");
413 context->set_global(
"interfaces");
424 interfaces_pushed_ =
true;
432 if (interfaces_pushed_) {
436 logger_->
log_warn(
"LuaInterfaceImporter",
"Failed to re-push interfacs, exception follows");
437 logger_->
log_warn(
"LuaInterfaceImporter", e);
448 LuaInterfaceImporter::InterfaceObserver::InterfaceObserver(LuaInterfaceImporter *lii,
451 const char * id_pattern)
456 bbio_add_observed_create(type, id_pattern);
460 LuaInterfaceImporter::InterfaceObserver::bb_interface_created(
const char *type,
461 const char *
id)
throw()
463 lii_->add_observed_interface(varname_, type,
id);