Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2640 was 2610, checked in by rgrieder, 16 years ago

Prefixed library directory for each internal third party library.
From now on, include for instance <tolua/tolua++> instead of <tolua++.h>
This may avoid problems if external include directories because some of our includes our modified. Consider e.g. ENet to be in /usr/include/enet/enet.h. Then you will have /usr/inlcude as include directory, possibly revealing an installed version of, say, TinyXML++.

  • 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 "core/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.