Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

fixed compatibility issue

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