Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Windows runs again without any segfaults
it seems, that windows links object files differently… and extremely strange

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