Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

new_class_id: hups… this was bad naming… confusing too.

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