Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/script_engine/script.cc @ 9012

Last change on this file since 9012 was 9003, checked in by bensch, 19 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
RevLine 
[8711]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
[8075]16#include "script.h"
[8202]17#include "script_class.h"
18#include "luaincl.h"
[8197]19
[8711]20#include "util/loading/resource_manager.h"
[8202]21
[8193]22#include "loading/load_param.h"
[8197]23#include "parser/tinyxml/tinyxml.h"
[8075]24
[8197]25#include "class_list.h"
[9003]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//                               ):
[8075]30
[8193]31Script::Script(const TiXmlElement* root)
[8075]32{
[8193]33  this->setClassID(CL_SCRIPT, "Script");
[8231]34
[8075]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);
[8193]45  if (root != NULL)
46    this->loadParams(root);
[8075]47}
48
49
50Script::~Script()
51{
52  lua_setgcthreshold(luaState, 0);  // collected garbage
53  lua_close(luaState);
54}
55
56
[8193]57void Script::loadParams(const TiXmlElement* root)
58{
[8408]59  //printf("Loading params for %p \n",this);
[8199]60  BaseObject::loadParams(root);
[8231]61
[8197]62  LOAD_PARAM_START_CYCLE(root, object);
[8193]63  {
[8197]64    LoadParam_CYCLE(object, "object", this, Script, addObject)
[8193]65        .describe("The name of an object that is needed by a script");
66  }
[8197]67  LOAD_PARAM_END_CYCLE(object);
[8193]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)
[8075]78 {
[9003]79   this->setName(filename);
[8711]80   std::string filedest(ResourceManager::getInstance()->getDataDir());
81   filedest += "scripts/" + filename;
82   
[8075]83   if(currentFile.length() != 0)
[8131]84   {
[8075]85     printf("Could not load %s because an other file is already loaded: %s\n",filename.c_str(), currentFile.c_str());
[8085]86     return false;
87    }
[8075]88
[8711]89   int error = luaL_loadfile (luaState, filedest.c_str());
[8075]90
91   if(error == 0)
92   {
[8711]93     
[8075]94     error = lua_pcall(luaState, 0, 0, 0);
95
96     if(error == 0)
97     {
98      currentFile = filename;
[9003]99      //this->addThisScript();
[8075]100      return true;
101     }
102     else
103     {
[8408]104       printf("ERROR while loading file %s: \n",filename.c_str());
105       reportError(error);
[8075]106     }
107
108   }
109   else
110   {
[8408]111     printf("ERROR while loading file %s: \n",filename.c_str());
[8075]112     reportError(error);
113   }
114
115   return false;
116 }
117
[8231]118
[8193]119 void Script::addObject(const std::string& className, const std::string& objectName)
120 {
[8783]121  // printf("Script %p: I am about to add %s of class %s\n",this,objectName.c_str(),className.c_str());
[8408]122
[8202]123   BaseObject* scriptClass = ClassList::getObject(className, CL_SCRIPT_CLASS);
[8783]124  // printf("The script class for %s is at %p \n",className.c_str(),scriptClass);
[8207]125   WorldObject tmpObj;
[8197]126   if (scriptClass != NULL)
127   {
[8231]128     tmpObj.type = className;
[8206]129     if( !classIsRegistered(className) )
[8207]130     {
[8202]131     static_cast<ScriptClass*>(scriptClass)->registerClass(this);
[8207]132     }
[8231]133
[8197]134     BaseObject* object = ClassList::getObject(objectName, className);
[8783]135    // printf("%s is at %p \n",objectName.c_str(),object);
[8206]136     if (object != NULL && !objectIsAdded(objectName))
[8197]137     {
[8202]138        static_cast<ScriptClass*>(scriptClass)->insertObject(this, object, false);
[8207]139        tmpObj.name = objectName;
140        registeredObjects.push_back(tmpObj);
[8197]141     }
142   }
[8193]143 }
144
[8231]145
146
147
[8075]148 bool Script::executeFile()
149 {
[8231]150   printf("WARNING: script.executeFile is not implemented yet");
151   /*if(currentFile.length() != 0)
[8075]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      }
[8231]161 }*/
[8075]162   return false;
163 }
164
165 bool Script::selectFunction(std::string& functionName, int retCount)
166 {
[8085]167   if(returnCount == 0 && currentFunction.length() == 0) //no return values left on the stack and no other function selected
[8075]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
[8085]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;
[8075]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    {
[8408]195     printf("ERROR while executing function %s: \n",currentFunction.c_str());
[8075]196     reportError(error);
[8408]197     //clean up
198     currentFunction.assign("");
199     argumentCount = returnCount = 0;
[8075]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");
[8408]211
212   return false;
[8075]213 }
214
215
216 //overload this function to add different types
217 bool Script::pushParam(int param, std::string& toFunction)
218 {
[8711]219   if(currentFunction == toFunction)
[8075]220   {
221     lua_pushnumber(luaState, (lua_Number) param);
222     argumentCount++;
[8711]223     return true;
[8075]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 {
[8408]268   int returnValue = 0;
[8075]269   if(returnCount > 0)
270   {
[8408]271     if(lua_isnumber(luaState, -1*returnCount))
[8075]272     {
[8408]273       returnValue = (int)lua_tonumber(luaState, -1*returnCount);
274       lua_remove(luaState,-1*returnCount);
[8075]275       returnCount--;
[8408]276       
[8075]277     }
278   }
279   return returnValue;
280 }
281
282
283 bool Script::getReturnedBool()
284 {
[8408]285   bool returnValue = false;
[8075]286   if(returnCount > 0)
287   {
[8408]288     if(lua_isboolean(luaState, -1*returnCount))
[8075]289     {
[8408]290       returnValue = (bool)lua_toboolean(luaState, -1*returnCount);
291       lua_remove(luaState,-1*returnCount);
[8075]292       returnCount--;
293     }
[8711]294     else
295       printf("ERROR: Form %s : trying to retreive non bolean value",this->currentFile.c_str());
[8075]296   }
297   return returnValue;
298 }
299
300float Script::getReturnedFloat()
301 {
[8408]302   float returnValue = 0.0f;
[8075]303   if(returnCount > 0)
304   {
[8408]305     if(lua_isnumber(luaState, -1*returnCount))
[8075]306     {
[8408]307       returnValue = (float)lua_tonumber(luaState, -1*returnCount);
308       lua_remove(luaState,-1*returnCount);
[8075]309       returnCount--;
310     }
311   }
312   return returnValue;
313 }
314
[8131]315 void Script::getReturnedString(std::string& string)
316 {
[8408]317   const char* returnValue = "";
[8131]318   if(returnCount > 0)
319   {
[8408]320     if(lua_isstring(luaState, -1*returnCount))
[8131]321     {
[8408]322       returnValue = lua_tostring(luaState, -1*returnCount);
323       lua_remove(luaState,-1*returnCount);
[8131]324       returnCount--;
325     }
326   }
327  string.assign(returnValue);
328 }
329
[9003]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
[8075]341 int Script::reportError(int error)
342 {
[8085]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);
[8408]349 }
[8085]350  return error;
[8075]351 }
352
[8711]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 }
[8231]382
[8206]383 bool Script::classIsRegistered(const std::string& type)
384 {
[8207]385   for(std::list<WorldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
[8206]386   {
387     if( (*it).type == type)
388     {
389       return true;
390     }
391   }
392   return false;
393 }
[8231]394
395
396
[8206]397 bool Script::objectIsAdded(const std::string& name)
398 {
[8207]399   for(std::list<WorldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
[8206]400   {
401     if( (*it).name == name)
402     {
403       return true;
404     }
405   }
406   return false;
[8231]407
408
[8206]409 }
Note: See TracBrowser for help on using the repository browser.