Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/heathaze/src/lib/script_engine/script.cc @ 10292

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

patch that allows to organize the scripts in folders

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