Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

injected silvans patch

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