Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8290 was 8290, checked in by snellen, 19 years ago

debug output is more verbose now

File size: 7.3 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  if (root != NULL)
26    this->loadParams(root);
27}
28
29
30Script::~Script()
31{
32  lua_setgcthreshold(luaState, 0);  // collected garbage
33  lua_close(luaState);
34}
35
36
37void Script::loadParams(const TiXmlElement* root)
38{
39  printf("Loading params for %p \n",this);
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       printf("ERROR while loading file %s: ",filename.c_str());
80       reportError(error);
81     }
82
83   }
84   else
85   {
86     printf("ERROR while loading file %s: ",filename.c_str());
87     reportError(error);
88   }
89
90   return false;
91 }
92
93
94 void Script::addObject(const std::string& className, const std::string& objectName)
95 {
96   printf("Script %p: I am about to add %s of class %s\n",this,objectName.c_str(),className.c_str());
97   
98   BaseObject* scriptClass = ClassList::getObject(className, CL_SCRIPT_CLASS);
99   WorldObject tmpObj;
100   if (scriptClass != NULL)
101   {
102     tmpObj.type = className;
103     if( !classIsRegistered(className) )
104     {
105     static_cast<ScriptClass*>(scriptClass)->registerClass(this);
106     }
107
108     BaseObject* object = ClassList::getObject(objectName, className);
109     if (object != NULL && !objectIsAdded(objectName))
110     {
111        static_cast<ScriptClass*>(scriptClass)->insertObject(this, object, false);
112        tmpObj.name = objectName;
113        registeredObjects.push_back(tmpObj);
114     }
115   }
116 }
117
118
119
120
121 bool Script::executeFile()
122 {
123   printf("WARNING: script.executeFile is not implemented yet");
124   /*if(currentFile.length() != 0)
125   {
126    int error = lua_pcall(luaState, 0, 0, 0);
127    if( error == 0)
128      return true;
129     else
130      {
131       reportError(error);
132       return false;
133      }
134 }*/
135   return false;
136 }
137
138 bool Script::selectFunction(std::string& functionName, int retCount)
139 {
140   if(returnCount == 0 && currentFunction.length() == 0) //no return values left on the stack and no other function selected
141   {
142   lua_pushlstring(luaState, functionName.c_str(), functionName.size() );
143   lua_gettable(luaState, LUA_GLOBALSINDEX);
144
145   if(lua_isfunction( luaState , -1))
146   {
147     returnCount = retCount;
148     argumentCount = 0;
149     currentFunction = functionName;
150     return true;
151   }
152   else
153    return false;
154   }
155   else
156     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());
157   return false;
158 }
159
160 //return number of returned values
161 bool Script::executeFunction()
162 {
163   if(currentFunction.length() != 0 )
164   {
165    int error = lua_pcall(luaState, argumentCount, returnCount,0);
166    if(error != 0)
167    {
168     printf("ERROR while executing function %s: \n",currentFunction.c_str());
169     reportError(error);
170     //clean up
171     currentFunction.assign(""); 
172     argumentCount = returnCount = 0;
173     return false;
174    }
175    else
176    {
177      currentFunction.assign("");//a function gets unusable after beeing called for the first time
178      argumentCount = 0;
179      return true;
180    }
181   }
182   else
183     printf("Error: no function selected.\n");
184   
185   return false;
186 }
187
188
189 //overload this function to add different types
190 bool Script::pushParam(int param, std::string& toFunction)
191 {
192   if(currentFunction.compare(toFunction) == 0)
193   {
194     lua_pushnumber(luaState, (lua_Number) param);
195     argumentCount++;
196    return true;
197   }
198   else
199   {
200    printf("Couldn't add parameter because the wrong function is selected: %s instead of %s\n", currentFunction.c_str(), toFunction.c_str());
201    return false;
202   }
203
204 }
205
206
207 bool Script::pushParam(float param, std::string& toFunction)
208 {
209   if(currentFunction.compare(toFunction) == 0)
210   {
211     lua_pushnumber(luaState,(lua_Number) param);
212     argumentCount++;
213     return true;
214   }
215   else
216   {
217     printf("Couldn't add parameter because the wrong function is selected: %s instead of %s\n", currentFunction.c_str(), toFunction.c_str());
218     return false;
219   }
220
221 }
222
223 bool Script::pushParam(double param, std::string& toFunction)
224 {
225   if(currentFunction.compare(toFunction) == 0)
226   {
227     lua_pushnumber(luaState,(lua_Number) param);
228     argumentCount++;
229     return true;
230   }
231   else
232   {
233     printf("Couldn't add parameter because the wrong function is selected: %s instead of %s\n", currentFunction.c_str(), toFunction.c_str());
234     return false;
235   }
236
237 }
238
239 int Script::getReturnedInt()
240 {
241   int returnValue;
242   if(returnCount > 0)
243   {
244     if(lua_isnumber(luaState, -1))
245     {
246       returnValue = (int)lua_tonumber(luaState, -1);
247       returnCount--;
248       lua_pop(luaState,1);
249     }
250   }
251   return returnValue;
252 }
253
254
255 bool Script::getReturnedBool()
256 {
257   bool returnValue;
258   if(returnCount > 0)
259   {
260     if(lua_isboolean(luaState, -1))
261     {
262       returnValue = (bool)lua_toboolean(luaState, -1);
263       returnCount--;
264       lua_pop(luaState,1);
265     }
266   }
267   return returnValue;
268 }
269
270float Script::getReturnedFloat()
271 {
272   float returnValue;
273   if(returnCount > 0)
274   {
275     if(lua_isnumber(luaState, -1))
276     {
277       returnValue = (float)lua_tonumber(luaState, -1);
278       returnCount--;
279       lua_pop(luaState,1);
280     }
281   }
282   return returnValue;
283 }
284
285 void Script::getReturnedString(std::string& string)
286 {
287   const char* returnValue;
288   if(returnCount > 0)
289   {
290     if(lua_isstring(luaState, -1))
291     {
292       returnValue = lua_tostring(luaState, -1);
293       returnCount--;
294       lua_pop(luaState,1);
295     }
296   }
297  string.assign(returnValue);
298 }
299
300 int Script::reportError(int error)
301 {
302 if(error != 0)
303 {
304  const char *msg = lua_tostring(luaState, -1);
305  if (msg == NULL) msg = "(error with no message)";
306  fprintf(stderr, "ERROR: %s\n", msg);
307  lua_pop(luaState, 1);
308 }
309  return error;
310 }
311
312
313 bool Script::classIsRegistered(const std::string& type)
314 {
315   for(std::list<WorldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
316   {
317     if( (*it).type == type)
318     {
319       return true;
320     }
321   }
322   return false;
323 }
324
325
326
327 bool Script::objectIsAdded(const std::string& name)
328 {
329   for(std::list<WorldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
330   {
331     if( (*it).name == name)
332     {
333       return true;
334     }
335   }
336   return false;
337
338
339 }
Note: See TracBrowser for help on using the repository browser.