Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

script checks now before adding an object and a class wether the class or object has already been added

File size: 6.6 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   if (scriptClass != NULL)
96   {
97     if( !classIsRegistered(className) )
98     static_cast<ScriptClass*>(scriptClass)->registerClass(this);
99     
100     BaseObject* object = ClassList::getObject(objectName, className);
101     if (object != NULL && !objectIsAdded(objectName))
102     {
103        static_cast<ScriptClass*>(scriptClass)->insertObject(this, object, false);
104     }
105   }
106 }
107
108 
109 
110 
111 bool Script::executeFile()
112 {
113   if(currentFile.length() != 0)
114   {
115    int error = lua_pcall(luaState, 0, 0, 0);
116    if( error == 0)
117      return true;
118     else
119      {
120       reportError(error);
121       return false;
122      }
123   }
124   return false;
125 }
126
127 bool Script::selectFunction(std::string& functionName, int retCount)
128 {
129   if(returnCount == 0 && currentFunction.length() == 0) //no return values left on the stack and no other function selected
130   {
131   lua_pushlstring(luaState, functionName.c_str(), functionName.size() );
132   lua_gettable(luaState, LUA_GLOBALSINDEX);
133
134   if(lua_isfunction( luaState , -1))
135   {
136     returnCount = retCount;
137     argumentCount = 0;
138     currentFunction = functionName;
139     return true;
140   }
141   else
142    return false;
143   }
144   else
145     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());
146   return false;
147 }
148
149 //return number of returned values
150 bool Script::executeFunction()
151 {
152   if(currentFunction.length() != 0 )
153   {
154    int error = lua_pcall(luaState, argumentCount, returnCount,0);
155    if(error != 0)
156    {
157     reportError(error);
158     return false;
159    }
160    else
161    {
162      currentFunction.assign("");//a function gets unusable after beeing called for the first time
163      argumentCount = 0;
164      return true;
165    }
166   }
167   else
168     printf("Error: no function selected.\n");
169 }
170
171
172 //overload this function to add different types
173 bool Script::pushParam(int param, std::string& toFunction)
174 {
175   if(currentFunction.compare(toFunction) == 0)
176   {
177     lua_pushnumber(luaState, (lua_Number) param);
178     argumentCount++;
179    return true;
180   }
181   else
182   {
183    printf("Couldn't add parameter because the wrong function is selected: %s instead of %s\n", currentFunction.c_str(), toFunction.c_str());
184    return false;
185   }
186
187 }
188
189
190 bool Script::pushParam(float 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 bool Script::pushParam(double param, std::string& toFunction)
207 {
208   if(currentFunction.compare(toFunction) == 0)
209   {
210     lua_pushnumber(luaState,(lua_Number) param);
211     argumentCount++;
212     return true;
213   }
214   else
215   {
216     printf("Couldn't add parameter because the wrong function is selected: %s instead of %s\n", currentFunction.c_str(), toFunction.c_str());
217     return false;
218   }
219
220 }
221
222 int Script::getReturnedInt()
223 {
224   int returnValue;
225   if(returnCount > 0)
226   {
227     if(lua_isnumber(luaState, -1))
228     {
229       returnValue = (int)lua_tonumber(luaState, -1);
230       returnCount--;
231       lua_pop(luaState,1);
232     }
233   }
234   return returnValue;
235 }
236
237
238 bool Script::getReturnedBool()
239 {
240   bool returnValue;
241   if(returnCount > 0)
242   {
243     if(lua_isboolean(luaState, -1))
244     {
245       returnValue = (bool)lua_toboolean(luaState, -1);
246       returnCount--;
247       lua_pop(luaState,1);
248     }
249   }
250   return returnValue;
251 }
252
253float Script::getReturnedFloat()
254 {
255   float returnValue;
256   if(returnCount > 0)
257   {
258     if(lua_isnumber(luaState, -1))
259     {
260       returnValue = (float)lua_tonumber(luaState, -1);
261       returnCount--;
262       lua_pop(luaState,1);
263     }
264   }
265   return returnValue;
266 }
267
268 void Script::getReturnedString(std::string& string)
269 {
270   const char* returnValue;
271   if(returnCount > 0)
272   {
273     if(lua_isstring(luaState, -1))
274     {
275       returnValue = lua_tostring(luaState, -1);
276       returnCount--;
277       lua_pop(luaState,1);
278     }
279   }
280  string.assign(returnValue);
281 }
282
283 int Script::reportError(int error)
284 {
285 if(error != 0)
286 {
287  const char *msg = lua_tostring(luaState, -1);
288  if (msg == NULL) msg = "(error with no message)";
289  fprintf(stderr, "ERROR: %s\n", msg);
290  lua_pop(luaState, 1);
291  return error;
292 }
293 }
294
295 
296 bool Script::classIsRegistered(const std::string& type)
297 {
298   for(std::list<worldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
299   {
300     if( (*it).type == type)
301     {
302       return true;
303     }
304   }
305   return false;
306 }
307 
308 
309 
310 bool Script::objectIsAdded(const std::string& name)
311 {
312   for(std::list<worldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
313   {
314     if( (*it).name == name)
315     {
316       return true;
317     }
318   }
319   return false;
320 
321 
322 }
Note: See TracBrowser for help on using the repository browser.