Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 9018 was 9003, checked in by bensch, 18 years ago

orxonox/trunk: merged the single_player_map branche back
merged with command:
svn merge -r8896:HEAD https://svn.orxonox.net/orxonox/branches/single_player_map .
no conflicts

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,"thisscript", 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.