Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

perpared possibility to add the script object to the lua script itself (so that all objects can be added from within the script ), prepared possibility to create triggers form within a script

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