00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "exec_thread.h"
00024
00025 #include <core/exceptions/software.h>
00026 #include <core/exceptions/system.h>
00027 #include <core/threading/mutex.h>
00028 #include <utils/logging/component.h>
00029
00030 #include <lua/context.h>
00031 #include <lua/interface_importer.h>
00032
00033 #include <interfaces/SkillerInterface.h>
00034 #include <interfaces/SkillerDebugInterface.h>
00035
00036 #include <string>
00037 #include <cstring>
00038
00039 using namespace std;
00040 using namespace fawkes;
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 LuaAgentExecutionThread::LuaAgentExecutionThread()
00052 : Thread("LuaAgentExecutionThread", Thread::OPMODE_WAITFORWAKEUP),
00053 BlockedTimingAspect(BlockedTimingAspect::WAKEUP_HOOK_THINK)
00054 {
00055 __lua = NULL;
00056 }
00057
00058
00059
00060 LuaAgentExecutionThread::~LuaAgentExecutionThread()
00061 {
00062 }
00063
00064
00065
00066
00067
00068
00069 void
00070 LuaAgentExecutionThread::init_failure_cleanup()
00071 {
00072 try {
00073 if ( __skiller_if ) {
00074 __skiller_if->msgq_enqueue(new SkillerInterface::ReleaseControlMessage());
00075 blackboard->close(__skiller_if);
00076 }
00077 if ( __agdbg_if ) blackboard->close(__agdbg_if);
00078
00079 delete __lua_ifi;
00080
00081 } catch (...) {
00082
00083
00084
00085 logger->log_error(name(), "Really screwed up while finalizing, aborting cleanup. "
00086 "Fawkes is no longer in a clean state. Restart!");
00087 }
00088 }
00089
00090
00091 void
00092 LuaAgentExecutionThread::init()
00093 {
00094 try {
00095 __cfg_agent = config->get_string("/luaagent/agent");
00096 __cfg_watch_files = config->get_bool("/luaagent/watch_files");
00097 } catch (Exception &e) {
00098 e.append("Insufficient configuration for LuaAgent");
00099 throw;
00100 }
00101
00102 logger->log_debug("LuaAgentExecutionThread", "Agent: %s", __cfg_agent.c_str());
00103
00104 __clog = new ComponentLogger(logger, "LuaAgentLua");
00105
00106 __lua = NULL;
00107 __lua_ifi = NULL;
00108 __skiller_if = NULL;
00109 __agdbg_if = NULL;
00110
00111 std::string reading_prefix = "/luaagent/interfaces/" + __cfg_agent + "/reading/";
00112 std::string writing_prefix = "/luaagent/interfaces/" + __cfg_agent + "/writing/";
00113
00114 __skiller_if = blackboard->open_for_reading<SkillerInterface>("Skiller");
00115
00116 __skiller_if->read();
00117 if (__skiller_if->exclusive_controller() != 0) {
00118 throw Exception("Skiller already has an exclusive controller");
00119 }
00120
00121 __skiller_if->msgq_enqueue(new SkillerInterface::AcquireControlMessage());
00122 __agdbg_if = blackboard->open_for_writing<SkillerDebugInterface>("LuaAgent");
00123
00124 try {
00125 __lua = new LuaContext(__cfg_watch_files);
00126
00127 __lua_ifi = new LuaInterfaceImporter(__lua, blackboard, config, logger);
00128 __lua_ifi->open_reading_interfaces(reading_prefix);
00129 __lua_ifi->open_writing_interfaces(writing_prefix);
00130
00131 __lua->add_package_dir(LUADIR);
00132 __lua->add_cpackage_dir(LUALIBDIR);
00133
00134 __lua->add_package("fawkesutils");
00135 __lua->add_package("fawkesconfig");
00136 __lua->add_package("fawkesinterface");
00137
00138 __lua->set_string("AGENT", __cfg_agent.c_str());
00139 __lua->set_usertype("config", config, "Configuration", "fawkes");
00140 __lua->set_usertype("logger", __clog, "ComponentLogger", "fawkes");
00141 __lua->set_usertype("clock", clock, "Clock", "fawkes");
00142
00143 __lua_ifi->add_interface("skiller", __skiller_if);
00144 __lua_ifi->add_interface("agdbg", __agdbg_if);
00145
00146 __lua_ifi->push_interfaces();
00147
00148 __lua->set_start_script(LUADIR"/luaagent/start.lua");
00149 } catch (Exception &e) {
00150 init_failure_cleanup();
00151 throw;
00152 }
00153
00154 __agdbg_if->set_graph("");
00155 __agdbg_if->set_graph_fsm(__cfg_agent.c_str());
00156
00157 }
00158
00159
00160 void
00161 LuaAgentExecutionThread::finalize()
00162 {
00163 if (__skiller_if->has_writer() ) {
00164 __skiller_if->msgq_enqueue(new SkillerInterface::ReleaseControlMessage());
00165 }
00166
00167 blackboard->close(__skiller_if);
00168 blackboard->close(__agdbg_if);
00169
00170 delete __lua_ifi;
00171 delete __lua;
00172 delete __clog;
00173 }
00174
00175 void
00176 LuaAgentExecutionThread::process_agdbg_messages()
00177 {
00178 while ( ! __agdbg_if->msgq_empty() ) {
00179 if (__agdbg_if->msgq_first_is<SkillerDebugInterface::SetGraphDirectionMessage>() ) {
00180 SkillerDebugInterface::SetGraphDirectionMessage *m = __agdbg_if->msgq_first<SkillerDebugInterface::SetGraphDirectionMessage>();
00181 try {
00182 std::string graphdir = "TB";
00183 switch (m->graph_dir()) {
00184 case SkillerDebugInterface::GD_BOTTOM_TOP: graphdir = "BT"; break;
00185 case SkillerDebugInterface::GD_LEFT_RIGHT: graphdir = "LR"; break;
00186 case SkillerDebugInterface::GD_RIGHT_LEFT: graphdir = "RL"; break;
00187 default: break;
00188 }
00189 __lua->do_string("agentenv.set_graphdir(\"%s\")", graphdir.c_str());
00190 } catch (Exception &e) {
00191 logger->log_warn("LuaAgentExecutionThread", "Failed to set graph direction, exception follows");
00192 logger->log_warn("LuaAgentExecutionThread", e);
00193 }
00194 } else if (__agdbg_if->msgq_first_is<SkillerDebugInterface::SetGraphColoredMessage>() ) {
00195 SkillerDebugInterface::SetGraphColoredMessage *m = __agdbg_if->msgq_first<SkillerDebugInterface::SetGraphColoredMessage>();
00196 try {
00197 __lua->do_string("agentenv.set_graph_colored(%s)", m->is_graph_colored() ? "true" : "false");
00198 } catch (Exception &e) {
00199 logger->log_warn("LuaAgentExecutionThread", "Failed to set graph direction, exception follows");
00200 logger->log_warn("LuaAgentExecutionThread", e);
00201 }
00202 }
00203
00204 __agdbg_if->msgq_pop();
00205 }
00206 }
00207
00208
00209 void
00210 LuaAgentExecutionThread::loop()
00211 {
00212 #ifdef HAVE_INOTIFY
00213 __lua->process_fam_events();
00214 #endif
00215
00216 process_agdbg_messages();
00217
00218 __lua_ifi->read();
00219 __skiller_if->read();
00220
00221 try {
00222
00223 __lua->do_string("agentenv.execute()");
00224 } catch (Exception &e) {
00225 logger->log_error("LuaAgentExecutionThread", "Execution of %s.execute() failed, exception follows",
00226 __cfg_agent.c_str());
00227 logger->log_error("LuaAgentExecutionThread", e);
00228 }
00229
00230 __lua_ifi->write();
00231 }