Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 9744 was 9298, checked in by bensch, 18 years ago

orxonox/trunk: merged the branche scripting back here.

merged with command:
svn merge -r9239:HEAD https://svn.orxonox.net/orxonox/branches/scripting .
no conflicts

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