Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

adapted script_engine

File size: 10.5 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"
[9298]19#include "debug.h"
[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
[9692]25CREATE_SCRIPTABLE_CLASS(Script, Script::classID(),
[9061]26                    addMethod("addObject", ExecutorLua2<Script,const std::string&, const std::string& >(&Script::addObject))
[9235]27                    ->addMethod("registerClass", ExecutorLua1<Script,const std::string&>(&Script::registerClass))
[9061]28                    ->addMethod("selectFunction", ExecutorLua2ret<Script, bool, const std::string&, int >(&Script::selectFunction))
29                    ->addMethod("executeFunction", ExecutorLua0ret<Script,bool >(&Script::executeFunction))
30                     );
[8075]31
[9692]32NewObjectListDefinition(Script);
33
[8193]34Script::Script(const TiXmlElement* root)
[8075]35{
[9692]36  this->registerObject(this, Script::_objectList);
[8231]37
[8075]38  returnCount = argumentCount = 0;
39
40  luaState = lua_open();
41
42  luaopen_base(luaState);
43  luaopen_table(luaState);
44  luaopen_io(luaState);
45  luaopen_string(luaState);
46  luaopen_math(luaState);
47  luaopen_debug(luaState);
[8193]48  if (root != NULL)
49    this->loadParams(root);
[8075]50}
51
52
[9298]53Script::Script(const std::string& filename)
54{
[9699]55  this->registerObject(this, Script::_objectList);
[9298]56
57  returnCount = argumentCount = 0;
58
59  luaState = lua_open();
60
61  luaopen_base(luaState);
62  luaopen_table(luaState);
63  luaopen_io(luaState);
64  luaopen_string(luaState);
65  luaopen_math(luaState);
66  luaopen_debug(luaState);
[9692]67
[9298]68  this->loadFile(filename);
69
70}
71
[8075]72Script::~Script()
73{
74  lua_setgcthreshold(luaState, 0);  // collected garbage
75  lua_close(luaState);
76}
77
78
[8193]79void Script::loadParams(const TiXmlElement* root)
80{
[9298]81  //printf(("Loading params for %p \n",this);
[8199]82  BaseObject::loadParams(root);
[8231]83
[9298]84 LOAD_PARAM_START_CYCLE(root, object);
[8193]85  {
[8197]86    LoadParam_CYCLE(object, "object", this, Script, addObject)
[9298]87       .describe("The name of an object that is needed by a script");
[8193]88  }
[9298]89 LOAD_PARAM_END_CYCLE(object);
[8193]90
91
92  LoadParam(root, "file", this, Script, loadFileNoRet)
93      .describe("the fileName of the script, that should be loaded into this world")
94      .defaultValues("");
95}
96
97
98
99bool Script::loadFile(const std::string& filename)
[8075]100 {
[8711]101   std::string filedest(ResourceManager::getInstance()->getDataDir());
102   filedest += "scripts/" + filename;
[9692]103
[9061]104   this->addThisScript();
105   this->registerStandartClasses();
[9692]106
[8075]107   if(currentFile.length() != 0)
[8131]108   {
[9298]109     printf("SCRIPT %s : ERROR: Could not load %s because an other file is already loaded: %s\n",currentFile.c_str(),filename.c_str(), currentFile.c_str());
[8085]110     return false;
111    }
[8075]112
[8711]113   int error = luaL_loadfile (luaState, filedest.c_str());
[8075]114
115   if(error == 0)
116   {
[9235]117     currentFile = filename;
[8075]118     error = lua_pcall(luaState, 0, 0, 0);
119
120     if(error == 0)
121     {
122      return true;
123     }
124     else
125     {
[9298]126       printf("SCRIPT %s : ERROR: while loading file %s: \n",currentFile.c_str(),filename.c_str());
[8408]127       reportError(error);
[8075]128     }
129
130   }
131   else
132   {
[9298]133     printf("SCRIPT %s : ERROR: while loading file %s: \n",currentFile.c_str(),filename.c_str());
[8075]134     reportError(error);
135   }
136
137   return false;
138 }
139
[8231]140
[8193]141 void Script::addObject(const std::string& className, const std::string& objectName)
142 {
[9298]143   //printf(("Script %s: I am about to add %s of class %s\n",this->getName(),objectName.c_str(),className.c_str());
[8408]144
[9699]145   ScriptClass* scriptClass = ScriptClass::objectList().getObject(className);
[9298]146  // printf(("The script class for %s is at %p \n",className.c_str(),scriptClass);
[8207]147   WorldObject tmpObj;
[8197]148   if (scriptClass != NULL)
149   {
[8231]150     tmpObj.type = className;
[8206]151     if( !classIsRegistered(className) )
[8207]152     {
[9699]153       scriptClass->registerClass(this);
[8207]154     }
[8231]155
[9699]156     BaseObject* object = NewObjectListBase::getBaseObject(objectName, className);
[9298]157    // printf(("%s is at %p \n",objectName.c_str(),object);
[8206]158     if (object != NULL && !objectIsAdded(objectName))
[8197]159     {
[9699]160        scriptClass->insertObject(this, object, false);
[8207]161        tmpObj.name = objectName;
162        registeredObjects.push_back(tmpObj);
[8197]163     }
164   }
[8193]165 }
166
[8231]167
168
169
[8075]170 bool Script::executeFile()
171 {
[9298]172   PRINT(2)("WARNING: script.executeFile is not implemented yet\n");
[8231]173   /*if(currentFile.length() != 0)
[8075]174   {
175    int error = lua_pcall(luaState, 0, 0, 0);
176    if( error == 0)
177      return true;
178     else
179      {
180       reportError(error);
181       return false;
182      }
[8231]183 }*/
[8075]184   return false;
185 }
186
[9061]187 bool Script::selectFunction(const std::string& functionName, int retCount)
[8075]188 {
[8085]189   if(returnCount == 0 && currentFunction.length() == 0) //no return values left on the stack and no other function selected
[8075]190   {
191   lua_pushlstring(luaState, functionName.c_str(), functionName.size() );
192   lua_gettable(luaState, LUA_GLOBALSINDEX);
193
194   if(lua_isfunction( luaState , -1))
195   {
196     returnCount = retCount;
197     argumentCount = 0;
198     currentFunction = functionName;
199     return true;
200   }
201   else
202    return false;
203   }
204   else
[9298]205     printf("SCRIPT %s : ERROR: There is an other function active ( %s ) or there are unremoved return values on the stack. Please remove them first.\n",currentFile.c_str(),currentFunction.c_str());
[8085]206   return false;
[8075]207 }
208
209 //return number of returned values
210 bool Script::executeFunction()
211 {
212   if(currentFunction.length() != 0 )
213   {
214    int error = lua_pcall(luaState, argumentCount, returnCount,0);
215    if(error != 0)
216    {
[9298]217      printf("SCRIPT %s : ERROR: Failed to execute function %s: \n",currentFile.c_str(),currentFunction.c_str());
[8075]218     reportError(error);
[8408]219     //clean up
220     currentFunction.assign("");
221     argumentCount = returnCount = 0;
[8075]222     return false;
223    }
224    else
225    {
226      currentFunction.assign("");//a function gets unusable after beeing called for the first time
227      argumentCount = 0;
228      return true;
229    }
230   }
231   else
[9298]232     printf("SCRIPT %s : ERROR: no function selected.\n",currentFile.c_str());
[8408]233
234   return false;
[8075]235 }
236
237
238 //overload this function to add different types
239 bool Script::pushParam(int param, std::string& toFunction)
240 {
[8711]241   if(currentFunction == toFunction)
[8075]242   {
243     lua_pushnumber(luaState, (lua_Number) param);
244     argumentCount++;
[8711]245     return true;
[8075]246   }
247   else
248   {
[9298]249     printf("SCRIPT %s : ERROR: Couldn't add parameter because the wrong function is selected: %s instead of %s\n",currentFile.c_str(), currentFunction.c_str(), toFunction.c_str());
[8075]250    return false;
251   }
252
253 }
254
255
256 bool Script::pushParam(float param, std::string& toFunction)
257 {
258   if(currentFunction.compare(toFunction) == 0)
259   {
260     lua_pushnumber(luaState,(lua_Number) param);
261     argumentCount++;
262     return true;
263   }
264   else
265   {
[9298]266     printf("SCRIPT %s : ERROR: Couldn't add parameter because the wrong function is selected: %s instead of %s\n",currentFile.c_str(), currentFunction.c_str(), toFunction.c_str());
[8075]267     return false;
268   }
269
270 }
271
272 bool Script::pushParam(double param, std::string& toFunction)
273 {
274   if(currentFunction.compare(toFunction) == 0)
275   {
276     lua_pushnumber(luaState,(lua_Number) param);
277     argumentCount++;
278     return true;
279   }
280   else
281   {
[9298]282     printf("SCRIPT %s : ERROR: Couldn't add parameter because the wrong function is selected: %s instead of %s\n",currentFile.c_str(), currentFunction.c_str(), toFunction.c_str());
[8075]283     return false;
284   }
285
286 }
287
288 int Script::getReturnedInt()
289 {
[8408]290   int returnValue = 0;
[8075]291   if(returnCount > 0)
292   {
[8408]293     if(lua_isnumber(luaState, -1*returnCount))
[8075]294     {
[8408]295       returnValue = (int)lua_tonumber(luaState, -1*returnCount);
296       lua_remove(luaState,-1*returnCount);
[8075]297       returnCount--;
[9692]298
[8075]299     }
300   }
301   return returnValue;
302 }
303
304
305 bool Script::getReturnedBool()
306 {
[8408]307   bool returnValue = false;
[8075]308   if(returnCount > 0)
309   {
[8408]310     if(lua_isboolean(luaState, -1*returnCount))
[8075]311     {
[8408]312       returnValue = (bool)lua_toboolean(luaState, -1*returnCount);
313       lua_remove(luaState,-1*returnCount);
[8075]314       returnCount--;
315     }
[8711]316     else
[9298]317       printf("SCRIPT %s : ERROR: Trying to retreive non bolean value\n",this->currentFile.c_str());
[8075]318   }
319   return returnValue;
320 }
321
322float Script::getReturnedFloat()
323 {
[8408]324   float returnValue = 0.0f;
[8075]325   if(returnCount > 0)
326   {
[8408]327     if(lua_isnumber(luaState, -1*returnCount))
[8075]328     {
[8408]329       returnValue = (float)lua_tonumber(luaState, -1*returnCount);
330       lua_remove(luaState,-1*returnCount);
[8075]331       returnCount--;
332     }
333   }
334   return returnValue;
335 }
336
[8131]337 void Script::getReturnedString(std::string& string)
338 {
[8408]339   const char* returnValue = "";
[8131]340   if(returnCount > 0)
341   {
[8408]342     if(lua_isstring(luaState, -1*returnCount))
[8131]343     {
[8408]344       returnValue = lua_tostring(luaState, -1*returnCount);
345       lua_remove(luaState,-1*returnCount);
[8131]346       returnCount--;
347     }
348   }
349  string.assign(returnValue);
350 }
351
[9003]352
353void Script::addThisScript()
354{
[9699]355  ScriptClass* scriptClass = ScriptClass::objectList().getObject("Script");
356
357  if (scriptClass != NULL)
[9003]358   {
[9699]359     scriptClass->registerClass(this);
360     scriptClass->insertObject(this, this,"thisscript", false);
[9003]361   }
362}
363
[8075]364 int Script::reportError(int error)
365 {
[8085]366 if(error != 0)
367 {
368  const char *msg = lua_tostring(luaState, -1);
[9298]369  if (msg == NULL) msg = "(error with no message)\n";
370  printf("ERROR: %s\n", msg);
[8085]371  lua_pop(luaState, 1);
[8408]372 }
[8085]373  return error;
[8075]374 }
375
[8711]376 bool Script::registerStandartClasses()
377 {
378   bool success = false;
[9692]379
[9235]380   //this->registerClass(std::string("Vector"));
381    this->registerClass("ScriptTrigger");
382  //  this->registerClass("AttractorMine");
[9061]383
[8711]384   return success;
385 }
[9692]386
387
[9235]388 void Script::registerClass( const std::string& className)
[8711]389 {
[9699]390   ScriptClass* scriptClass = ScriptClass::objectList().getObject(className);
[9298]391   //printf(("The script class for %s is at %p \n",className.c_str(),scriptClass);
[9699]392
[8711]393   WorldObject tmpObj;
394   if (scriptClass != NULL)
395   {
396     tmpObj.type = className;
397     if( !classIsRegistered(className) )
398     {
399       static_cast<ScriptClass*>(scriptClass)->registerClass(this);
400       tmpObj.name = "";
401       registeredObjects.push_back(tmpObj);
[9235]402       return;
[8711]403     }
404   }
[9692]405
[8711]406 }
[8231]407
[8206]408 bool Script::classIsRegistered(const std::string& type)
409 {
[8207]410   for(std::list<WorldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
[8206]411   {
412     if( (*it).type == type)
413     {
414       return true;
415     }
416   }
417   return false;
418 }
[8231]419
420
421
[8206]422 bool Script::objectIsAdded(const std::string& name)
423 {
[8207]424   for(std::list<WorldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
[8206]425   {
426     if( (*it).name == name)
427     {
428       return true;
429     }
430   }
431   return false;
[8231]432
433
[8206]434 }
Note: See TracBrowser for help on using the repository browser.