279 lines
4.6 KiB
C++
279 lines
4.6 KiB
C++
|
|
// LuaScript.cpp
|
|
|
|
// Implements the cLuaScript class that loads a Lua script file to produce a web template out of it
|
|
|
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
|
|
|
#include "LuaScript.h"
|
|
|
|
extern "C"
|
|
{
|
|
#include "lualib.h"
|
|
}
|
|
|
|
#include "tolua++.h"
|
|
#include "Bindings.h"
|
|
#include "ManualBindings.h"
|
|
|
|
// fwd: SQLite/lsqlite3.c
|
|
extern "C"
|
|
{
|
|
LUALIB_API int luaopen_lsqlite3(lua_State * L);
|
|
}
|
|
|
|
// fwd: LuaExpat/lxplib.c:
|
|
extern "C"
|
|
{
|
|
int luaopen_lxp(lua_State * L);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cLuaScript::cLuaScript()
|
|
: m_LuaState(NULL)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cLuaScript::~cLuaScript()
|
|
{
|
|
if( m_LuaState )
|
|
{
|
|
lua_close( m_LuaState );
|
|
m_LuaState = 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cLuaScript::Initialize()
|
|
{
|
|
// Check to see if this script has not been initialized before
|
|
ASSERT(!m_LuaState);
|
|
|
|
// Create a Lua state and bind all libraries to it
|
|
m_LuaState = lua_open();
|
|
luaL_openlibs(m_LuaState);
|
|
tolua_AllToLua_open(m_LuaState);
|
|
ManualBindings::Bind(m_LuaState);
|
|
luaopen_lsqlite3(m_LuaState);
|
|
luaopen_lxp(m_LuaState);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool cLuaScript::LoadFile( const char* a_FilePath )
|
|
{
|
|
// Make sure the plugin is initialized
|
|
ASSERT(m_LuaState);
|
|
|
|
// Load the file into the Lua state
|
|
int s = luaL_loadfile(m_LuaState, a_FilePath );
|
|
if (ReportErrors(s))
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool cLuaScript::Execute()
|
|
{
|
|
// Make sure we got a Lua state
|
|
ASSERT(m_LuaState);
|
|
|
|
// Execute the script as it is right now
|
|
int s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0);
|
|
if( ReportErrors( s ) )
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool cLuaScript::ReportErrors( int a_Status )
|
|
{
|
|
if (a_Status == 0)
|
|
{
|
|
// No error to report
|
|
return false;
|
|
}
|
|
|
|
// Status was set to error so get the error from the Lua state and log it
|
|
LOGERROR("LUA: %s", lua_tostring(m_LuaState, -1));
|
|
lua_pop(m_LuaState, 1);
|
|
|
|
// Return true to indicate that an error was returned
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool cLuaScript::LuaPushFunction( const char * a_FunctionName, bool a_bLogError /*= true*/ )
|
|
{
|
|
ASSERT(m_LuaState);
|
|
|
|
// Find and push the function on the Lua stack
|
|
lua_getglobal(m_LuaState, a_FunctionName);
|
|
|
|
// Make sure we found a function
|
|
if (!lua_isfunction(m_LuaState, -1))
|
|
{
|
|
if (a_bLogError)
|
|
{
|
|
LOGWARN("LUA: Could not find function %s()", a_FunctionName);
|
|
}
|
|
|
|
// Pop the pushed 'object' back
|
|
lua_pop(m_LuaState, 1);
|
|
return false;
|
|
}
|
|
|
|
// Successfully pushed a function to the Lua stack
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool cLuaScript::LuaCallFunction( int a_NumArgs, int a_NumResults, const char * a_FunctionName )
|
|
{
|
|
ASSERT(m_LuaState);
|
|
|
|
// Make sure there's a lua function on the stack
|
|
ASSERT(lua_isfunction(m_LuaState, -a_NumArgs - 1));
|
|
|
|
// Call the desired function
|
|
int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0);
|
|
|
|
// Check for errors
|
|
if (ReportErrors(s))
|
|
{
|
|
LOGWARN("LUA: Error calling function %s()", a_FunctionName);
|
|
return false;
|
|
}
|
|
|
|
// Successfully executed function
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool cLuaScript::CallFunction( const char* a_Function, AString& ReturnedString )
|
|
{
|
|
// Make sure we have the required things to call a function
|
|
ASSERT(m_LuaState);
|
|
ASSERT(a_Function);
|
|
|
|
// Push the desired function on the stack
|
|
if (!LuaPushFunction(a_Function))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!LuaCallFunction(0, 1, a_Function))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (lua_isstring(m_LuaState, -1))
|
|
{
|
|
ReturnedString = tolua_tostring(m_LuaState, -1, "");
|
|
}
|
|
lua_pop(m_LuaState, 1);
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool cLuaScript::CallFunction( const char* a_Function, const sLuaUsertype& a_UserType, AString& ReturnedString )
|
|
{
|
|
// Make sure we have the required things to call a function
|
|
ASSERT(m_LuaState);
|
|
ASSERT(a_Function);
|
|
|
|
// Push the desired function on the stack
|
|
if (!LuaPushFunction(a_Function))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
tolua_pushusertype(m_LuaState, a_UserType.Object, a_UserType.ClassName);
|
|
|
|
if (!LuaCallFunction(1, 1, a_Function))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (lua_isstring(m_LuaState, -1))
|
|
{
|
|
ReturnedString = tolua_tostring(m_LuaState, -1, "");
|
|
}
|
|
lua_pop(m_LuaState, 1);
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool cLuaScript::CallFunction( const char* a_Function, const sLuaUsertype& a_UserType1, const sLuaUsertype& a_UserType2, AString& ReturnedString )
|
|
{
|
|
// Make sure we have the required things to call a function
|
|
ASSERT(m_LuaState);
|
|
ASSERT(a_Function);
|
|
|
|
// Push the desired function on the stack
|
|
if (!LuaPushFunction(a_Function))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
tolua_pushusertype(m_LuaState, a_UserType1.Object, a_UserType1.ClassName);
|
|
tolua_pushusertype(m_LuaState, a_UserType2.Object, a_UserType2.ClassName);
|
|
|
|
if (!LuaCallFunction(2, 1, a_Function))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (lua_isstring(m_LuaState, -1))
|
|
{
|
|
ReturnedString = tolua_tostring(m_LuaState, -1, "");
|
|
}
|
|
lua_pop(m_LuaState, 1);
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|