OrocosComponentLibrary  2.7.0
lua_plugin.cpp
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