Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

all scripts now get loaded from datadir/scripts

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