Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/scriptchanges.new/src/lib/script_engine/script.cc @ 10350

Last change on this file since 10350 was 10350, checked in by snellen, 17 years ago

object name in orxonox and in the script can now be handled seperately

File size: 11.0 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
173void Script::addObjectAsName( const std::string& className, const std::string& objectName, const std::string& nameInScript)
174 {
175   ScriptClass* scriptClass = ScriptClass::objectList().getObject(className);
176   WorldObject tmpObj;
177   if (scriptClass != NULL)
178   {
179     tmpObj.type = className;
180     if( !classIsRegistered(className) )
181     {
182       scriptClass->registerClass(this);
183     }
184     BaseObject* object = ObjectListBase::getBaseObject(className, objectName);
185     if (object != NULL && !objectIsAdded(objectName))
186     {
187        scriptClass->insertObject(this, object,nameInScript, false);
188        tmpObj.name = objectName;
189        registeredObjects.push_back(tmpObj);
190     }
191   }
192 }
193
194
195
196 bool Script::executeFile()
197 {
198   PRINTF(2)("script.executeFile is not implemented yet\n");
199   /*if(currentFile.length() != 0)
200   {
201    int error = lua_pcall(luaState, 0, 0, 0);
202    if( error == 0)
203      return true;
204     else
205      {
206       reportError(error);
207       return false;
208      }
209 }*/
210   return false;
211 }
212
213 bool Script::selectFunction(const std::string& functionName, int retCount)
214 {
215   if(returnCount == 0 && currentFunction.length() == 0) //no return values left on the stack and no other function selected
216   {
217   lua_pushlstring(luaState, functionName.c_str(), functionName.size() );
218   lua_gettable(luaState, LUA_GLOBALSINDEX);
219
220   if(lua_isfunction( luaState , -1))
221   {
222     returnCount = retCount;
223     argumentCount = 0;
224     currentFunction = functionName;
225     return true;
226   }
227   else
228    return false;
229   }
230   else
231     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());
232   return false;
233 }
234
235 //return number of returned values
236 bool Script::executeFunction()
237 {
238   if(currentFunction.length() != 0 )
239   {
240    int error = lua_pcall(luaState, argumentCount, returnCount,0);
241    if(error != 0)
242    {
243      PRINTF(1)("Script '%s' : Failed to execute function '%s': \n",currentFile.c_str(),currentFunction.c_str());
244     reportError(error);
245     //clean up
246     currentFunction.assign("");
247     argumentCount = returnCount = 0;
248     return false;
249    }
250    else
251    {
252      currentFunction.assign("");//a function gets unusable after beeing called for the first time
253      argumentCount = 0;
254      return true;
255    }
256   }
257   else
258     PRINTF(1)("SCRIPT '%s' : no function selected.\n",currentFile.c_str());
259
260   return false;
261 }
262
263
264 //overload this function to add different types
265 bool Script::pushParam(int param, std::string& toFunction)
266 {
267   if(currentFunction == toFunction)
268   {
269     lua_pushnumber(luaState, (lua_Number) param);
270     argumentCount++;
271     return true;
272   }
273   else
274   {
275     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());
276    return false;
277   }
278
279 }
280
281
282 bool Script::pushParam(float param, std::string& toFunction)
283 {
284   if(currentFunction.compare(toFunction) == 0)
285   {
286     lua_pushnumber(luaState,(lua_Number) param);
287     argumentCount++;
288     return true;
289   }
290   else
291   {
292     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());
293     return false;
294   }
295
296 }
297
298 bool Script::pushParam(double param, std::string& toFunction)
299 {
300   if(currentFunction.compare(toFunction) == 0)
301   {
302     lua_pushnumber(luaState,(lua_Number) param);
303     argumentCount++;
304     return true;
305   }
306   else
307   {
308     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());
309     return false;
310   }
311
312 }
313
314 int Script::getReturnedInt()
315 {
316   int returnValue = 0;
317   if(returnCount > 0)
318   {
319     if(lua_isnumber(luaState, -1*returnCount))
320     {
321       returnValue = (int)lua_tonumber(luaState, -1*returnCount);
322       lua_remove(luaState,-1*returnCount);
323       returnCount--;
324
325     }
326   }
327   return returnValue;
328 }
329
330
331 bool Script::getReturnedBool()
332 {
333   bool returnValue = false;
334   if(returnCount > 0)
335   {
336     if(lua_isboolean(luaState, -1*returnCount))
337     {
338       returnValue = (bool)lua_toboolean(luaState, -1*returnCount);
339       lua_remove(luaState,-1*returnCount);
340       returnCount--;
341     }
342     else
343       printf("SCRIPT %s : ERROR: Trying to retreive non bolean value\n",this->currentFile.c_str());
344   }
345   return returnValue;
346 }
347
348float Script::getReturnedFloat()
349 {
350   float returnValue = 0.0f;
351   if(returnCount > 0)
352   {
353     if(lua_isnumber(luaState, -1*returnCount))
354     {
355       returnValue = (float)lua_tonumber(luaState, -1*returnCount);
356       lua_remove(luaState,-1*returnCount);
357       returnCount--;
358     }
359   }
360   return returnValue;
361 }
362
363 void Script::getReturnedString(std::string& string)
364 {
365   const char* returnValue = "";
366   if(returnCount > 0)
367   {
368     if(lua_isstring(luaState, -1*returnCount))
369     {
370       returnValue = lua_tostring(luaState, -1*returnCount);
371       lua_remove(luaState,-1*returnCount);
372       returnCount--;
373     }
374   }
375  string.assign(returnValue);
376 }
377
378
379void Script::addThisScript()
380{
381  ScriptClass* scriptClass = ScriptClass::objectList().getObject("Script");
382
383  if (scriptClass != NULL)
384   {
385     scriptClass->registerClass(this);
386     scriptClass->insertObject(this, this,"thisscript", false);
387   }
388}
389
390 int Script::reportError(int error)
391 {
392 if(error != 0)
393 {
394  const char *msg = lua_tostring(luaState, -1);
395  if (msg == NULL) msg = "(error with no message)\n";
396  printf("ERROR: %s\n", msg);
397  lua_pop(luaState, 1);
398 }
399  return error;
400 }
401
402 bool Script::registerStandartClasses()
403 {
404   bool success = false;
405
406   //this->registerClass(std::string("Vector"));
407    this->registerClass("ScriptTrigger");
408  //  this->registerClass("AttractorMine");
409
410   return success;
411 }
412
413
414 void Script::registerClass( const std::string& className)
415 {
416   ScriptClass* scriptClass = ScriptClass::objectList().getObject(className);
417   //printf(("The script class for %s is at %p \n",className.c_str(),scriptClass);
418
419   WorldObject tmpObj;
420   if (scriptClass != NULL)
421   {
422     tmpObj.type = className;
423     if( !classIsRegistered(className) )
424     {
425       static_cast<ScriptClass*>(scriptClass)->registerClass(this);
426       tmpObj.name = "";
427       registeredObjects.push_back(tmpObj);
428       return;
429     }
430   }
431
432 }
433
434 bool Script::classIsRegistered(const std::string& type)
435 {
436   for(std::list<WorldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
437   {
438     if( (*it).type == type)
439     {
440       return true;
441     }
442   }
443   return false;
444 }
445
446
447
448 bool Script::objectIsAdded(const std::string& name)
449 {
450   for(std::list<WorldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
451   {
452     if( (*it).name == name)
453     {
454       return true;
455     }
456   }
457   return false;
458
459
460 }
Note: See TracBrowser for help on using the repository browser.