22 #include <blackboard/remote.h>
23 #include <interfaces/SkillerInterface.h>
24 #include <plugins/openprs/mod_utils.h>
25 #include <utils/misc/string_conversions.h>
29 extern "C" void finalize();
35 std::string g_skill_string;
36 unsigned int g_skill_msgid = 0;
37 Thread_Intention_Block *g_skill_tib = NULL;
40 gen_skill_string(TermList terms)
42 int terms_len = sl_slist_length(terms);
43 Term * name = (Term *)get_list_pos(terms, 1);
44 std::string skill_string = std::string(name->u.string) +
"{";
45 for (
int i = 2; i < terms_len; i += 2) {
46 Term *key_t = (Term *)get_list_pos(terms, i);
47 Term *val_t = (Term *)get_list_pos(terms, i + 1);
49 if (key_t->type != TT_ATOM && key_t->type != STRING) {
51 "Error: skill argument key neither of type "
52 "SYMBOL/ATOM nor STRING (%i)\n",
61 arg_key = (key_t->type == TT_ATOM) ? key_t->u.id : key_t->u.string;
62 skill_string += std::string(arg_key) +
"=";
64 switch (val_t->type) {
70 case STRING: skill_string += std::string(
"\"") + val_t->u.string +
"\"";
break;
71 case TT_ATOM: skill_string += val_t->u.id;
break;
74 sl_loop_through_slist(global_var_list, env, Envar *)
76 if (strcmp(env->name, val_t->u.var->name) == 0) {
77 skill_string += env->value->u.string;
79 skill_string +=
"nil";
86 "Warning: unknown variable type for skill %s argument %s, using nil\n",
89 skill_string +=
"nil";
98 assert_exclusive_controller(
unsigned int num_tries,
unsigned int delay_msec)
104 for (
unsigned int i = 0; i < num_tries; ++i) {
113 usleep(delay_msec * 1000);
123 action_skill_call(TermList terms)
125 int terms_len = sl_slist_length(terms);
126 if (terms_len == 0) {
127 fprintf(stderr,
"Error: no arguments to skill call\n");
132 ACTION_SET_AND_ASSERT_ARG_TYPE(
"skill-call", name, terms, 1, STRING);
134 if (terms_len % 2 == 0) {
136 "Error: invalid number of arguments (%i) to skill call for %s\n",
145 if (action_first_call()) {
148 fprintf(stderr,
"Cannot send skill, interface has no writer\n");
151 if (!assert_exclusive_controller(20, 100)) {
152 fprintf(stderr,
"Cannot send skill, not exclusive controller\n");
156 std::string skill_string = gen_skill_string(terms);
157 if (skill_string.empty()) {
158 fprintf(stderr,
"Error: failed to generate skill string\n");
162 printf(
"Calling skill %s\n", skill_string.c_str());
170 g_skill_msgid = msg->id();
171 g_skill_string = skill_string;
175 g_skill_tib = current_tib;
179 if (current_tib != g_skill_tib) {
180 fprintf(stderr,
"Skill preempted by another skill, returning fail");
186 if (skiller_if->
msgid() > g_skill_msgid) {
188 "Fail: a more recent message is being processed by the skiller (%u > %u)\n",
192 }
else if (skiller_if->
msgid() < g_skill_msgid) {
197 switch (skiller_if->
status()) {
202 printf(
"Skill %s has FAILED\n", name->u.string);
205 default: ACTION_WAIT();
215 printf(
"*** LOADING mod_skiller\n");
217 std::string fawkes_host;
218 unsigned short fawkes_port = 0;
219 get_fawkes_host_port(fawkes_host, fawkes_port);
221 printf(
"Connecting to Fawkes at %s:%u\n", fawkes_host.c_str(), fawkes_port);
225 fprintf(stderr,
"Error: cannot establish blackboard connection: %s\n", e.
what_no_backtrace());
230 printf(
"Acquiring exclusive skiller control\n");
235 declare_atom(
"true");
236 declare_atom(
"false");
237 make_and_declare_action(
"skill-call", action_skill_call, -1);
238 add_user_end_kernel_hook(finalize);
245 printf(
"*** DESTROYING mod_skiller\n");
252 blackboard->
close(skiller_if);