// GameCode4 is the sample application that encapsulates much of the source code // discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David // "Rez" Graham, published by Charles River Media. // ISBN-10: 1133776574 | ISBN-13: 978-1133776574 // // If this source code has found it's way to you, and you think it has helped you // in any way, do the authors a favor and buy a new copy of the book - there are // detailed explanations in it that compliment this code well. Buy a copy at Amazon.com // by clicking here: // http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller= // // There's a companion web site at http://www.mcshaffry.com/GameCode/ // // The source code is managed and maintained through Google Code: // http://code.google.com/p/gamecode4/ // // (c) Copyright 2012 Michael L. McShaffry and David Graham // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser GPL v3 // as published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // http://www.gnu.org/licenses/lgpl-3.0.txt for more details. // // You should have received a copy of the GNU Lesser GPL v3 // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //======================================================================== #include "LuaStateManager.h" #include "../Unix/GameCodeStd.h" #include "../Debugging/Logger.h" #include "../Utilities/String.h" LuaStateManager* LuaStateManager::s_pSingleton = NULL; bool LuaStateManager::Create(void) { if (s_pSingleton) { GCC_ERROR("Overwriting LuaStateManager singleton"); SAFE_DELETE(s_pSingleton); } s_pSingleton = GCC_NEW LuaStateManager; if (s_pSingleton) return s_pSingleton->VInit(); return false; } void LuaStateManager::Destroy(void) { GCC_ASSERT(s_pSingleton); SAFE_DELETE(s_pSingleton); } bool LuaStateManager::VInit(void) { m_luaState.open_libraries(sol::lib::base); // // register functions m_luaState["ExecuteFile"] = [this](const std::string& path) { return this->VExecuteFile(path.c_str()); }; m_luaState["ExecuteString"] = [this](const std::string& chunk) { return this->VExecuteString(chunk.c_str()); }; return true; } void LuaStateManager::VExecuteFile(const char* path) { try { auto result = m_luaState.script_file(path); } catch(sol::error const& err) { SetError(err); } } void LuaStateManager::VExecuteString(const char* chunk) { try { // Most strings are passed straight through to the Lua interpreter if (strlen(chunk) <= 1 || chunk[0] != '=') { m_luaState.script(chunk); } else // If the string starts with '=', wrap the statement in the print() function. { std::string buffer("print("); buffer += (chunk + 1); buffer += ")"; m_luaState.script(buffer); } } catch(sol::error const& err) { SetError(err); } } void LuaStateManager::SetError(sol::error const& err) { m_lastError = err.what(); GCC_ERROR(m_lastError); } sol::global_table LuaStateManager::GetGlobalVars(void) { return m_luaState.globals(); } sol::state_view LuaStateManager::GetLuaState(void) { return m_luaState; } sol::table LuaStateManager::CreatePath(const char* pathString, bool toIgnoreLastElement) { StringVec splitPath; Split(pathString, splitPath, '.'); if (toIgnoreLastElement) splitPath.pop_back(); sol::table context = GetGlobalVars(); for (auto it=splitPath.begin(); it != splitPath.end(); ++it) { // make sure we still have a valid context if (context == sol::lua_nil) { GCC_ERROR("Something broke in CreatePath(); bailing out (element == " + (*it) + ")"); return context; // this will be nil } // grab whatever exists for this element const std::string& element = (*it); sol::object curr = context[element]; if (!curr.is()) { // if the element is not a table and not nil, we clobber it if (curr != sol::lua_nil) { GCC_WARNING("Overwriting element '" + element + "' in table"); context[element] = sol::lua_nil; } context[element] = sol::state_view(context.lua_state()).create_table(); } context = context[element]; } return context; }