Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/resource2/src/core/LuaState.cc @ 5654

Last change on this file since 5654 was 5654, checked in by rgrieder, 15 years ago
  • Implemented file management via resource manager and loading of resource locations via XML. Changes made:
    • SoundManager loads via memory stream rather than via file
    • Loader uses LuaState::includeFile() to load an XML file and passes the lua tag remover function to its LuaState.
    • ConfigFileManager still loads with hard paths because the files are required before Ogre gets created
  • Renamed LuaBind to LuaState, deSingletonised it and added new features:
    • doFile(), doString(), includeFile(), includeString() where include will preparse the string with a function provided with LuaState::setIncludeParser
    • Moved lua tags replace function to Loader (since it's actually an XML related task)
    • Using data_path/lua/LuaInitScript.lua to provide the following functions
      • logMessage(level, message)
      • doFile, dofile, include (all working with relative paths but within the same resource group)
  • Modified Script class to work with LuaState and fixed its XML Loader
  • Adjusted all level and include files (both "include" and "dofile" lua commands)
  • Property svn:eol-style set to native
File size: 8.9 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 *      Reto Grieder
25 *   Co-authors:
26 *      ...
27 *
28 */
29
30#include "LuaState.h"
31
32#include <tolua/tolua++.h>
33extern "C" {
34#include <lua.h>
35#include <lualib.h>
36}
37
38#include "util/Debug.h"
39#include "Core.h"
40#include "Resource.h"
41
42namespace orxonox
43{
44    LuaState::ToluaInterfaceMap LuaState::toluaInterfaces_s;
45    std::vector<LuaState*> LuaState::instances_s;
46
47    LuaState::LuaState()
48        : bIsRunning_(false)
49        , includeParseFunction_(NULL)
50    {
51        // Create new lua state and configure it
52        luaState_ = lua_open();
53#if LUA_VERSION_NUM == 501
54        luaL_openlibs(luaState_);
55#else
56        luaopen_base(luaState_);
57        luaopen_string(luaState_);
58        luaopen_table(luaState_);
59        luaopen_math(luaState_);
60        luaopen_io(luaState_);
61        luaopen_debug(luaState_);
62#endif
63
64        // Open all available tolua interfaces
65        this->openToluaInterfaces(luaState_);
66
67        // Create dummy file info
68        sourceFileInfo_.reset(new ResourceInfo());
69        sourceFileInfo_->group = "General";
70        sourceFileInfo_->size = 0;
71
72        // Push this pointer
73        tolua_pushusertype(luaState_, static_cast<void*>(this), "orxonox::LuaState");
74        lua_setglobal(luaState_, "luaState");
75
76        // Parse init script
77        // Note: We have to use a hard coded path because the script is required for the resource loading
78        this->doString("dofile(\"" + Core::getDataPathString() + "lua/LuaStateInit.lua\")");
79    }
80
81    LuaState::~LuaState()
82    {
83        lua_close(luaState_);
84    }
85
86    shared_ptr<ResourceInfo> LuaState::getFileInfo(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
87    {
88        shared_ptr<ResourceInfo> sourceInfo;
89        if (resourceGroup != "NoResourceGroupProvided")
90            sourceInfo = Resource::getInfo(filename, resourceGroup);
91
92        // Continue search if not explicitely forbidden
93        if (bSearchOtherPaths && sourceInfo == NULL)
94        {
95            // Call might be relative to the file currently being processed
96            sourceInfo = Resource::getInfo(sourceFileInfo_->path + filename, sourceFileInfo_->group);
97            if (sourceInfo == NULL)
98            {
99                // Maybe find something in the same group but in the root path
100                sourceInfo = Resource::getInfo(filename, sourceFileInfo_->group);
101            }
102        }
103        return sourceInfo;
104    }
105
106    void LuaState::includeFile(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
107    {
108        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename, resourceGroup, bSearchOtherPaths);
109        if (sourceInfo != NULL)
110            this->includeString(Resource::open(sourceInfo->filename, sourceInfo->group)->getAsString(), sourceInfo);
111        else
112            COUT(2) << "LuaState: Cannot include file '" << filename << "' in resource group '"
113                    << (resourceGroup == "NoResourceGroupProvided" ? sourceFileInfo_->group : resourceGroup) << "': group not found." << std::endl;
114    }
115
116    void LuaState::includeString(const std::string& code, shared_ptr<ResourceInfo> sourceFileInfo)
117    {
118        // Parse string with provided include parser (otherwise don't preparse at all)
119        std::string luaInput;
120        if (includeParseFunction_ != NULL)
121            luaInput = (*includeParseFunction_)(code);
122        else
123            luaInput = code;
124
125        this->doString(luaInput, sourceFileInfo);
126    }
127
128    void LuaState::doFile(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
129    {
130        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename, resourceGroup, bSearchOtherPaths);
131        if (sourceInfo != NULL)
132            this->doString(Resource::open(sourceInfo->filename, sourceInfo->group)->getAsString(), sourceInfo);
133        else
134            COUT(2) << "LuaState: Cannot do file '" << filename << "' in resource group '"
135                << (resourceGroup == "NoResourceGroupProvided" ? sourceFileInfo_->group : resourceGroup) << "': group not found." << std::endl;
136    }
137
138    void LuaState::doString(const std::string& code, shared_ptr<ResourceInfo> sourceFileInfo)
139    {
140        // Save the oold source file info
141        shared_ptr<ResourceInfo> oldSourceFileInfo = sourceFileInfo_;
142        // Only override if sourceFileInfo provides useful information
143        if (sourceFileInfo != NULL)
144            sourceFileInfo_ = sourceFileInfo;
145
146        //if (!bIsRunning_)
147        //{
148        //    bIsRunning_ = true;
149
150        int error = 0;
151#if LUA_VERSION_NUM != 501
152        LoadS ls;
153        ls.s = code.c_str();
154        ls.size = code.size();
155        error = lua_load(luaState_, &orxonox::LuaState::lua_Chunkreader, &ls, code.c_str());
156#else
157        error = luaL_loadstring(luaState_, code.c_str());
158#endif
159
160        // execute the chunk
161        if (error == 0)
162            error = lua_pcall(luaState_, 0, 0, 0);
163        if (error != 0)
164        {
165            std::string origin;
166            if (sourceFileInfo != NULL)
167                origin = " originating from " + sourceFileInfo_->filename;
168            COUT(2) << "Error in Lua-script" << origin << ": " << lua_tostring(luaState_, -1) << std::endl;
169        }
170
171        //    bIsRunning_ = false;
172        //}
173        //else
174        //{
175        //    COUT(2) << "Warning: LuaState do function called while running!" << std::endl;
176        //}
177
178        // Load the old info again
179        sourceFileInfo_ = oldSourceFileInfo;
180    }
181
182    void LuaState::luaPrint(const std::string& str)
183    {
184        output_ << str;
185    }
186
187    void LuaState::luaLog(unsigned int level, const std::string& message)
188    {
189        OutputHandler::getOutStream().setOutputLevel(level) << message << std::endl;
190    }
191
192#if LUA_VERSION_NUM != 501
193    const char * LuaState::lua_Chunkreader(lua_State *L, void *data, size_t *size)
194    {
195        LoadS* ls = static_cast<LoadS*>(data);
196        if (ls->size == 0)
197            return NULL;
198        *size = ls->size;
199        ls->size = 0;
200        return ls->s;
201    }
202#endif
203
204    /*static*/ bool LuaState::addToluaInterface(int (*function)(lua_State*), const std::string& name)
205    {
206        for (ToluaInterfaceMap::const_iterator it = toluaInterfaces_s.begin(); it != toluaInterfaces_s.end(); ++it)
207        {
208            if (it->first == name || it->second == function)
209            {
210                COUT(2) << "Warning: Trying to add a Tolua interface with the same name or function." << std::endl;
211                return true;
212            }
213        }
214        toluaInterfaces_s[name] = function;
215
216        // Open interface in all LuaStates
217        for (std::vector<LuaState*>::const_iterator it = instances_s.begin(); it != instances_s.end(); ++it)
218            (*function)((*it)->luaState_);
219
220        // Return dummy bool
221        return true;
222    }
223
224    /*static*/ bool LuaState::removeToluaInterface(const std::string& name)
225    {
226        ToluaInterfaceMap::iterator it = toluaInterfaces_s.find(name);
227        if (it == toluaInterfaces_s.end())
228        {
229            COUT(2) << "Warning: Cannot remove Tolua interface '" << name << "': Not found" << std::endl;
230            return true;
231        }
232
233        // Close interface in all LuaStates
234        for (std::vector<LuaState*>::const_iterator itState = instances_s.begin(); itState != instances_s.end(); ++itState)
235        {
236            lua_pushnil((*itState)->luaState_);
237            lua_setglobal((*itState)->luaState_, it->first.c_str());
238        }
239
240        // Remove entry
241        toluaInterfaces_s.erase(it);
242
243        // Return dummy bool
244        return true;
245    }
246
247    /*static*/ void LuaState::openToluaInterfaces(lua_State* state)
248    {
249        for (ToluaInterfaceMap::const_iterator it = toluaInterfaces_s.begin(); it != toluaInterfaces_s.end(); ++it)
250            (*it->second)(state);
251    }
252
253    /*static*/ void LuaState::closeToluaInterfaces(lua_State* state)
254    {
255        for (ToluaInterfaceMap::const_iterator it = toluaInterfaces_s.begin(); it != toluaInterfaces_s.end(); ++it)
256        {
257            lua_pushnil(state);
258            lua_setglobal(state, it->first.c_str());
259        }
260    }
261}
Note: See TracBrowser for help on using the repository browser.