Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/script_engine/src/lib/script_engine/script.cc @ 8211

Last change on this file since 8211 was 8207, checked in by snellen, 18 years ago

set parent mode of script trigger to PNODE_MOVEMENT

File size: 6.8 KB
Line 
1#include "script.h"
2#include "script_class.h"
3#include "luaincl.h"
4
5
6#include "loading/load_param.h"
7#include "parser/tinyxml/tinyxml.h"
8
9#include "class_list.h"
10
11Script::Script(const TiXmlElement* root)
12{
13  this->setClassID(CL_SCRIPT, "Script");
14 
15  returnCount = argumentCount = 0;
16
17  luaState = lua_open();
18
19  luaopen_base(luaState);
20  luaopen_table(luaState);
21  luaopen_io(luaState);
22  luaopen_string(luaState);
23  luaopen_math(luaState);
24  luaopen_debug(luaState);
25 
26  if (root != NULL)
27    this->loadParams(root);
28}
29
30
31Script::~Script()
32{
33  lua_setgcthreshold(luaState, 0);  // collected garbage
34  lua_close(luaState);
35}
36
37
38void Script::loadParams(const TiXmlElement* root)
39{
40  BaseObject::loadParams(root);
41 
42  LOAD_PARAM_START_CYCLE(root, object);
43  {
44    LoadParam_CYCLE(object, "object", this, Script, addObject)
45        .describe("The name of an object that is needed by a script");
46  }
47  LOAD_PARAM_END_CYCLE(object);
48
49
50  LoadParam(root, "file", this, Script, loadFileNoRet)
51      .describe("the fileName of the script, that should be loaded into this world")
52      .defaultValues("");
53}
54
55
56
57bool Script::loadFile(const std::string& filename)
58 {
59
60   if(currentFile.length() != 0)
61   {
62     printf("Could not load %s because an other file is already loaded: %s\n",filename.c_str(), currentFile.c_str());
63     return false;
64    }
65
66   int error = luaL_loadfile (luaState, filename.c_str());
67
68   if(error == 0)
69   {
70     error = lua_pcall(luaState, 0, 0, 0);
71
72     if(error == 0)
73     {
74      currentFile = filename;
75      return true;
76     }
77     else
78     {
79      reportError(error);
80     }
81
82   }
83   else
84   {
85     reportError(error);
86   }
87
88   return false;
89 }
90
91 
92 void Script::addObject(const std::string& className, const std::string& objectName)
93 {
94   BaseObject* scriptClass = ClassList::getObject(className, CL_SCRIPT_CLASS);
95   WorldObject tmpObj;
96   if (scriptClass != NULL)
97   {
98     if( !classIsRegistered(className) )
99     {
100     static_cast<ScriptClass*>(scriptClass)->registerClass(this);
101     tmpObj.type = className;
102     }
103     
104     BaseObject* object = ClassList::getObject(objectName, className);
105     if (object != NULL && !objectIsAdded(objectName))
106     {
107        static_cast<ScriptClass*>(scriptClass)->insertObject(this, object, false);
108        tmpObj.name = objectName;
109        registeredObjects.push_back(tmpObj);
110     }
111   }
112 }
113
114 
115 
116 
117 bool Script::executeFile()
118 {
119   if(currentFile.length() != 0)
120   {
121    int error = lua_pcall(luaState, 0, 0, 0);
122    if( error == 0)
123      return true;
124     else
125      {
126       reportError(error);
127       return false;
128      }
129   }
130   return false;
131 }
132
133 bool Script::selectFunction(std::string& functionName, int retCount)
134 {
135   if(returnCount == 0 && currentFunction.length() == 0) //no return values left on the stack and no other function selected
136   {
137   lua_pushlstring(luaState, functionName.c_str(), functionName.size() );
138   lua_gettable(luaState, LUA_GLOBALSINDEX);
139
140   if(lua_isfunction( luaState , -1))
141   {
142     returnCount = retCount;
143     argumentCount = 0;
144     currentFunction = functionName;
145     return true;
146   }
147   else
148    return false;
149   }
150   else
151     printf("There is an other function active ( %s ) or there are unremoved return values on the stack. Please remove them first.\n",currentFunction.c_str());
152   return false;
153 }
154
155 //return number of returned values
156 bool Script::executeFunction()
157 {
158   if(currentFunction.length() != 0 )
159   {
160    int error = lua_pcall(luaState, argumentCount, returnCount,0);
161    if(error != 0)
162    {
163     reportError(error);
164     return false;
165    }
166    else
167    {
168      currentFunction.assign("");//a function gets unusable after beeing called for the first time
169      argumentCount = 0;
170      return true;
171    }
172   }
173   else
174     printf("Error: no function selected.\n");
175 }
176
177
178 //overload this function to add different types
179 bool Script::pushParam(int param, std::string& toFunction)
180 {
181   if(currentFunction.compare(toFunction) == 0)
182   {
183     lua_pushnumber(luaState, (lua_Number) param);
184     argumentCount++;
185    return true;
186   }
187   else
188   {
189    printf("Couldn't add parameter because the wrong function is selected: %s instead of %s\n", currentFunction.c_str(), toFunction.c_str());
190    return false;
191   }
192
193 }
194
195
196 bool Script::pushParam(float param, std::string& toFunction)
197 {
198   if(currentFunction.compare(toFunction) == 0)
199   {
200     lua_pushnumber(luaState,(lua_Number) param);
201     argumentCount++;
202     return true;
203   }
204   else
205   {
206     printf("Couldn't add parameter because the wrong function is selected: %s instead of %s\n", currentFunction.c_str(), toFunction.c_str());
207     return false;
208   }
209
210 }
211
212 bool Script::pushParam(double param, std::string& toFunction)
213 {
214   if(currentFunction.compare(toFunction) == 0)
215   {
216     lua_pushnumber(luaState,(lua_Number) param);
217     argumentCount++;
218     return true;
219   }
220   else
221   {
222     printf("Couldn't add parameter because the wrong function is selected: %s instead of %s\n", currentFunction.c_str(), toFunction.c_str());
223     return false;
224   }
225
226 }
227
228 int Script::getReturnedInt()
229 {
230   int returnValue;
231   if(returnCount > 0)
232   {
233     if(lua_isnumber(luaState, -1))
234     {
235       returnValue = (int)lua_tonumber(luaState, -1);
236       returnCount--;
237       lua_pop(luaState,1);
238     }
239   }
240   return returnValue;
241 }
242
243
244 bool Script::getReturnedBool()
245 {
246   bool returnValue;
247   if(returnCount > 0)
248   {
249     if(lua_isboolean(luaState, -1))
250     {
251       returnValue = (bool)lua_toboolean(luaState, -1);
252       returnCount--;
253       lua_pop(luaState,1);
254     }
255   }
256   return returnValue;
257 }
258
259float Script::getReturnedFloat()
260 {
261   float returnValue;
262   if(returnCount > 0)
263   {
264     if(lua_isnumber(luaState, -1))
265     {
266       returnValue = (float)lua_tonumber(luaState, -1);
267       returnCount--;
268       lua_pop(luaState,1);
269     }
270   }
271   return returnValue;
272 }
273
274 void Script::getReturnedString(std::string& string)
275 {
276   const char* returnValue;
277   if(returnCount > 0)
278   {
279     if(lua_isstring(luaState, -1))
280     {
281       returnValue = lua_tostring(luaState, -1);
282       returnCount--;
283       lua_pop(luaState,1);
284     }
285   }
286  string.assign(returnValue);
287 }
288
289 int Script::reportError(int error)
290 {
291 if(error != 0)
292 {
293  const char *msg = lua_tostring(luaState, -1);
294  if (msg == NULL) msg = "(error with no message)";
295  fprintf(stderr, "ERROR: %s\n", msg);
296  lua_pop(luaState, 1);
297  return error;
298 }
299 }
300
301 
302 bool Script::classIsRegistered(const std::string& type)
303 {
304   for(std::list<WorldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
305   {
306     if( (*it).type == type)
307     {
308       return true;
309     }
310   }
311   return false;
312 }
313 
314 
315 
316 bool Script::objectIsAdded(const std::string& name)
317 {
318   for(std::list<WorldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
319   {
320     if( (*it).name == name)
321     {
322       return true;
323     }
324   }
325   return false;
326 
327 
328 }
Note: See TracBrowser for help on using the repository browser.