Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy2/src/core/LuaBind.cc @ 2687

Last change on this file since 2687 was 2344, checked in by rgrieder, 16 years ago

Completed destruction of static elements like XMLPort, Identifier, etc.
Of initially about 250 memory leaks (not in the actual meaning but the memory was never freed anyway) only 1 remains in TinyCpp.

  • Core class is now a normal Singleton that gets created and destroyed in main.
  • The same goes for Language, LuaBind, SignalHandler and PlayerManager.
  • Added a new std::set to the CommandExecutor so that the external ConsoleCommands can get destroyed too.
  • Code for destroying CommandLineArguments
  • Added destruction code for ConstructionCallbacks in Identifier
  • Moved internal identifier map (the one with the typeid(.) names) in a static function in Identifier. This was necessary in order to destroy ALL Identifiers with the static destruction function. Before it was possible to create an Identifier with having a class instance (that would call RegisterObject) for instance by simply accessing it via getIdentifier.
  • Removed a big memory leak in Button (forgot to destroy the ConfigValueContainers)
  • Added destruction code for InputBufferListenerTuples in InputBuffer destructor.
  • Added destruction code for load and save executors in both XMLPortParam and XMLPortObject
  • Added destruction code for ConsoleCommands in GSRoot, GSGraphics and GSLevel (temporary solution anyway)
  • Deleting the CEGUILua script module seems to work properly now, one memory leak less (GUIManager.cc)
  • Added global destruction calls in Main.cc
  • Property svn:eol-style set to native
File size: 7.8 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Benjamin Knecht
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "LuaBind.h"
30
31#include <fstream>
32#include <map>
33
34#include "lua/lua.hpp"
35#include "tolua/tolua++.h"
36#include "tolua/tolua_bind.h"
37#include "util/String.h"
38#include "CoreIncludes.h"
39
40namespace orxonox
41{
42  LuaBind* LuaBind::singletonRef_s = NULL;
43
44  LuaBind::LuaBind()
45  {
46    assert(LuaBind::singletonRef_s == 0);
47    LuaBind::singletonRef_s = this;
48
49    luaState_ = lua_open();
50    luaSource_ = "";
51#if LUA_VERSION_NUM == 501
52    luaL_openlibs(luaState_);
53#else
54    luaopen_base(luaState_);
55    luaopen_string(luaState_);
56    luaopen_table(luaState_);
57    luaopen_math(luaState_);
58    luaopen_io(luaState_);
59    luaopen_debug(luaState_);
60#endif
61    tolua_Core_open(luaState_);
62    output_ = "";
63    isRunning_ = false;
64  }
65
66  void LuaBind::luaPrint(std::string str)
67  {
68    output_ += str;
69//    COUT(4) << "Lua_output!:" << std::endl << str << std::endl << "***" << std::endl;
70    COUT(5) << str;
71  }
72
73  /**
74      @brief Loads the specified file line by line
75      @param filename The filename of the file
76      @param luaTags if true, the loaded file gets stripped off luaTags
77  */
78  void LuaBind::loadFile(std::string filename, bool luaTags)
79  {
80    output_ = "";
81    std::ifstream file;
82    file.open(filename.c_str(), std::fstream::in);
83
84    if (!file.is_open())
85    {
86      // some error msg
87    }
88
89    char line[1024];
90    std::string levelString = "";
91
92    while (file.good() && !file.eof())
93    {
94      file.getline(line, 1024);
95      levelString += line;
96      levelString += "\n";
97    }
98
99    file.close();
100    //std::string output;
101
102    if (luaTags) luaSource_ = replaceLuaTags(levelString);
103    COUT(5) << "ParsedSourceCode: " << luaSource_ << std::endl;
104  }
105
106  void LuaBind::loadString(std::string code)
107  {
108    luaSource_ = code;
109    output_ = "";
110  }
111
112#if LUA_VERSION_NUM != 501
113  const char * LuaBind::lua_Chunkreader(lua_State *L, void *data, size_t *size)
114  {
115    LoadS* ls = ((LoadS*)data);
116    if (ls->size == 0) return NULL;
117    *size = ls->size;
118    ls->size = 0;
119    return ls->s;
120  }
121#endif
122  void LuaBind::run()
123  {
124    if (!isRunning_)
125    {
126      isRunning_ = true;
127      int error = 0;
128      std::string init = "local scr = orxonox.LuaBind:getInstance()\nlocal debug = print\nprint = function(s)\nscr:luaPrint(s)\nend\ninclude = function(f)\nfile = assert(io.open(\"" + this->includePath_ + "\"..\"/\"..f))\ncontent = file:read(\"*a\")\nfile:close()\nsource = scr:replaceLuaTags(content)\nassert(loadstring(source))()\nend\n";
129      init += luaSource_;
130  #if LUA_VERSION_NUM == 501
131      error = luaL_loadstring(luaState_, init.c_str());
132  #else
133      LoadS ls;
134      ls.s = init.c_str();
135      ls.size = init.size();
136      error = lua_load(luaState_, &orxonox::LuaBind::lua_Chunkreader, &ls, init.c_str());
137  #endif
138      if (error == 0)
139      {
140        error = lua_pcall(luaState_, 0, 0, 0);
141      }
142      if (error != 0)
143      {
144        COUT(2) << "Error in Lua-script: " << lua_tostring(luaState_, -1) << std::endl;
145      }
146      isRunning_ = false;
147    }
148    else
149    {
150      COUT(2) << "Warning: Lua's run is called while running!" << std::endl;
151    }
152  }
153
154  std::string LuaBind::replaceLuaTags(const std::string& text)
155  {
156    // chreate map with all Lua tags
157    std::map<size_t, bool> luaTags;
158    {
159      size_t pos = 0;
160      while ((pos = text.find("<?lua", pos)) != std::string::npos)
161        luaTags[pos++] = true;
162    }
163    {
164      size_t pos = 0;
165      while ((pos = text.find("?>", pos)) != std::string::npos)
166        luaTags[pos++] = false;
167    }
168
169    // erase all tags from the map that are between two quotes
170    {
171      std::map<size_t, bool>::iterator it = luaTags.begin();
172      std::map<size_t, bool>::iterator it2 = it;
173      bool bBetweenQuotes = false;
174      size_t pos = 0;
175      while ((pos = getNextQuote(text, pos)) != std::string::npos)
176      {
177        while ((it != luaTags.end()) && (it->first < pos))
178        {
179          if (bBetweenQuotes) {
180            it2++;
181            if(it->second && !(it2->second) && it2->first < pos)
182              it = ++it2;
183            else
184              luaTags.erase(it++);
185          }
186          else
187            ++it;
188        }
189        bBetweenQuotes = !bBetweenQuotes;
190        pos++;
191      }
192    }
193
194    // check whether on every opening <?lua tag a closing ?> tag follows
195    {
196      bool expectedValue = true;
197      for (std::map<size_t, bool>::iterator it = luaTags.begin(); it != luaTags.end(); ++it)
198      {
199        if (it->second == expectedValue)
200          expectedValue = !expectedValue;
201        else
202        {
203          expectedValue = false;
204          break;
205        }
206      }
207      if (!expectedValue) {
208        COUT(2) << "Warning: Error in level file" << std::endl;
209        // todo: errorhandling
210        return "";
211      }
212    }
213
214    // cut the original string into pieces and put them together with print() instead of lua tags
215    std::string output;
216    {
217      std::map<size_t, bool>::iterator it = luaTags.begin();
218      bool bInPrintFunction = true;
219      size_t start = 0;
220      size_t end = 0;
221
222      do
223      {
224        if (it != luaTags.end())
225          end = (*(it++)).first;
226        else
227          end = std::string::npos;
228
229        unsigned int equalSignCounter = 0;
230
231        if (bInPrintFunction)
232        {
233          // count ['='[ and ]'='] and replace tags with print([[ and ]])
234          std::string temp = text.substr(start, end - start);
235          {
236            size_t pos = 0;
237            while ((pos = temp.find('[', pos)) != std::string::npos)
238            {
239              unsigned int tempCounter = 1;
240              size_t tempPos = pos++;
241              while(temp[++tempPos] == '=') {
242                tempCounter++;
243              }
244              if(temp[tempPos] != '[') {
245                tempCounter = 0;
246              }
247              else if(tempCounter == 0) {
248                tempCounter = 1;
249              }
250              if (tempCounter > equalSignCounter)
251                equalSignCounter = tempCounter;
252            }
253          }
254          {
255            size_t pos = 0;
256            while ((pos = temp.find(']', pos)) != std::string::npos)
257            {
258              unsigned int tempCounter = 1;
259              size_t tempPos = pos++;
260              while(temp[++tempPos] == '=') {
261                tempCounter++;
262              }
263              if(temp[tempPos] != ']') {
264                tempCounter = 0;
265              }
266              else if(tempCounter == 0) {
267                tempCounter = 1;
268              }
269              if (tempCounter > equalSignCounter)
270                equalSignCounter = tempCounter;
271            }
272          }
273          std::string equalSigns = "";
274          for(unsigned int i = 0; i < equalSignCounter; i++) {
275            equalSigns += "=";
276          }
277          output += "print([" + equalSigns + "[" + temp + "]" + equalSigns +"])";
278          start = end + 5;
279        }
280        else
281        {
282          output += text.substr(start, end - start);
283          start = end + 2;
284        }
285
286        bInPrintFunction = !bInPrintFunction;
287      }
288      while (end != std::string::npos);
289    }
290
291    return output;
292  }
293
294}
Note: See TracBrowser for help on using the repository browser.