Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10321 was 10321, checked in by patrick, 17 years ago

silvans complete patch

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