Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/scriptchanges/src/lib/script_engine/script.cc @ 10451

Last change on this file since 10451 was 10324, checked in by snellen, 18 years ago

added addObjectAsName

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