23 #include <lua/interface_importer.h>
24 #include <lua/context.h>
26 #include <config/config.h>
27 #include <interface/interface.h>
28 #include <blackboard/blackboard.h>
29 #include <logging/logger.h>
56 LuaInterfaceImporter::LuaInterfaceImporter(
LuaContext *context,
62 __blackboard = blackboard;
66 __context->add_watcher(
this);
68 __interfaces_pushed =
false;
73 LuaInterfaceImporter::~LuaInterfaceImporter()
75 __context->remove_watcher(
this);
76 close_writing_interfaces();
77 close_reading_interfaces();
89 LuaInterfaceImporter::open_interfaces(std::string &prefix, InterfaceMap &imap,
bool write)
95 if (strcmp(vi->
type(),
"string") != 0) {
97 "but found value of type %s",
98 prefix.c_str(), vi->
type());
104 if (uid.find(
"::") == std::string::npos) {
106 throw Exception(
"Interface UID '%s' at %s is not valid, missing double colon",
107 uid.c_str(), vi->
path());
109 std::string varname = std::string(vi->
path()).substr(prefix.length());
110 std::string iftype = uid.substr(0, uid.find(
"::"));
111 std::string ifname = uid.substr(uid.find(
"::") + 2);
113 if ( __reading_ifs.find(varname) != __reading_ifs.end() ) {
115 throw Exception(
"Reading interface with varname %s already opened", varname.c_str());
117 if ( __reading_multi_ifs.find(varname) != __reading_multi_ifs.end() ) {
119 throw Exception(
"Reading multi interface with varname %s already opened", varname.c_str());
121 if ( __writing_ifs.find(varname) != __writing_ifs.end() ) {
123 throw Exception(
"Writing interface with varname %s already opened", varname.c_str());
127 if (ifname.find_first_of(
"*?[") == std::string::npos) {
128 __logger->log_info(
"LuaInterfaceImporter",
"Adding %s interface %s::%s with name %s",
129 write ?
"writing" :
"reading",
130 iftype.c_str(), ifname.c_str(), varname.c_str());
134 iface = __blackboard->open_for_writing(iftype.c_str(), ifname.c_str());
136 iface = __blackboard->open_for_reading(iftype.c_str(), ifname.c_str());
139 iface->resize_buffers(1);
141 imap[varname] = iface;
142 }
catch (Exception &e) {
149 throw Exception(
"Illegal config entry %s=%s, multiple interfaces can "
150 "only be opened for reading", vi->
path(), uid.c_str());
152 __logger->log_info(
"LuaInterfaceImporter",
"Adding multiple %s interfaces %s::%s with in table %s",
153 write ?
"writing" :
"reading",
154 iftype.c_str(), ifname.c_str(), varname.c_str());
156 std::list<Interface *> interfaces = __blackboard->open_multiple_for_reading(iftype.c_str(), ifname.c_str());
157 __reading_multi_ifs[varname] = interfaces;
158 InterfaceObserver *observer =
159 new InterfaceObserver(
this, varname, iftype.c_str(), ifname.c_str());
160 __observers[varname] = observer;
161 __blackboard->register_observer(observer);
172 LuaInterfaceImporter::open_reading_interfaces(std::string &prefix)
174 open_interfaces(prefix, __reading_ifs,
false);
181 LuaInterfaceImporter::open_writing_interfaces(std::string &prefix)
183 open_interfaces(prefix, __writing_ifs,
true);
197 LuaInterfaceImporter::add_interface(std::string varname,
Interface *interface)
200 __ext_wifs[varname] = interface;
202 __ext_rifs[varname] = interface;
208 LuaInterfaceImporter::add_observed_interface(std::string varname,
209 const char *type,
const char *
id)
212 if (__reading_multi_ifs.find(varname) == __reading_multi_ifs.end() ) {
213 throw Exception(
"Notified about unknown interface varname %s", varname.c_str());
215 Interface *iface = __blackboard->open_for_reading(type,
id);
216 __context->add_package((std::string(
"interfaces.") + iface->type()).c_str());
217 __reading_multi_ifs[varname].push_back(iface);
218 __context->get_global(
"interfaces");
219 __context->get_field(-1,
"reading");
220 __context->get_field(-1, varname.c_str());
221 __context->push_usertype(iface, iface->type(),
"fawkes");
222 __context->raw_seti(-2, __reading_multi_ifs[varname].size());
223 __context->push_usertype(iface, iface->type(),
"fawkes");
224 __context->set_field(iface->uid(), -2);
226 }
catch (Exception &e) {
227 __logger->log_warn(
"LuaInterfaceImporter",
"Failed to add observed interface "
228 "%s:%s, exception follows", type,
id);
229 __logger->log_warn(
"LuaInterfaceImporter", e);
236 LuaInterfaceImporter::close_reading_interfaces()
238 for (InterfaceMap::iterator i = __reading_ifs.begin(); i != __reading_ifs.end(); ++i) {
239 __blackboard->close(i->second);
241 __reading_ifs.clear();
243 for (ObserverMap::iterator o = __observers.begin(); o != __observers.end(); ++o) {
244 __blackboard->unregister_observer(o->second);
249 for (InterfaceListMap::iterator i = __reading_multi_ifs.begin(); i != __reading_multi_ifs.end(); ++i) {
250 for (std::list<Interface *>::iterator j = i->second.begin(); j != i->second.end(); ++j) {
251 __blackboard->close(*j);
254 __reading_multi_ifs.clear();
260 LuaInterfaceImporter::close_writing_interfaces()
262 for (InterfaceMap::iterator i = __writing_ifs.begin(); i != __writing_ifs.end(); ++i) {
263 __blackboard->close(i->second);
265 __writing_ifs.clear();
272 LuaInterfaceImporter::reading_interfaces()
274 return __reading_ifs;
282 LuaInterfaceImporter::writing_interfaces()
284 return __writing_ifs;
290 LuaInterfaceImporter::read()
292 for (InterfaceMap::iterator i = __reading_ifs.begin(); i != __reading_ifs.end(); ++i) {
301 LuaInterfaceImporter::read_to_buffer()
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);
320 LuaInterfaceImporter::read_from_buffer()
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);
334 LuaInterfaceImporter::write()
336 for (InterfaceMap::iterator i = __writing_ifs.begin(); i != __writing_ifs.end(); ++i) {
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");
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());
387 LuaInterfaceImporter::push_interfaces(LuaContext *context)
391 context->create_table(0, 4);
393 context->create_table(0, __reading_ifs.size() + __ext_rifs.size());
394 push_interfaces_varname(context, __reading_ifs);
395 push_interfaces_varname(context, __ext_rifs);
396 push_multi_interfaces_varname(context, __reading_multi_ifs);
397 context->set_field(
"reading");
399 context->create_table(0, __reading_ifs.size() + __ext_rifs.size());
400 push_interfaces_uid(context, __reading_ifs);
401 push_interfaces_uid(context, __ext_rifs);
402 context->set_field(
"reading_by_uid");
404 context->create_table(0, __writing_ifs.size() + __ext_wifs.size());
405 push_interfaces_varname(context, __writing_ifs);
406 push_interfaces_varname(context, __ext_wifs);
407 context->set_field(
"writing");
409 context->create_table(0, __writing_ifs.size());
410 push_interfaces_uid(context, __writing_ifs);
411 push_interfaces_uid(context, __ext_wifs);
412 context->set_field(
"writing_by_uid");
414 context->set_global(
"interfaces");
423 LuaInterfaceImporter::push_interfaces()
425 __interfaces_pushed =
true;
426 push_interfaces(__context);
434 if ( __interfaces_pushed ) {
435 push_interfaces(context);
438 __logger->log_warn(
"LuaInterfaceImporter",
"Failed to re-push interfacs, exception follows");
439 __logger->log_warn(
"LuaInterfaceImporter", e);
453 const char *type,
const char *id_pattern)
458 bbio_add_observed_create(type, id_pattern);
463 LuaInterfaceImporter::InterfaceObserver::bb_interface_created(
const char *type,
const char *
id)
throw()
465 __lii->add_observed_interface(__varname, type,
id);
virtual const char * type() const =0
Type of value.
Fawkes library namespace.
virtual bool next()=0
Check if there is another element and advance to this if possible.
A NULL pointer was supplied where not allowed.
Base class for all Fawkes BlackBoard interfaces.
void set_field(const char *key, int t_index=-2)
Set field of a table.
void add_package(const char *package)
Add a default package.
Base class for exceptions in Fawkes.
virtual std::string get_string() const =0
Get string value.
virtual const char * path() const =0
Path of value.
void push_usertype(void *data, const char *type_name, const char *name_space=0)
Push usertype on top of stack.
void print_trace()
Prints trace to stderr.
Iterator interface to iterate over config values.
bool is_writer() const
Check if this is a writing instance.
The BlackBoard abstract class.
Interface for configuration handling.
void append(const char *format,...)
Append messages to the message list.