- °³¿ä
- ¼Ò½º
- LuaDispatcher.h
- LuaDispatcher.cpp
- LuaAPI.h
- LuaAPI.cpp
- »ç¿ë¹ý
- TODO
1 °³¿ä
·ç¾Æ ÂÊ¿¡¼ C/C++ ÂÊÀÇ ÇÔ¼ö¸¦ È£ÃâÇÏ´Â °ÍÀº ºñ±³Àû °£´ÜÇϳª(±×·¸Áöµµ ¾Ê³ª...), ¹Ý´ë·Î C/C++ ÂÊ¿¡¼ ·ç¾Æ ÂÊÀÇ ÇÔ¼ö¸¦ È£ÃâÇÏ´Â °ÍÀº »ó´çÈ÷ ±ÍÂúÀº ÆíÀÌ´Ù. ¿¹¸¦ µé¾î, 2°³ÀÇ ¼ýÀÚÀμö¸¦ ¹Þ¾Æ ±× ÇÕÀ» ¹ÝȯÇÏ´Â ÇÔ¼ö°¡ ·ç¾Æ ÂÊ¿¡ ÀÖ´Ù°í ÇÏÀÚ.
function add(lhs, rhs)
assert(type(lhs) == "number")
assert(type(rhs) == "number")
return lhs + rhs
end ÀÌ ÇÔ¼ö¸¦ C/C++ ÂÊ¿¡¼ È£ÃâÇϰíÀÚ ÇÑ´Ù¸é ´ë·« ´ÙÀ½°ú °°Àº Äڵ带 ¸¸µé¾î¾ß ÇÑ´Ù.
int call_add(lua_State* L, int lhs, int rhs)
{
// ÇÔ¼ö¸¦ °¡Á®¿Í ½ºÅÿ¡´Ù Ǫ½ÃÇÑ´Ù.
lua_getglobal(L, "add");
luaL_checktype(L, -1, LUA_TFUNCTION);
// µð¹ö±×¸¦ À§ÇØ Æ®·¹À̽º ÇÔ¼ö¸¦ °¡Á®¿Í Áý¾î³Ö´Â´Ù.
int errorfunc = lua_gettop(L);
lua_getglobal(L, "_TRACEBACK");
luaL_checktype(L, -1, LUA_TFUNCTION);
lua_insert(L, errorfunc);
// ÀÎÀÚ¸¦ Ǫ½¬ÇÑ´Ù.
lua_pushnumber(L, lhs);
lua_pushnumber(L, rhs);
// 2°³ÀÇ ÀÎÀÚ¸¦ °¡Áö°í 1°³ÀÇ ¹Ýȯ°ªÀ» °¡Áö´Â ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.
if (lua_pcall(L, 2, 1, errorfunc) != 0)
{
// ¿¡·¯°¡ ¹ß»ýÇß´Ù. 󸮸¦ ÇØÁØ´Ù.
cerr << "ERROR: " << lua_tostring(L, -1) << endl;
lua_pop(L, 1);
return 0;
}
// ½ºÅÿ¡¼ ¹Ýȯ°ªÀ» ²¨³½´Ù.
luaL_checktype(L, -1, LUA_TNUMBER);
int result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
// ½ºÅÿ¡¼ Æ®·¹À̽º ÇÔ¼ö¸¦ ²¨³½´Ù.
lua_pop(L, 1);
return result;
} ´ÜÁö ¼ýÀÚ 2°³¸¦ ´õÇØ¼ ¹ÝȯÇÏ´Â ÇÔ¼öÀÏ »ÓÀε¥, ÀÌ Á¤µµ Äڵ尡 ÇÊ¿äÇÏ´Ù. ¿¡·¯ 󸮸¦ »ý·«ÇÏ¸é ¾à°£ °£´ÜÇØÁö±â´Â ÇϰÚÁö¸¸, Á¦´ë·ÎµÈ µð¹ö°Åµµ ¾ø´Â »óȲ¿¡¼ ¿¡·¯ 󸮴 Çʼö´Ù.
±×·¡¼ ¾î¶»°Ô Çϸé C++ »ó¿¡¼ ·ç¾Æ ÂÊ¿¡ ÀÖ´Â ÇÔ¼ö¸¦ Á» ´õ ½±°Ô È£ÃâÇÒ ¼ö ÀÖÀ»±îÇÏ°í ¹æ¹ýÀ» ã¾ÆºÃ´Ù. °¡Àå °¡º¿î ¸ðµâÀÌ
LuaPlus ÂÊ¿¡ Call Dispatcher¶ó´Â ¸ðµâÀ̾ú´Âµ¥, ÅÛÇø´ ¶±Ä¥ÀÌ µÇ¾îÀÖ´Â Á¡ÀÌ ¸¶À½¿¡ µéÁö ¾Ê¾Æ °á±¹ µû·Î ¸¸µé°Ô µÇ¾ú´Ù.
2 ¼Ò½º
ÀÌ »çÀÌÆ®¿¡ ÀÖ´Â ´ëºÎºÐÀÇ ¼Ò½º°¡ ±×·¸µíÀÌ ¹Ù·Î ÄÄÆÄÀϵÇÁö´Â ¾ÊÀ» °ÍÀÌ´Ù. Çì´õ ÆÄÀÏÀ» Àû´çÈ÷ ¼öÁ¤Çϰí, Assert¸¦ ¼ÕºÁ¾ßÇÑ´Ù.
2.1 LuaDispatcher.h
//////////////////////////////////////////////////////////////////////////////
/// \file LuaDispatcher.h
/// \author excel96
/// \date 2005.1.19
//////////////////////////////////////////////////////////////////////////////
#pragma once
#include "LuaAPI.h"
#include "Noncopyable.h"
//////////////////////////////////////////////////////////////////////////////
/// \class LuaDispatcherBase
/// \brief C/C++ ÂÊ¿¡¼ Lua ÂÊ ÇÔ¼ö È£ÃâÀ» Á» ´õ ½±°Ô Çϱâ À§ÇÑ Å¬·¡½º.
///
/// LuaDispatcher Ŭ·¡½ºÀÇ º£À̽º Ŭ·¡½º°¡ µÇ´Â Ŭ·¡½ºÀÌ´Ù. ÀÌ´ë·Î »ç¿ëÇØµµ
/// º° ¹®Á¦°¡ ¾ø±â´Â Çϳª, Á» ´õ ÆíÇÏ°Ô Çϱâ À§Çؼ´Â LuaDispatcher Ŭ·¡½º¸¦
/// ÀÌ¿ëÇÏ´Â °ÍÀÌ ³´´Ù.
//////////////////////////////////////////////////////////////////////////////
class LuaDispatcherBase
{
public:
/// ¿¡·¯ ÅëÁö ÇÔ¼ö
typedef void (*PFN_ERROR_HANDLER)(const string& errormsg);
protected:
lua_State* m_pState; ///< ·ç¾Æ »óÅ °´Ã¼
int m_MaxArgs; ///< ÀμöÀÇ °¹¼ö
int m_MaxReturns; ///< ¸®ÅϰªÀÇ °¹¼ö
int m_CurArgs; ///< Ǫ½¬µÈ ÀμöÀÇ °¹¼ö
int m_CurReturns; ///< ÆËµÈ ¸®ÅϰªÀÇ °¹¼ö
int m_ErrorFunc; ///< ¿¡·¯ ó¸® ÇÔ¼öÀÇ ½ºÅà À妽º
PFN_ERROR_HANDLER m_pfnErrorHandler; ///< ¿¡·¯ Çڵ鷯
public:
/// \brief »ý¼ºÀÚ
/// \param L ·ç¾Æ »óÅ °´Ã¼
/// \param funcname ÇÔ¼ö À̸§
/// \param nargs ÀμöÀÇ °¹¼ö
/// \param nreturns ¸®ÅϰªÀÇ °¹¼ö
LuaDispatcherBase(lua_State* L, const char* funcname, int nargs, int nreturns);
/// \brief ¼Ò¸êÀÚ
virtual ~LuaDispatcherBase();
public:
/// \name Àμö Ǫ½¬
/// \{
void arg(const bool value);
void arg(const int value);
void arg(const string& value);
void arg(const void* value);
void arg(const LUA_VECTOR& value);
void arg(const LUA_MAP& value);
/// \}
/// \name ¸®Åϰª ÆË
/// \{
void ret(bool& value);
void ret(int& value);
void ret(string& value);
void ret(void** value);
void ret(LUA_VECTOR& value);
void ret(LUA_MAP& value);
/// \}
/// \brief ÇÔ¼ö¸¦ ½ÇÇàÇÑ´Ù.
void execute();
/// \brief ¿¡·¯ Çڵ鷯¸¦ ¼³Á¤ÇÑ´Ù.
/// \param pfnErrorHandler ¿¡·¯ Çڵ鷯
void setErrorHandler(PFN_ERROR_HANDLER pfnErrorHandler) {
m_pfnErrorHandler = pfnErrorHandler;
}
};
//////////////////////////////////////////////////////////////////////////////
/// \class LuaDispatcher
/// \brief C/C++ ÂÊ¿¡¼ Lua ÂÊ ÇÔ¼ö È£ÃâÀ» Á» ´õ ½±°Ô Çϱâ À§ÇÑ Å¬·¡½º.
//////////////////////////////////////////////////////////////////////////////
class LuaDispatcher : public LuaDispatcherBase
{
public:
LuaDispatcher(lua_State* L, const char* funcname)
: LuaDispatcherBase(L, funcname, 0, 0)
{
execute();
}
LuaDispatcher(lua_State* L, const char* funcname, int nreturns)
: LuaDispatcherBase(L, funcname, 0, nreturns)
{
execute();
}
template <typename A1>
LuaDispatcher(lua_State* L, const char* funcname, int nreturns,
const A1& a1)
: LuaDispatcherBase(L, funcname, 1, nreturns)
{
arg(a1);
execute();
}
template <typename A1, typename A2>
LuaDispatcher(lua_State* L, const char* funcname, int nreturns,
const A1& a1, const A2& a2)
: LuaDispatcherBase(L, funcname, 2, nreturns)
{
arg(a1);
arg(a2);
execute();
}
template <typename A1, typename A2, typename A3>
LuaDispatcher(lua_State* L, const char* funcname, int nreturns,
const A1& a1, const A2& a2, const A3& a3)
: LuaDispatcherBase(L, funcname, 3, nreturns)
{
arg(a1);
arg(a2);
arg(a3);
execute();
}
template <typename A1, typename A2, typename A3, typename A4>
LuaDispatcher(lua_State* L, const char* funcname, int nreturns,
const A1& a1, const A2& a2, const A3& a3, const A4& a4)
: LuaDispatcherBase(L, funcname, 4, nreturns)
{
arg(a1);
arg(a2);
arg(a3);
arg(a4);
execute();
}
template <typename A1, typename A2, typename A3, typename A4, typename A5>
LuaDispatcher(lua_State* L, const char* funcname, int nreturns,
const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
: LuaDispatcherBase(L, funcname, 5, nreturns)
{
arg(a1);
arg(a2);
arg(a3);
arg(a4);
arg(a5);
execute();
}
/// \brief ¼Ò¸êÀÚ
virtual ~LuaDispatcher() {}
};
2.2 LuaDispatcher.cpp
//////////////////////////////////////////////////////////////////////////////
/// \file LuaDispatcher.cpp
/// \author excel96
/// \date 2005.1.19
//////////////////////////////////////////////////////////////////////////////
#include "GameLibPCH.h"
#include "LuaDispatcher.h"
//////////////////////////////////////////////////////////////////////////////
/// \brief ±âº» ¿¡·¯ Çڵ鷯
/// \param errormsg ¿¡·¯ ¸Þ½ÃÁö
//////////////////////////////////////////////////////////////////////////////
static void DEFAULT_ERROR_HANDLER(const string& errormsg)
{
filelog(NULL, "script execution error:\n%s", errormsg.c_str());
Assert(false && "script execution error");
}
//////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
/// \param L ·ç¾Æ »óÅ °´Ã¼
/// \param funcname ÇÔ¼ö À̸§
/// \param nargs ÀμöÀÇ °¹¼ö
/// \param nreturns ¸®ÅϰªÀÇ °¹¼ö
//////////////////////////////////////////////////////////////////////////////
LuaDispatcherBase::LuaDispatcherBase(lua_State* L, const char* funcname, int nargs, int nreturns)
: m_pState(L), m_MaxArgs(nargs), m_MaxReturns(nreturns),
m_CurArgs(0), m_CurReturns(0), m_pfnErrorHandler(DEFAULT_ERROR_HANDLER)
{
AssertPtr(m_pState);
AssertPtr(funcname);
Assert(m_MaxArgs >= 0);
Assert(m_MaxReturns >= 0);
// ÇÔ¼ö¸¦ °¡Á®¿Í ½ºÅÿ¡´Ù Ǫ½ÃÇÑ´Ù.
lua_getglobal(m_pState, funcname);
luaL_checktype(m_pState, -1, LUA_TFUNCTION);
// µð¹ö±×¸¦ À§ÇØ Æ®·¹À̽º ÇÔ¼ö¸¦ °¡Á®¿Í Áý¾î³Ö´Â´Ù.
m_ErrorFunc = lua_gettop(m_pState);
lua_getglobal(m_pState, "_TRACEBACK");
luaL_checktype(m_pState, -1, LUA_TFUNCTION);
lua_insert(m_pState, m_ErrorFunc);
}
//////////////////////////////////////////////////////////////////////////////
/// \brief ¼Ò¸êÀÚ
//////////////////////////////////////////////////////////////////////////////
LuaDispatcherBase::~LuaDispatcherBase()
{
if (m_CurReturns == 0)
{
luaL_checktype(m_pState, -1, LUA_TFUNCTION);
lua_pop(m_pState, 1); // Æ®·¹À̽º ÇÔ¼ö¸¦ ÆË ÇÑ´Ù.
}
else if (m_pfnErrorHandler)
{
m_pfnErrorHandler("not all return values popped");
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief Àμö¸¦ Ǫ½¬ÇÑ´Ù.
/// \param value Àμö°ª
//////////////////////////////////////////////////////////////////////////////
void LuaDispatcherBase::arg(const bool value)
{
if (m_CurArgs < m_MaxArgs)
{
LuaAPI::push(m_pState, value);
++m_CurArgs;
}
else if (m_pfnErrorHandler)
{
m_pfnErrorHandler("too many arguments");
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief Àμö¸¦ Ǫ½¬ÇÑ´Ù.
/// \param value Àμö°ª
//////////////////////////////////////////////////////////////////////////////
void LuaDispatcherBase::arg(const int value)
{
if (m_CurArgs < m_MaxArgs)
{
LuaAPI::push(m_pState, value);
++m_CurArgs;
}
else if (m_pfnErrorHandler)
{
m_pfnErrorHandler("too many arguments");
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief Àμö¸¦ Ǫ½¬ÇÑ´Ù.
/// \param value Àμö°ª
//////////////////////////////////////////////////////////////////////////////
void LuaDispatcherBase::arg(const string& value)
{
if (m_CurArgs < m_MaxArgs)
{
LuaAPI::push(m_pState, value);
++m_CurArgs;
}
else if (m_pfnErrorHandler)
{
m_pfnErrorHandler("too many arguments");
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief Àμö¸¦ Ǫ½¬ÇÑ´Ù.
/// \param value Àμö°ª
//////////////////////////////////////////////////////////////////////////////
void LuaDispatcherBase::arg(const void* value)
{
if (m_CurArgs < m_MaxArgs)
{
LuaAPI::push(m_pState, value);
++m_CurArgs;
}
else if (m_pfnErrorHandler)
{
m_pfnErrorHandler("too many arguments");
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief Àμö¸¦ Ǫ½¬ÇÑ´Ù.
/// \param value Àμö°ª
//////////////////////////////////////////////////////////////////////////////
void LuaDispatcherBase::arg(const LUA_VECTOR& value)
{
if (m_CurArgs < m_MaxArgs)
{
LuaAPI::push(m_pState, value);
++m_CurArgs;
}
else if (m_pfnErrorHandler)
{
m_pfnErrorHandler("too many arguments");
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief Àμö¸¦ Ǫ½¬ÇÑ´Ù.
/// \param value Àμö°ª
//////////////////////////////////////////////////////////////////////////////
void LuaDispatcherBase::arg(const LUA_MAP& value)
{
if (m_CurArgs < m_MaxArgs)
{
LuaAPI::push(m_pState, value);
++m_CurArgs;
}
else if (m_pfnErrorHandler)
{
m_pfnErrorHandler("too many arguments");
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief ¸®ÅϰªÀ» ½ºÅÿ¡¼ ÆËÇÑ´Ù.
/// \param value ¸®ÅϰªÀÌ µé¾î°¥ º¯¼ö
//////////////////////////////////////////////////////////////////////////////
void LuaDispatcherBase::ret(bool& value)
{
if (m_CurReturns > 0)
{
LuaAPI::pop(m_pState, value);
--m_CurReturns;
}
else if (m_pfnErrorHandler)
{
m_pfnErrorHandler("no more return value");
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief ¸®ÅϰªÀ» ½ºÅÿ¡¼ ÆËÇÑ´Ù.
/// \param value ¸®ÅϰªÀÌ µé¾î°¥ º¯¼ö
//////////////////////////////////////////////////////////////////////////////
void LuaDispatcherBase::ret(int& value)
{
if (m_CurReturns > 0)
{
LuaAPI::pop(m_pState, value);
--m_CurReturns;
}
else if (m_pfnErrorHandler)
{
m_pfnErrorHandler("no more return value");
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief ¸®ÅϰªÀ» ½ºÅÿ¡¼ ÆËÇÑ´Ù.
/// \param value ¸®ÅϰªÀÌ µé¾î°¥ º¯¼ö
//////////////////////////////////////////////////////////////////////////////
void LuaDispatcherBase::ret(string& value)
{
if (m_CurReturns > 0)
{
LuaAPI::pop(m_pState, value);
--m_CurReturns;
}
else if (m_pfnErrorHandler)
{
m_pfnErrorHandler("no more return value");
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief ¸®ÅϰªÀ» ½ºÅÿ¡¼ ÆËÇÑ´Ù.
/// \param value ¸®ÅϰªÀÌ µé¾î°¥ º¯¼ö
//////////////////////////////////////////////////////////////////////////////
void LuaDispatcherBase::ret(void** value)
{
if (m_CurReturns > 0)
{
LuaAPI::pop(m_pState, value);
--m_CurReturns;
}
else if (m_pfnErrorHandler)
{
m_pfnErrorHandler("no more return value");
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief ¸®ÅϰªÀ» ½ºÅÿ¡¼ ÆËÇÑ´Ù.
/// \param value ¸®ÅϰªÀÌ µé¾î°¥ º¯¼ö
//////////////////////////////////////////////////////////////////////////////
void LuaDispatcherBase::ret(LUA_VECTOR& value)
{
if (m_CurReturns > 0)
{
LuaAPI::pop(m_pState, value);
--m_CurReturns;
}
else if (m_pfnErrorHandler)
{
m_pfnErrorHandler("no more return value");
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief ¸®ÅϰªÀ» ½ºÅÿ¡¼ ÆËÇÑ´Ù.
/// \param value ¸®ÅϰªÀÌ µé¾î°¥ º¯¼ö
//////////////////////////////////////////////////////////////////////////////
void LuaDispatcherBase::ret(LUA_MAP& value)
{
if (m_CurReturns > 0)
{
LuaAPI::pop(m_pState, value);
--m_CurReturns;
}
else if (m_pfnErrorHandler)
{
m_pfnErrorHandler("no more return value");
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief ÇÔ¼ö¸¦ ½ÇÇàÇÑ´Ù. ½ÇÇàÇϱâ Àü¿¡ ¸ðµç Àμö¸¦ Ǫ½¬ÇÑ »óÅ¿©¾ßÇÑ´Ù.
//////////////////////////////////////////////////////////////////////////////
void LuaDispatcherBase::execute()
{
if (m_CurArgs != m_MaxArgs && m_pfnErrorHandler)
{
m_pfnErrorHandler("not enough or too many arguments");
return;
}
if (lua_pcall(m_pState, m_MaxArgs, m_MaxReturns, m_ErrorFunc) == 0)
{
m_CurArgs = 0;
m_CurReturns = m_MaxReturns;
}
else if (m_pfnErrorHandler)
{
string errormsg;
LuaAPI::pop(m_pState, errormsg);
m_pfnErrorHandler(errormsg);
}
}
2.3 LuaAPI.h
//////////////////////////////////////////////////////////////////////////////
/// \file LuaAPI.h
/// \author excel96
/// \date 2004.10.18
//////////////////////////////////////////////////////////////////////////////
#pragma once
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
typedef vector<string> LUA_VECTOR;
typedef map<string, string> LUA_MAP;
//////////////////////////////////////////////////////////////////////////////
/// \class LuaAPI
/// \brief ·ç¾Æ <--> C/C++ µ¥ÀÌÅÍ ±³È¯À» Á» ´õ ÆíÇÏ°Ô ´Ù·ç±â À§ÇØ ¸¸µç
/// À¯Æ¿¸®Æ¼ Ŭ·¡½º.
///
/// Å×ÀÌºí °°Àº °æ¿ì¿¡´Â vector<string>, map<string, string> Çü½ÄÀ¸·Î¸¸
/// Ãë±ÞÇÑ´Ù. Å×ÀÌºí ¾ÈÀÇ Å×ÀÌºí °°Àº °É ´Ù·ç°Ô µÇ¸é, ÄÚµå Å©±âµµ Å©±âÁö¸¸
/// »ç¿ëÇϱⰡ º¹ÀâÇØÁö±â ¶§¹®ÀÌ´Ù.
//////////////////////////////////////////////////////////////////////////////
class LuaAPI
{
public:
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡ ÀÖ´Â °ªÀ» ÆËÇÑ´Ù.
static void pop(lua_State* L) {
AssertPtr(L);
lua_pop(L, 1);
}
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡ ÀÖ´Â °ªÀÌ nilÀÏ °æ¿ì ÆËÇÑ´Ù.
static void popnil(lua_State* L) {
AssertPtr(L);
luaL_checktype(L, -1, LUA_TNIL);
lua_pop(L, 1);
}
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡ ÀÖ´Â °ªÀ» ÁÖ¾îÁø bool º¯¼ö¿¡´Ù ¾´´Ù.
static void pop(lua_State* L, bool& value) {
AssertPtr(L);
luaL_checktype(L, -1, LUA_TBOOLEAN);
value = lua_toboolean(L, -1) != 0;
lua_pop(L, 1);
}
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡ ÀÖ´Â °ªÀ» ÁÖ¾îÁø int º¯¼ö¿¡´Ù ¾´´Ù.
static void pop(lua_State* L, int& value) {
AssertPtr(L);
luaL_checkint(L, -1);
value = static_cast<int>(lua_tonumber(L, -1));
lua_pop(L, 1);
}
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡ ÀÖ´Â °ªÀ» ÁÖ¾îÁø string º¯¼ö¿¡´Ù ¾´´Ù.
static void pop(lua_State* L, string& value) {
AssertPtr(L);
luaL_checkstring(L, -1);
value = string(lua_tostring(L, -1));
lua_pop(L, 1);
}
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡ ÀÖ´Â °ªÀ» ÁÖ¾îÁø void* º¯¼ö¿¡´Ù ¾´´Ù.
static void pop(lua_State* L, void** value)
{
AssertPtr(L);
luaL_checktype(L, -1, LUA_TLIGHTUSERDATA);
*value = const_cast<void*>(lua_topointer(L, -1));
lua_pop(L, 1);
}
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡ ÀÖ´Â °ªÀ» ÁÖ¾îÁø LUA_VECTOR º¯¼ö¿¡´Ù ¾´´Ù.
static void pop(lua_State* L, LUA_VECTOR& value);
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡ ÀÖ´Â °ªÀ» ÁÖ¾îÁø LUA_MAP º¯¼ö¿¡´Ù ¾´´Ù.
static void pop(lua_State* L, LUA_MAP& value);
public:
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡´Ù nil °ªÀ» pushÇÑ´Ù.
static void pushnil(lua_State* L) {
AssertPtr(L);
lua_pushnil(L);
}
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡´Ù bool °ªÀ» pushÇÑ´Ù.
static void push(lua_State* L, const bool value) {
AssertPtr(L);
lua_pushboolean(L, value);
}
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡´Ù int °ªÀ» pushÇÑ´Ù.
static void push(lua_State* L, const int value) {
AssertPtr(L);
lua_pushnumber(L, value);
}
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡´Ù string °ªÀ» pushÇÑ´Ù.
static void push(lua_State* L, const string& value) {
AssertPtr(L);
lua_pushstring(L, value.c_str());
}
static void push(lua_State* L, const void* value)
{
AssertPtr(L);
lua_pushlightuserdata(L, const_cast<void*>(value));
}
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡´Ù º¤Å͸¦ pushÇÑ´Ù.
static void push(lua_State* L, const LUA_VECTOR& value);
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡´Ù ¸ÊÀ» pushÇÑ´Ù.
static void push(lua_State* L, const LUA_MAP& value);
public:
/// \brief ÇöÀç ½ºÅÃÀ» Ãâ·ÂÇÑ´Ù
/// \param L ·ç¾Æ »óÅ °´Ã¼
static void printStack(lua_State* L);
};
2.4 LuaAPI.cpp
//////////////////////////////////////////////////////////////////////////////
/// \file LuaAPI.cpp
/// \author excel96
/// \date 2004.10.18
//////////////////////////////////////////////////////////////////////////////
#include "GameLibPCH.h"
#include "LuaAPI.h"
//////////////////////////////////////////////////////////////////////////////
/// \brief Á¤¼ö¸¦ ¹®ÀÚ¿·Î º¯È¯ÇÑ´Ù.
/// \param i ¹®ÀÚ¿·Î º¯È¯ÇÒ Á¤¼ö°ª
/// \return static string º¯È¯µÈ ¹®ÀÚ¿
//////////////////////////////////////////////////////////////////////////////
static string itos(const int i)
{
char buf[128] = {0,};
_snprintf(buf, sizeof(buf)-1, "%d", i);
return buf;
}
//////////////////////////////////////////////////////////////////////////////
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡ ÀÖ´Â °ªÀ» ÁÖ¾îÁø LUA_VECTOR º¯¼ö¿¡´Ù ¾´´Ù.
/// \param L ·ç¾Æ »óÅ °´Ã¼
/// \param value °ªÀ» Áý¾î³ÖÀ» º¯¼öÀÇ ÂüÁ¶
//////////////////////////////////////////////////////////////////////////////
void LuaAPI::pop(lua_State* L, LUA_VECTOR& value)
{
AssertPtr(L);
luaL_checktype(L, -1, LUA_TTABLE); // Å×À̺í È®ÀÎ
// Å×À̺íÀ» Ⱦ´ÜÇÏ¸é¼ °ªµéÀ» º¹»çÇÑ´Ù.
lua_pushnil(L);
while (lua_next(L, -2) != 0)
{
// key´Â stack[-2]¿¡ ÀÖ°í, value´Â stack[-1]¿¡ ÀÖ´Ù.
switch (lua_type(L, -1))
{
case LUA_TNUMBER:
value.push_back(itos(static_cast<int>(lua_tonumber(L, -1))));
break;
case LUA_TSTRING:
value.push_back( string(lua_tostring(L, -1)) );
break;
default:
break;
}
// Ű¿¡ ½ÖÀÌ µÇ´Â °ª(value)¸¸ Á¦°ÅÇÑ´Ù.
// ´ÙÀ½ iteration ½ÇÇàÀ» À§ÇØ ÇöÀç key°ªÀº ³²°ÜµÐ´Ù.
lua_pop(L, 1);
}
lua_pop(L, 1); // Å×À̺íÀ» popÇØÁØ´Ù.
}
//////////////////////////////////////////////////////////////////////////////
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡ ÀÖ´Â °ªÀ» ÁÖ¾îÁø LUA_MAP º¯¼ö¿¡´Ù ¾´´Ù.
/// \param L ·ç¾Æ »óÅ °´Ã¼
/// \param value °ªÀ» Áý¾î³ÖÀ» º¯¼öÀÇ ÂüÁ¶
//////////////////////////////////////////////////////////////////////////////
void LuaAPI::pop(lua_State* L, LUA_MAP& value)
{
AssertPtr(L);
luaL_checktype(L, -1, LUA_TTABLE); // Å×À̺í È®ÀÎ
// Å×À̺íÀ» Ⱦ´ÜÇÏ¸é¼ °ªµéÀ» º¹»çÇÑ´Ù.
lua_pushnil(L);
while (lua_next(L, -2) != 0)
{
// key´Â stack[-2]¿¡ ÀÖ°í, value´Â stack[-1]¿¡ ÀÖ´Ù.
string key, val;
switch (lua_type(L, -2))
{
case LUA_TNUMBER:
key = itos(static_cast<int>(lua_tonumber(L, -2)));
break;
case LUA_TSTRING:
key = string(lua_tostring(L, -2));
break;
default:
break;
}
switch (lua_type(L, -1))
{
case LUA_TNUMBER:
val = itos(static_cast<int>(lua_tonumber(L, -1)));
break;
case LUA_TSTRING:
val = string(lua_tostring(L, -1));
break;
default:
break;
}
value.insert(LUA_MAP::value_type(key, val));
// Ű¿¡ ½ÖÀÌ µÇ´Â °ª(value)¸¸ Á¦°ÅÇÑ´Ù.
// ´ÙÀ½ iteration ½ÇÇàÀ» À§ÇØ ÇöÀç key°ªÀº ³²°ÜµÐ´Ù.
lua_pop(L, 1);
}
lua_pop(L, 1); // Å×À̺íÀ» popÇØÁØ´Ù.
}
//////////////////////////////////////////////////////////////////////////////
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡´Ù º¤Å͸¦ pushÇÑ´Ù.
/// \param L ·ç¾Æ »óÅ °´Ã¼
/// \param value ½ºÅÿ¡´Ù Áý¾î³ÖÀ» º¯¼ö
//////////////////////////////////////////////////////////////////////////////
void LuaAPI::push(lua_State* L, const LUA_VECTOR& value)
{
AssertPtr(L);
// ºó Å×À̺íÀ» »ý¼ºÇØ ½ºÅÃÀÇ ¸Ç À§¿¡´Ù ³õ°í...
lua_newtable(L);
for (size_t i=0; i<value.size(); i++)
{
// ·ç¾Æ¿¡¼ index´Â 1ºÎÅÍ ½ÃÀÛ
lua_pushnumber(L, static_cast<int>(i+1));
lua_pushstring(L, value[i].c_str());
lua_rawset(L, -3);
}
}
//////////////////////////////////////////////////////////////////////////////
/// \brief ½ºÅÃÀÇ ÃÖ»ó´Ü¿¡´Ù ¸ÊÀ» pushÇÑ´Ù.
/// \param L ·ç¾Æ »óÅ °´Ã¼
/// \param value ½ºÅÿ¡´Ù Áý¾î³ÖÀ» º¯¼ö
//////////////////////////////////////////////////////////////////////////////
void LuaAPI::push(lua_State* L, const LUA_MAP& value)
{
AssertPtr(L);
// ºó Å×À̺íÀ» »ý¼ºÇØ ½ºÅÃÀÇ ¸Ç À§¿¡´Ù ³õ°í...
lua_newtable(L);
for (LUA_MAP::const_iterator itr(value.begin());
itr != value.end(); itr++)
{
lua_pushstring(L, itr->first.c_str());
lua_pushstring(L, itr->second.c_str());
lua_rawset(L, -3);
}
}
3 »ç¿ë¹ý
°³¿ä¿¡¼ ³ª¿Â ÇÔ¼ö¸¦ È£ÃâÇϰíÀÚ ÇÑ´Ù¸é ´ÙÀ½°ú °°ÀÌ ÇÏ¸é µÈ´Ù.
int call_add(lua_State* L, int lhs, int rhs)
{
LuaDispatcher d(L, "add", 1, lhs, rhs);
int result = 0;
d.ret(result);
return result;
}
4 TODO
- ¹Ýȯ°ª ó¸®ÇÏ´Â ºÎºÐµµ ¾à°£ ´õ ½Å°æ¾²¸é ±ò²ûÇÏ°Ô Ã³¸®ÇÒ ¼ö ÀÖÀ» °Í °°Àºµ¥...
SeriousMoin v1 (koMoinMoin 1.0a4 Modified)