mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
************************************************************
* Merged Source Code from Development Trunk: Revision 4063 * ************************************************************ - Source Code is merged from: https://81.169.133.124/source/ja2/branches/Wanne/JA2%201.13%20MP - This will be the Source for the Beta 2011 Test git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4064 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -0,0 +1,293 @@
|
||||
#include "lua/lua_state.h"
|
||||
#include <Debug.h>
|
||||
#include "sgp_logger.h"
|
||||
|
||||
#include <vfs/Core/vfs_string.h>
|
||||
|
||||
LuaState::LuaState(lua_State* state, bool own) : _L(state), _own(own), _registry(state)
|
||||
{
|
||||
}
|
||||
|
||||
LuaState::LuaState() : _L(NULL), _own(true), _registry(NULL)
|
||||
{
|
||||
//_L = lua_open();
|
||||
//_registry._L = _L;
|
||||
}
|
||||
|
||||
LuaState::~LuaState()
|
||||
{
|
||||
}
|
||||
|
||||
void LuaState::init(bool init_libs)
|
||||
{
|
||||
if(!_L)
|
||||
{
|
||||
_L = lua_open();
|
||||
if(init_libs)
|
||||
{
|
||||
luaL_openlibs(_L);
|
||||
}
|
||||
_registry._L = _L;
|
||||
}
|
||||
}
|
||||
|
||||
void LuaState::close()
|
||||
{
|
||||
if(_L && _own)
|
||||
{
|
||||
lua_close(_L);
|
||||
}
|
||||
}
|
||||
|
||||
#include <vfs/Core/vfs_file_raii.h>
|
||||
bool LuaState::EvalFile(const char* filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
vfs::COpenReadFile rfile(filename);
|
||||
vfs::UInt32 size = rfile.file().getSize();
|
||||
std::vector<vfs::Byte> buffer(size+1);
|
||||
rfile.file().read(&buffer[0], size);
|
||||
buffer[size] = 0;
|
||||
return this->EvalString((char*)&buffer[0], size, filename);
|
||||
}
|
||||
catch(std::exception &ex)
|
||||
{
|
||||
SGP_ERROR(ex.what());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LuaState::CallFunction(const char* function_name)
|
||||
{
|
||||
if(function_name)
|
||||
{
|
||||
// call function
|
||||
lua_getglobal(_L, function_name);
|
||||
if(lua_isfunction(_L, -1))
|
||||
{
|
||||
if( lua_pcall(_L, 0, 1, 0) != 0 )
|
||||
{
|
||||
std::string err = lua_tostring(_L, -1);
|
||||
std::wstringstream wss;
|
||||
wss << L"Execution of lua function '" << vfs::String::as_utf16(function_name) << L"' failed : ";
|
||||
wss << vfs::String::as_utf16(err);
|
||||
SGP_THROW(wss.str().c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool LuaState::EvalString(const wchar_t *lua_str, size_t length, const char* id_str)
|
||||
{
|
||||
std::string s = vfs::String::as_utf8(lua_str, length);
|
||||
|
||||
return this->EvalString(s.c_str(), s.length(), id_str);
|
||||
}
|
||||
|
||||
bool LuaState::EvalString(const char *lua_str, size_t length, const char* id_str)
|
||||
{
|
||||
int error;
|
||||
|
||||
if(length == 0)
|
||||
{
|
||||
length = strlen(lua_str);
|
||||
}
|
||||
error = luaL_loadbuffer(_L, lua_str, length, id_str) ||
|
||||
lua_pcall(_L, 0, 0, 0);
|
||||
|
||||
if (error)
|
||||
{
|
||||
const char *error = lua_tostring(_L, -1);
|
||||
int len = strlen( error);
|
||||
if (len >= 7 && !strcmp( error + len - 7, "'<eof>'"))
|
||||
{
|
||||
lua_pop(_L, 1); /* pop error message from the stack */
|
||||
return false;
|
||||
}
|
||||
std::string s = lua_tostring(_L, -1);
|
||||
SGP_THROW(s);
|
||||
//printf( "%s\n", lua_tostring(L, -1));
|
||||
//lua_pop(L, 1); /* pop error message from the stack */
|
||||
//return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LuaState::Registry::Registry(lua_State* L) : _L(L)
|
||||
{
|
||||
}
|
||||
|
||||
void LuaState::Registry::CreateCallbackTable()
|
||||
{
|
||||
lua_getfield(_L, LUA_REGISTRYINDEX, "__CallBackRegistry");
|
||||
if(lua_isnil(_L,-1))
|
||||
{
|
||||
lua_pop(_L,1); // pop 'nil' from stack
|
||||
lua_newtable(_L);
|
||||
lua_setfield(_L,LUA_REGISTRYINDEX,"__CallBackRegistry"); // 'setfield' removes value from stack
|
||||
return;
|
||||
}
|
||||
else if(lua_istable(_L,-1))
|
||||
{
|
||||
lua_pop(_L,1);
|
||||
return;
|
||||
}
|
||||
SGP_THROW(L"Could not create callback registy table");
|
||||
}
|
||||
void LuaState::Registry::GetCallbackTable()
|
||||
{
|
||||
lua_getfield(_L, LUA_REGISTRYINDEX, "__CallBackRegistry");
|
||||
if(!lua_istable(_L,-1))
|
||||
{
|
||||
SGP_THROW("CallBack registry table does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
void LuaState::Registry::SetCallback(const char* callback_name)
|
||||
{
|
||||
// function is at (L, -2)
|
||||
// user data value is at (L, -1)
|
||||
this->GetCallbackTable();
|
||||
lua_pushvalue(_L, -2);
|
||||
lua_rawget(_L, -2);
|
||||
if(!lua_istable(_L, -1))
|
||||
{
|
||||
lua_pop(_L, 1); // remove 'nil'
|
||||
// set new table
|
||||
lua_pushvalue(_L, -2);
|
||||
lua_newtable(_L);
|
||||
lua_rawset(_L, -3);
|
||||
// get table
|
||||
lua_pushvalue(_L, -2);
|
||||
lua_rawget(_L, -2);
|
||||
}
|
||||
if(!lua_istable(_L,-1))
|
||||
{
|
||||
SGP_THROW("Could not create callback");
|
||||
}
|
||||
lua_pushvalue(_L, -4);
|
||||
lua_setfield(_L, -2, callback_name);
|
||||
lua_pop(_L, 4);
|
||||
}
|
||||
void LuaState::Registry::GetCallback(const char* callback_name)
|
||||
{
|
||||
// user data is at (L, -1)
|
||||
this->GetCallbackTable();
|
||||
lua_pushvalue(_L, -2);
|
||||
lua_rawget(_L, -2);
|
||||
if(lua_istable(_L, -1))
|
||||
{
|
||||
lua_getfield(_L, -1, callback_name);
|
||||
if(lua_isfunction(_L, -1))
|
||||
{
|
||||
lua_insert(_L, -4);
|
||||
lua_pop(_L, 3);
|
||||
if(!lua_isfunction(_L,-1))
|
||||
{
|
||||
SGP_THROW("messed up stack");
|
||||
}
|
||||
return;
|
||||
}
|
||||
// no callback defined
|
||||
lua_pop(_L, 4);
|
||||
}
|
||||
// no table created
|
||||
lua_pop(_L, 3); // also pops user data
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void LuaState::Registry::CreateUserDataTable()
|
||||
{
|
||||
lua_getfield(_L, LUA_REGISTRYINDEX, "__UserData");
|
||||
if(lua_isnil(_L,-1))
|
||||
{
|
||||
lua_pop(_L,1); // pop 'nil' from stack
|
||||
lua_newtable(_L);
|
||||
lua_setfield(_L,LUA_REGISTRYINDEX,"__UserData"); // 'setfield' removes value from stack
|
||||
return;
|
||||
}
|
||||
else if(lua_istable(_L,-1))
|
||||
{
|
||||
lua_pop(_L,1);
|
||||
return;
|
||||
}
|
||||
SGP_THROW(L"Could not create User Data registy table");
|
||||
}
|
||||
|
||||
void LuaState::Registry::GetUserDataTable()
|
||||
{
|
||||
lua_getfield(_L, LUA_REGISTRYINDEX, "__UserData");
|
||||
if(!lua_istable(_L,-1))
|
||||
{
|
||||
SGP_THROW("User Data registry table does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************/
|
||||
|
||||
#include <map>
|
||||
|
||||
class LuaStateManager
|
||||
{
|
||||
public:
|
||||
~LuaStateManager() {
|
||||
_states.clear();
|
||||
};
|
||||
|
||||
static LuaStateManager& instance() {
|
||||
static LuaStateManager lsm;
|
||||
return lsm;
|
||||
};
|
||||
|
||||
LuaState& GetState(lua::State eState) {
|
||||
return _states[eState];
|
||||
}
|
||||
|
||||
private:
|
||||
LuaStateManager() {};
|
||||
static std::map<lua::State, LuaState> _states;
|
||||
};
|
||||
|
||||
std::map<lua::State, LuaState> LuaStateManager::_states;
|
||||
|
||||
|
||||
void LuaState::INIT(lua::State state_id, bool init_libs)
|
||||
{
|
||||
LuaStateManager::instance().GetState(state_id).init(init_libs);
|
||||
}
|
||||
|
||||
LuaState LuaState::INIT(bool init_libs)
|
||||
{
|
||||
LuaState L;
|
||||
L.init(init_libs);
|
||||
return L;
|
||||
}
|
||||
|
||||
void LuaState::CLOSE(lua::State state_id)
|
||||
{
|
||||
LuaStateManager::instance().GetState(state_id).close();
|
||||
}
|
||||
|
||||
void LuaState::CLOSE(LuaState state)
|
||||
{
|
||||
state.close();
|
||||
}
|
||||
|
||||
LuaState LuaState::GET(lua::State state_id)
|
||||
{
|
||||
return LuaStateManager::instance().GetState(state_id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user