Changeset 6746 for code/trunk/src/libraries/core/LuaState.cc
- Timestamp:
- Apr 16, 2010, 2:50:16 PM (15 years ago)
- Location:
- code/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
-
code/trunk/src/libraries/core/LuaState.cc
r6417 r6746 37 37 38 38 #include "util/Debug.h" 39 #include "util/Exception.h" 40 #include "util/ScopeGuard.h" 41 #include "IOConsole.h" 39 42 #include "Resource.h" 40 43 #include "ToluaBindCore.h" … … 54 57 // Create new lua state and configure it 55 58 luaState_ = lua_open(); 59 Loki::ScopeGuard luaStateGuard = Loki::MakeGuard(&lua_close, luaState_); 56 60 #if LUA_VERSION_NUM == 501 57 61 luaL_openlibs(luaState_); … … 78 82 79 83 // 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(); 81 88 } 82 89 … … 96 103 } 97 104 98 voidLuaState::includeFile(const std::string& filename)105 bool LuaState::includeFile(const std::string& filename) 99 106 { 100 107 shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename); 101 108 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) 108 118 { 109 119 // Parse string with provided include parser (otherwise don't preparse at all) … … 114 124 luaInput = code; 115 125 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) 120 146 { 121 147 shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename); 122 148 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) 129 158 { 130 159 // Save the old source file info … … 134 163 sourceFileInfo_ = sourceFileInfo; 135 164 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 137 187 #if LUA_VERSION_NUM != 501 138 188 LoadS ls; 139 189 ls.s = code.c_str(); 140 190 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()); 142 192 #else 143 error = luaL_loadstring(luaState_, code.c_str());193 int error = luaL_loadbuffer(luaState_, code.c_str(), code.size(), chunkname.c_str()); 144 194 #endif 145 195 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 147 206 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 149 235 if (error != 0) 150 236 { 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. 159 246 lua_setglobal(luaState_, "LuaStateReturnValue"); 160 247 161 248 // Load the old info again 162 249 sourceFileInfo_ = oldSourceFileInfo; 250 251 return (error == 0); 163 252 } 164 253 … … 180 269 else 181 270 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(); 182 291 } 183 292
Note: See TracChangeset
for help on using the changeset viewer.