OrocosComponentLibrary
2.7.0
|
00001 /* 00002 * Lua scripting plugin 00003 */ 00004 00005 #include <rtt/Service.hpp> 00006 #include <rtt/plugin/ServicePlugin.hpp> 00007 #include <iostream> 00008 00009 #include "../rtt.hpp" 00010 00011 #ifdef LUA_RTT_TLSF 00012 extern "C" { 00013 #include "../tlsf_rtt.h" 00014 } 00015 #endif 00016 00017 #ifdef LUA_RTT_TLSF 00018 #define LuaService LuaTLSFService 00019 #else 00020 #define LuaService LuaService 00021 #endif 00022 00023 using namespace RTT; 00024 00025 class LuaService : public Service 00026 { 00027 protected: 00028 lua_State *L; 00029 os::Mutex m; 00030 #if LUA_RTT_TLSF 00031 struct lua_tlsf_info tlsf_inf; 00032 #endif 00033 00034 public: 00035 LuaService(RTT::TaskContext* tc) 00036 #if LUA_RTT_TLSF 00037 : RTT::Service("LuaTLSF", tc) 00038 #else 00039 : RTT::Service("Lua", tc) 00040 #endif 00041 { 00042 /* initialize lua */ 00043 os::MutexLock lock(m); 00044 00045 #if LUA_RTT_TLSF 00046 if(tlsf_rtt_init_mp(&tlsf_inf, TLSF_INITIAL_POOLSIZE)) { 00047 Logger::log(Logger::Error) << "LuaService (TLSF)'" 00048 << this->getOwner()->getName() << ": failed to create tlsf pool (" 00049 << std::hex << TLSF_INITIAL_POOLSIZE << "bytes)" << endlog(); 00050 throw; 00051 } 00052 00053 L = lua_newstate(tlsf_alloc, &tlsf_inf); 00054 tlsf_inf.L = L; 00055 set_context_tlsf_info(&tlsf_inf); 00056 register_tlsf_api(L); 00057 #else 00058 L = luaL_newstate(); 00059 #endif 00060 00061 if (L == NULL) { 00062 Logger::log(Logger::Error) << "LuaService ctr '" << this->getOwner()->getName() << "': " 00063 << "cannot create state: not enough memory" << endlog(); 00064 throw; 00065 } 00066 00067 00068 lua_gc(L, LUA_GCSTOP, 0); 00069 luaL_openlibs(L); 00070 lua_gc(L, LUA_GCRESTART, 0); 00071 00072 /* setup rtt bindings */ 00073 lua_pushcfunction(L, luaopen_rtt); 00074 lua_call(L, 0, 0); 00075 00076 set_context_tc(tc, L); 00077 00078 this->addOperation("exec_file", &LuaService::exec_file, this) 00079 .doc("load (and run) the given lua script") 00080 .arg("filename", "filename of the lua script"); 00081 00082 this->addOperation("exec_str", &LuaService::exec_str, this) 00083 .doc("evaluate the given string in the lua environment") 00084 .arg("lua-string", "string of lua code to evaluate"); 00085 00086 #ifdef LUA_RTT_TLSF 00087 this->addOperation("tlsf_incmem", &LuaService::tlsf_incmem, this, OwnThread) 00088 .doc("increase the TLSF memory pool") 00089 .arg("size", "size in bytes to add to pool"); 00090 #endif 00091 } 00092 00093 // Destructor 00094 ~LuaService() 00095 { 00096 os::MutexLock lock(m); 00097 lua_close(L); 00098 #ifdef LUA_RTT_TLSF 00099 tlsf_rtt_free_mp(&tlsf_inf); 00100 #endif 00101 } 00102 00103 00104 #ifdef LUA_RTT_TLSF 00105 bool tlsf_incmem(unsigned int size) 00106 { 00107 return tlsf_rtt_incmem(&tlsf_inf, size); 00108 } 00109 #endif 00110 bool exec_file(const std::string &file) 00111 { 00112 os::MutexLock lock(m); 00113 if (luaL_dofile(L, file.c_str())) { 00114 Logger::log(Logger::Error) << "LuaService '" << this->getOwner()->getName() 00115 << "': " << lua_tostring(L, -1) << endlog(); 00116 return false; 00117 } 00118 return true; 00119 } 00120 00121 bool exec_str(const std::string &str) 00122 { 00123 os::MutexLock lock(m); 00124 if (luaL_dostring(L, str.c_str())) { 00125 Logger::log(Logger::Error) << "LuaService '" << this->getOwner()->getName() 00126 << "': " << lua_tostring(L, -1) << endlog(); 00127 return false; 00128 } 00129 return true; 00130 } 00131 }; 00132 00133 #ifdef LUA_RTT_TLSF 00134 ORO_SERVICE_NAMED_PLUGIN(LuaService , "LuaTLSF") 00135 #else 00136 ORO_SERVICE_NAMED_PLUGIN(LuaService , "Lua") 00137 #endif