Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/script_engine/script.cc @ 8881

Last change on this file since 8881 was 8783, checked in by patrick, 18 years ago

merged the script engine branche back to trunk

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