Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Apr 16, 2010, 2:50:16 PM (14 years ago)
Author:
rgrieder
Message:

Merged gamestates2 branch back to trunk.
This brings in some heavy changes in the GUI framework.
It should also fix problems with triggered asserts in the InputManager.

Note: PickupInventory does not seem to work —> Segfault when showing because before, the owner in GUIOverlay::setGUIName is already NULL.
I haven't tested it before, so I can't tell whether it's my changes.

Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/core/LuaState.cc

    r6417 r6746  
    3737
    3838#include "util/Debug.h"
     39#include "util/Exception.h"
     40#include "util/ScopeGuard.h"
     41#include "IOConsole.h"
    3942#include "Resource.h"
    4043#include "ToluaBindCore.h"
     
    5457        // Create new lua state and configure it
    5558        luaState_ = lua_open();
     59        Loki::ScopeGuard luaStateGuard = Loki::MakeGuard(&lua_close, luaState_);
    5660#if LUA_VERSION_NUM == 501
    5761        luaL_openlibs(luaState_);
     
    7882
    7983        // Parse init script
    80         this->doFile("LuaStateInit.lua");
     84        if (!this->doFile("LuaStateInit.lua"))
     85            ThrowException(InitialisationFailed, "Running LuaStateInit.lua failed");
     86
     87        luaStateGuard.Dismiss();
    8188    }
    8289
     
    96103    }
    97104
    98     void LuaState::includeFile(const std::string& filename)
     105    bool LuaState::includeFile(const std::string& filename)
    99106    {
    100107        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename);
    101108        if (sourceInfo != NULL)
    102             this->includeString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
    103         else
    104             COUT(2) << "LuaState: Cannot include file '" << filename << "'." << std::endl;
    105     }
    106 
    107     void LuaState::includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
     109            return this->includeString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
     110        else
     111        {
     112            COUT(2) << "LuaState: Cannot include file '" << filename << "' (not found)." << std::endl;
     113            return false;
     114        }
     115    }
     116
     117    bool LuaState::includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
    108118    {
    109119        // Parse string with provided include parser (otherwise don't preparse at all)
     
    114124            luaInput = code;
    115125
    116         this->doString(luaInput, sourceFileInfo);
    117     }
    118 
    119     void LuaState::doFile(const std::string& filename)
     126        if (sourceFileInfo != NULL)
     127        {
     128            // Also fill a map with the actual source code. This is just for the include* commands
     129            // where the content of sourceFileInfo->filename doesn't match 'code'
     130            this->sourceCodeMap_[sourceFileInfo->filename] = code;
     131        }
     132
     133        bool returnValue = this->doString(luaInput, sourceFileInfo);
     134
     135        if (sourceFileInfo != NULL)
     136        {
     137            // Delete source code entry
     138            if (sourceFileInfo != NULL)
     139                this->sourceCodeMap_.erase(sourceFileInfo->filename);
     140        }
     141
     142        return returnValue;
     143    }
     144
     145    bool LuaState::doFile(const std::string& filename)
    120146    {
    121147        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename);
    122148        if (sourceInfo != NULL)
    123             this->doString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
    124         else
    125             COUT(2) << "LuaState: Cannot do file '" << filename << "'." << std::endl;
    126     }
    127 
    128     void LuaState::doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
     149            return this->doString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
     150        else
     151        {
     152            COUT(2) << "LuaState: Cannot do file '" << filename << "' (not found)." << std::endl;
     153            return false;
     154        }
     155    }
     156
     157    bool LuaState::doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
    129158    {
    130159        // Save the old source file info
     
    134163            sourceFileInfo_ = sourceFileInfo;
    135164
    136         int error = 0;
     165        std::string chunkname;
     166        if (sourceFileInfo != NULL)
     167        {
     168            // Provide lua_load with the filename for debug purposes
     169            // The '@' is a Lua convention to identify the chunk name as filename
     170            chunkname = '@' + sourceFileInfo->filename;
     171        }
     172        else
     173        {
     174            // Use the code string to identify the chunk
     175            chunkname = code;
     176        }
     177
     178        // Push custom error handler that uses the debugger
     179        lua_getglobal(this->luaState_, "errorHandler");
     180        int errorHandler = lua_gettop(luaState_);
     181        if (lua_isnil(this->luaState_, -1))
     182        {
     183            lua_pop(this->luaState_, 1);
     184            errorHandler = 0;
     185        }
     186
    137187#if LUA_VERSION_NUM != 501
    138188        LoadS ls;
    139189        ls.s = code.c_str();
    140190        ls.size = code.size();
    141         error = lua_load(luaState_, &orxonox::LuaState::lua_Chunkreader, &ls, code.c_str());
     191        int error = lua_load(luaState_, &orxonox::LuaState::lua_Chunkreader, &ls, chunkname.c_str());
    142192#else
    143         error = luaL_loadstring(luaState_, code.c_str());
     193        int error = luaL_loadbuffer(luaState_, code.c_str(), code.size(), chunkname.c_str());
    144194#endif
    145195
    146         // execute the chunk
     196        switch (error)
     197        {
     198        case LUA_ERRSYNTAX: // Syntax error
     199            COUT(1) << "Lua syntax error: " << lua_tostring(luaState_, -1) << std::endl;
     200            break;
     201        case LUA_ERRMEM:    // Memory allocation error
     202            COUT(1) << "Lua memory allocation error: Consult your dentist immediately!" << std::endl;
     203            break;
     204        }
     205
    147206        if (error == 0)
    148             error = lua_pcall(luaState_, 0, 1, 0);
     207        {
     208            // Execute the chunk in protected mode with an error handler function (stack index)
     209            error = lua_pcall(luaState_, 0, 1, errorHandler);
     210
     211            switch (error)
     212            {
     213            case LUA_ERRRUN: // Runtime error
     214                if (errorHandler)
     215                {
     216                    // Do nothing (we already display the error in the
     217                    // 'errorHandler' Lua function in LuaStateInit.lua)
     218                }
     219                else
     220                {
     221                    std::string errorString = lua_tostring(this->luaState_, -1);
     222                    if (errorString.find("Error propagation") == std::string::npos)
     223                        COUT(1) << "Lua runtime error: " << errorString << std::endl;
     224                }
     225                break;
     226            case LUA_ERRERR: // Error in the error handler
     227                COUT(1) << "Lua error in error handler. No message available." << std::endl;
     228                break;
     229            case LUA_ERRMEM: // Memory allocation error
     230                COUT(1) << "Lua memory allocation error: Consult your dentist immediately!" << std::endl;
     231                break;
     232            }
     233        }
     234
    149235        if (error != 0)
    150236        {
    151             std::string origin;
    152             if (sourceFileInfo != NULL)
    153                 origin = " originating from " + sourceFileInfo_->filename;
    154             COUT(1) << "Error in Lua-script" << origin << ": " << lua_tostring(luaState_, -1) << std::endl;
    155             // return value is nil
    156             lua_pushnil(luaState_);
    157         }
    158         // push return value because it will get lost since the return value of this function is void
     237            lua_pop(luaState_, 1);  // Remove error message
     238            lua_pushnil(luaState_); // Push a nil return value
     239        }
     240
     241        if (errorHandler != 0)
     242            lua_remove(luaState_, errorHandler); // Remove error handler from stack
     243
     244        // Set return value to a global variable because we cannot return a table in this function
     245        // here. It would work for numbers, pointers and strings, but certainly not for Lua tables.
    159246        lua_setglobal(luaState_, "LuaStateReturnValue");
    160247
    161248        // Load the old info again
    162249        sourceFileInfo_ = oldSourceFileInfo;
     250
     251        return (error == 0);
    163252    }
    164253
     
    180269        else
    181270            return true;
     271    }
     272
     273    //! Returns the content of a file
     274    std::string LuaState::getSourceCode(const std::string& filename)
     275    {
     276        // Try the internal map first to get the actual Lua code
     277        // and not just some pseudo Lua-XML code when using include* commands
     278        std::map<std::string, std::string>::const_iterator it = this->sourceCodeMap_.find(filename);
     279        if (it != this->sourceCodeMap_.end())
     280            return it->second;
     281        shared_ptr<ResourceInfo> info = Resource::getInfo(filename);
     282        if (info == NULL)
     283            return "";
     284        else
     285            return Resource::open(info)->getAsString();
     286    }
     287
     288    bool LuaState::usingIOConsole() const
     289    {
     290        return IOConsole::exists();
    182291    }
    183292
Note: See TracChangeset for help on using the changeset viewer.