Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/lib/script_engine/script.cc @ 9692

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

orxonox/new_class_id: some thoughts on a BaseIterator class, that can travers through ObejectLists without knowing the Polymorph type.
This is all virtual, and since templated virutal functions are not allowed, quite hard to implements…
hpe it will work

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