Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/buildsystem2/src/core/LuaBind.cc @ 2664

Last change on this file since 2664 was 2641, checked in by rgrieder, 16 years ago
  • Update to boost 1.37: System library is now REQUIRED when finding boost even if you have less than boost 1.35. If this is problem, it's going to get quite ugly, but it's possible.
  • Fixed a problem in cpptcl.cc: Boost 1.36 introduced boost::exception which conflicted with std::exception (cpptcl makes use of 'using namespace'…)
  • Fixed two little bugs for tolua bind files and gcc warnings
  • Property svn:eol-style set to native
  • Property svn:mergeinfo set to (toggle deleted branches)
    /code/branches/buildsystem/src/core/Script.ccmergedeligible
    /code/branches/questsystem2/src/core/LuaBind.ccmergedeligible
    /code/branches/buildsystem/src/core/LuaBind.cc1874-2276,​2278-2400
    /code/branches/ceguilua/src/core/LuaBind.cc1802-1808
    /code/branches/core3/src/core/LuaBind.cc1572-1739
    /code/branches/gcc43/src/core/LuaBind.cc1580
    /code/branches/gui/src/core/LuaBind.cc1635-1723
    /code/branches/input/src/core/LuaBind.cc1629-1636
    /code/branches/objecthierarchy/src/core/LuaBind.cc1911-2085,​2100,​2110-2169
    /code/branches/pickups/src/core/LuaBind.cc1926-2086
    /code/branches/questsystem/src/core/LuaBind.cc1894-2088
    /code/branches/script_trigger/src/core/LuaBind.cc1295-1953,​1955
    /code/branches/weapon/src/core/LuaBind.cc1925-2094
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
34extern "C" {
35#include <lua.h>
36#include <lualib.h>
37}
38#include <tolua/tolua++.h>
39
40#include "ToluaBindCore.h"
41#include "util/String.h"
42#include "CoreIncludes.h"
43
44namespace orxonox
45{
46  LuaBind* LuaBind::singletonRef = NULL;
47
48  LuaBind::LuaBind()
49  {
50    luaState_ = lua_open();
51    luaSource_ = "";
52#if LUA_VERSION_NUM == 501
53    luaL_openlibs(luaState_);
54#else
55    luaopen_base(luaState_);
56    luaopen_string(luaState_);
57    luaopen_table(luaState_);
58    luaopen_math(luaState_);
59    luaopen_io(luaState_);
60    luaopen_debug(luaState_);
61#endif
62    tolua_Core_open(luaState_);
63    output_ = "";
64    isRunning_ = false;
65  }
66
67  void LuaBind::luaPrint(std::string str)
68  {
69    output_ += str;
70//    COUT(4) << "Lua_output!:" << std::endl << str << std::endl << "***" << std::endl;
71    COUT(5) << str;
72  }
73
74  /**
75      @brief Loads the specified file line by line
76      @param filename The filename of the file
77      @param luaTags if true, the loaded file gets stripped off luaTags
78  */
79  void LuaBind::loadFile(std::string filename, bool luaTags)
80  {
81    output_ = "";
82    std::ifstream file;
83    file.open(filename.c_str(), std::fstream::in);
84
85    if (!file.is_open())
86    {
87      // some error msg
88    }
89
90    char line[1024];
91    std::string levelString = "";
92
93    while (file.good() && !file.eof())
94    {
95      file.getline(line, 1024);
96      levelString += line;
97      levelString += "\n";
98    }
99
100    file.close();
101    //std::string output;
102
103    if (luaTags) luaSource_ = replaceLuaTags(levelString);
104    COUT(5) << "ParsedSourceCode: " << luaSource_ << std::endl;
105  }
106
107  void LuaBind::loadString(std::string code)
108  {
109    luaSource_ = code;
110    output_ = "";
111  }
112
113#if LUA_VERSION_NUM != 501
114  const char * LuaBind::lua_Chunkreader(lua_State *L, void *data, size_t *size)
115  {
116    LoadS* ls = ((LoadS*)data);
117    if (ls->size == 0) return NULL;
118    *size = ls->size;
119    ls->size = 0;
120    return ls->s;
121  }
122#endif
123  void LuaBind::run()
124  {
125    if (!isRunning_)
126    {
127      isRunning_ = true;
128      int error = 0;
129      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";
130      init += luaSource_;
131  #if LUA_VERSION_NUM == 501
132      error = luaL_loadstring(luaState_, init.c_str());
133  #else
134      LoadS ls;
135      ls.s = init.c_str();
136      ls.size = init.size();
137      error = lua_load(luaState_, &orxonox::LuaBind::lua_Chunkreader, &ls, init.c_str());
138  #endif
139      if (error == 0)
140      {
141        error = lua_pcall(luaState_, 0, 0, 0);
142      }
143      if (error != 0)
144      {
145        COUT(2) << "Error in Lua-script: " << lua_tostring(luaState_, -1) << std::endl;
146      }
147      isRunning_ = false;
148    }
149    else
150    {
151      COUT(2) << "Warning: Lua's run is called while running!" << std::endl;
152    }
153  }
154
155  std::string LuaBind::replaceLuaTags(const std::string& text)
156  {
157    // chreate map with all Lua tags
158    std::map<size_t, bool> luaTags;
159    {
160      size_t pos = 0;
161      while ((pos = text.find("<?lua", pos)) != std::string::npos)
162        luaTags[pos++] = true;
163    }
164    {
165      size_t pos = 0;
166      while ((pos = text.find("?>", pos)) != std::string::npos)
167        luaTags[pos++] = false;
168    }
169
170    // erase all tags from the map that are between two quotes
171    {
172      std::map<size_t, bool>::iterator it = luaTags.begin();
173      std::map<size_t, bool>::iterator it2 = it;
174      bool bBetweenQuotes = false;
175      size_t pos = 0;
176      while ((pos = getNextQuote(text, pos)) != std::string::npos)
177      {
178        while ((it != luaTags.end()) && (it->first < pos))
179        {
180          if (bBetweenQuotes) {
181            it2++;
182            if(it->second && !(it2->second) && it2->first < pos)
183              it = ++it2;
184            else
185              luaTags.erase(it++);
186          }
187          else
188            ++it;
189        }
190        bBetweenQuotes = !bBetweenQuotes;
191        pos++;
192      }
193    }
194
195    // check whether on every opening <?lua tag a closing ?> tag follows
196    {
197      bool expectedValue = true;
198      for (std::map<size_t, bool>::iterator it = luaTags.begin(); it != luaTags.end(); ++it)
199      {
200        if (it->second == expectedValue)
201          expectedValue = !expectedValue;
202        else
203        {
204          expectedValue = false;
205          break;
206        }
207      }
208      if (!expectedValue) {
209        COUT(2) << "Warning: Error in level file" << std::endl;
210        // todo: errorhandling
211        return "";
212      }
213    }
214
215    // cut the original string into pieces and put them together with print() instead of lua tags
216    std::string output;
217    {
218      std::map<size_t, bool>::iterator it = luaTags.begin();
219      bool bInPrintFunction = true;
220      size_t start = 0;
221      size_t end = 0;
222
223      do
224      {
225        if (it != luaTags.end())
226          end = (*(it++)).first;
227        else
228          end = std::string::npos;
229
230        unsigned int equalSignCounter = 0;
231
232        if (bInPrintFunction)
233        {
234          // count ['='[ and ]'='] and replace tags with print([[ and ]])
235          std::string temp = text.substr(start, end - start);
236          {
237            size_t pos = 0;
238            while ((pos = temp.find('[', pos)) != std::string::npos)
239            {
240              unsigned int tempCounter = 1;
241              size_t tempPos = pos++;
242              while(temp[++tempPos] == '=') {
243                tempCounter++;
244              }
245              if(temp[tempPos] != '[') {
246                tempCounter = 0;
247              }
248              else if(tempCounter == 0) {
249                tempCounter = 1;
250              }
251              if (tempCounter > equalSignCounter)
252                equalSignCounter = tempCounter;
253            }
254          }
255          {
256            size_t pos = 0;
257            while ((pos = temp.find(']', pos)) != std::string::npos)
258            {
259              unsigned int tempCounter = 1;
260              size_t tempPos = pos++;
261              while(temp[++tempPos] == '=') {
262                tempCounter++;
263              }
264              if(temp[tempPos] != ']') {
265                tempCounter = 0;
266              }
267              else if(tempCounter == 0) {
268                tempCounter = 1;
269              }
270              if (tempCounter > equalSignCounter)
271                equalSignCounter = tempCounter;
272            }
273          }
274          std::string equalSigns = "";
275          for(unsigned int i = 0; i < equalSignCounter; i++) {
276            equalSigns += "=";
277          }
278          output += "print([" + equalSigns + "[" + temp + "]" + equalSigns +"])";
279          start = end + 5;
280        }
281        else
282        {
283          output += text.substr(start, end - start);
284          start = end + 2;
285        }
286
287        bInPrintFunction = !bInPrintFunction;
288      }
289      while (end != std::string::npos);
290    }
291
292    return output;
293  }
294
295}
Note: See TracBrowser for help on using the repository browser.