OrocosComponentLibrary  2.9.0
LuaComponent.cpp
1 /*
2  * Lua-RTT bindings. LuaComponent.
3  *
4  * (C) Copyright 2010 Markus Klotzbuecher
5  * markus.klotzbuecher@mech.kuleuven.be
6  * Department of Mechanical Engineering,
7  * Katholieke Universiteit Leuven, Belgium.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public
11  * License as published by the Free Software Foundation;
12  * version 2 of the License.
13  *
14  * As a special exception, you may use this file as part of a free
15  * software library without restriction. Specifically, if other files
16  * instantiate templates or use macros or inline functions from this
17  * file, or you compile this file and link it with other files to
18  * produce an executable, this file does not by itself cause the
19  * resulting executable to be covered by the GNU General Public
20  * License. This exception does not however invalidate any other
21  * reasons why the executable file might be covered by the GNU General
22  * Public License.
23  *
24  * This library is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27  * Lesser General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public
30  * License along with this library; if not, write to the Free Software
31  * Foundation, Inc., 59 Temple Place,
32  * Suite 330, Boston, MA 02111-1307 USA
33  */
34 
35 #include "LuaComponent.hpp"
36 #include <iostream>
37 
38 #include "rtt.hpp"
39 
40 #ifdef LUA_RTT_TLSF
41 extern "C" {
42 #include "tlsf_rtt.h"
43 }
44 #endif
45 
46 #ifdef LUA_RTT_TLSF
47 #define LuaComponent LuaTLSFComponent
48 #else
49 #define LuaComponent LuaComponent
50 #endif
51 
52 using namespace RTT;
53 
54 namespace OCL
55 {
56  LuaComponent::LuaComponent(std::string name)
57  : TaskContext(name, PreOperational)
58  {
59  os::MutexLock lock(m);
60 #if LUA_RTT_TLSF
61  tlsf_inf = new lua_tlsf_info;
62  if(tlsf_rtt_init_mp(tlsf_inf, TLSF_INITIAL_POOLSIZE)) {
63  Logger::log(Logger::Error) << "LuaComponent '" << name << ": failed to create tlsf pool ("
64  << std::hex << TLSF_INITIAL_POOLSIZE << "bytes)" << endlog();
65  throw;
66  }
67 
68  L = lua_newstate(tlsf_alloc, tlsf_inf);
69  tlsf_inf->L = L;
70  set_context_tlsf_info(tlsf_inf);
71  register_tlsf_api(L);
72 #else
73  L = luaL_newstate();
74 #endif
75  if (L == NULL) {
76  Logger::log(Logger::Error) << "LuaComponent '" << name
77  << "': failed to allocate memory for Lua state" << endlog();
78  throw;
79  }
80 
81  lua_gc(L, LUA_GCSTOP, 0);
82  luaL_openlibs(L);
83  lua_gc(L, LUA_GCRESTART, 0);
84 
85  /* setup rtt bindings */
86  lua_pushcfunction(L, luaopen_rtt);
87  lua_call(L, 0, 0);
88 
89  set_context_tc(this, L);
90 
91  this->addProperty("lua_string", lua_string).doc("string of lua code to be executed during configureHook");
92  this->addProperty("lua_file", lua_file).doc("file with lua program to be executed during configuration");
93 
94  this->addOperation("exec_file", &LuaComponent::exec_file, this, OwnThread)
95  .doc("load (and run) the given lua script")
96  .arg("filename", "filename of the lua script");
97 
98  this->addOperation("exec_str", &LuaComponent::exec_str, this, OwnThread)
99  .doc("evaluate the given string in the lua environment")
100  .arg("lua-string", "string of lua code to evaluate");
101 
102 #ifdef LUA_RTT_TLSF
103  this->addOperation("tlsf_incmem", &LuaComponent::tlsf_incmem, this, OwnThread)
104  .doc("increase the TLSF memory pool")
105  .arg("size", "size in bytes to add to pool");
106 #endif
107  }
108 
109  LuaComponent::~LuaComponent()
110  {
111  os::MutexLock lock(m);
112  lua_close(L);
113 #ifdef LUA_RTT_TLSF
114  tlsf_rtt_free_mp(tlsf_inf);
115  delete tlsf_inf;
116 #endif
117  }
118 
119 #ifdef LUA_RTT_TLSF
120  bool LuaComponent::tlsf_incmem(unsigned int size)
121  {
122  return tlsf_rtt_incmem(tlsf_inf, size);
123  }
124 #endif
125 
126 
127  bool LuaComponent::exec_file(const std::string &file)
128  {
129  os::MutexLock lock(m);
130  if (luaL_dofile(L, file.c_str())) {
131  Logger::log(Logger::Error) << "LuaComponent '" << this->getName() << "': " << lua_tostring(L, -1) << endlog();
132  return false;
133  }
134  return true;
135  }
136 
137  bool LuaComponent::exec_str(const std::string &str)
138  {
139  os::MutexLock lock(m);
140  if (luaL_dostring(L, str.c_str())) {
141  Logger::log(Logger::Error) << "LuaComponent '" << this->getName() << "': " << lua_tostring(L, -1) << endlog();
142  return false;
143  }
144  return true;
145  }
146 
147  bool LuaComponent::configureHook()
148  {
149  if(!lua_string.empty())
150  exec_str(lua_string);
151 
152  if(!lua_file.empty())
153  exec_file(lua_file);
154  return call_func(L, "configureHook", this, 0, 1);
155  }
156 
157  bool LuaComponent::activateHook()
158  {
159  os::MutexLock lock(m);
160  return call_func(L, "activateHook", this, 0, 1);
161  }
162 
163  bool LuaComponent::startHook()
164  {
165  os::MutexLock lock(m);
166  return call_func(L, "startHook", this, 0, 1);
167  }
168 
169  void LuaComponent::updateHook()
170  {
171  os::MutexLock lock(m);
172  call_func(L, "updateHook", this, 0, 0);
173  }
174 
175  void LuaComponent::stopHook()
176  {
177  os::MutexLock lock(m);
178  call_func(L, "stopHook", this, 0, 0);
179  }
180 
181  void LuaComponent::cleanupHook()
182  {
183  os::MutexLock lock(m);
184  call_func(L, "cleanupHook", this, 0, 0);
185  }
186 
187  void LuaComponent::errorHook()
188  {
189  os::MutexLock lock(m);
190  call_func(L, "errorHook", this, 0, 0);
191  }
192 
193  LuaStateHandle LuaComponent::getLuaState()
194  {
195  return LuaStateHandle(L, m);
196  }
197 
198 } // namespace OCL
199 
200 #include "ocl/Component.hpp"
201 ORO_CREATE_COMPONENT( OCL::LuaComponent )
This file contains the macros and definitions to create dynamically loadable components.
The Orocos Component Library.
Definition: Component.hpp:43
Definition: Category.hpp:10