00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef OCL_COMPONENT_ONLY
00036 extern "C" {
00037 #include "lua-repl.h"
00038 void dotty (lua_State *L);
00039 void l_message (const char *pname, const char *msg);
00040 int dofile (lua_State *L, const char *name);
00041 int dostring (lua_State *L, const char *s, const char *name);
00042 int main_args(lua_State *L, int argc, char **argv);
00043
00044 #include <sys/types.h>
00045 #include <sys/stat.h>
00046 #include <unistd.h>
00047 #include <wordexp.h>
00048 }
00049 #endif
00050
00051 #include "rtt.hpp"
00052
00053 #include <string>
00054 #include <rtt/os/main.h>
00055 #include <rtt/os/Mutex.hpp>
00056 #include <rtt/os/MutexLock.hpp>
00057 #include <rtt/TaskContext.hpp>
00058 #include <ocl/OCL.hpp>
00059 #include <deployment/DeploymentComponent.hpp>
00060
00061 #define INIT_FILE "~/.rttlua"
00062
00063 using namespace std;
00064 using namespace RTT;
00065 using namespace Orocos;
00066
00067 namespace OCL
00068 {
00069 class LuaComponent : public TaskContext
00070 {
00071 protected:
00072 std::string lua_string;
00073 std::string lua_file;
00074 lua_State *L;
00075 os::Mutex m;
00076
00077 public:
00078 LuaComponent(std::string name)
00079 : TaskContext(name, PreOperational)
00080 {
00081 os::MutexLock lock(m);
00082 L = lua_open();
00083 lua_gc(L, LUA_GCSTOP, 0);
00084 luaL_openlibs(L);
00085 lua_gc(L, LUA_GCRESTART, 0);
00086
00087 if (L == NULL) {
00088 Logger::log(Logger::Error) << "LuaComponent '" << name <<"': failed to allocate memory for Lua state" << endlog();
00089 throw;
00090 }
00091
00092
00093 lua_pushcfunction(L, luaopen_rtt);
00094 lua_call(L, 0, 0);
00095
00096 set_context_tc(this, L);
00097
00098 this->addProperty("lua_string", lua_string).doc("string of lua code to be executed during configureHook");
00099 this->addProperty("lua_file", lua_file).doc("file with lua program to be executed during configuration");
00100
00101 this->addOperation("exec_file", &LuaComponent::exec_file, this, OwnThread)
00102 .doc("load (and run) the given lua script")
00103 .arg("filename", "filename of the lua script");
00104
00105 this->addOperation("exec_str", &LuaComponent::exec_str, this, OwnThread)
00106 .doc("evaluate the given string in the lua environment")
00107 .arg("lua-string", "string of lua code to evaluate");
00108 }
00109
00110 ~LuaComponent()
00111 {
00112 os::MutexLock lock(m);
00113 lua_close(L);
00114 }
00115
00116 bool exec_file(const std::string &file)
00117 {
00118 os::MutexLock lock(m);
00119 if (luaL_dofile(L, file.c_str())) {
00120 Logger::log(Logger::Error) << "LuaComponent '" << this->getName() << "': " << lua_tostring(L, -1) << endlog();
00121 return false;
00122 }
00123 return true;
00124 }
00125
00126 bool exec_str(const std::string &str)
00127 {
00128 os::MutexLock lock(m);
00129 if (luaL_dostring(L, str.c_str())) {
00130 Logger::log(Logger::Error) << "LuaComponent '" << this->getName() << "': " << lua_tostring(L, -1) << endlog();
00131 return false;
00132 }
00133 return true;
00134 }
00135
00136 #ifndef OCL_COMPONENT_ONLY
00137 void lua_repl()
00138 {
00139 os::MutexLock lock(m);
00140 dotty(L);
00141 }
00142
00143 int lua_repl(int argc, char **argv)
00144 {
00145 os::MutexLock lock(m);
00146 return main_args(L, argc, argv);
00147 }
00148 #endif
00149 bool configureHook()
00150 {
00151 os::MutexLock lock(m);
00152 if(!lua_string.empty())
00153 exec_str(lua_string);
00154
00155 if(!lua_file.empty())
00156 exec_file(lua_file);
00157 return call_func(L, "configureHook", this, 0, 1);
00158 }
00159
00160 bool activateHook()
00161 {
00162 os::MutexLock lock(m);
00163 return call_func(L, "activateHook", this, 0, 1);
00164 }
00165
00166 bool startHook()
00167 {
00168 os::MutexLock lock(m);
00169 return call_func(L, "startHook", this, 0, 1);
00170 }
00171
00172 void updateHook()
00173 {
00174 os::MutexLock lock(m);
00175 call_func(L, "updateHook", this, 0, 0);
00176 }
00177
00178 void stopHook()
00179 {
00180 os::MutexLock lock(m);
00181 call_func(L, "stopHook", this, 0, 0);
00182 }
00183
00184 void cleanupHook()
00185 {
00186 os::MutexLock lock(m);
00187 call_func(L, "cleanupHook", this, 0, 0);
00188 }
00189
00190 void errorHook()
00191 {
00192 os::MutexLock lock(m);
00193 call_func(L, "errorHook", this, 0, 0);
00194 }
00195 };
00196 }
00197
00198
00199 #ifndef OCL_COMPONENT_ONLY
00200
00201 int ORO_main(int argc, char** argv)
00202 {
00203 struct stat stb;
00204 wordexp_t init_exp;
00205
00206 LuaComponent lua("lua");
00207 DeploymentComponent dc("deployer");
00208 lua.connectPeers(&dc);
00209
00210
00211 wordexp(INIT_FILE, &init_exp, 0);
00212 if(stat(init_exp.we_wordv[0], &stb) != -1) {
00213 if((stb.st_mode & S_IFMT) != S_IFREG)
00214 cout << "rttlua: warning: init file " << init_exp.we_wordv[0] << " is not a regular file" << endl;
00215 else
00216 lua.exec_file(init_exp.we_wordv[0]);
00217 }
00218 wordfree(&init_exp);
00219
00220 lua.lua_repl(argc, argv);
00221 return 0;
00222 }
00223
00224 #else
00225
00226 #include "ocl/Component.hpp"
00227 ORO_CREATE_COMPONENT( OCL::LuaComponent )
00228 #endif