LuaRover 1.0.0 알파 버전입니다.

9 views
Skip to first unread message

류광

unread,
Dec 13, 2007, 10:59:00 AM12/13/07
to luausers-kr
테스트를 목적으로 하는 알파 버전입니다. '파일' 란에 압축 파일을 올려 두었습니다.

ReadMe.txt 내용은 다음과 같습니다:

=================================================
C++을 위한 간단한 루아 접근 라이브러리 - LuaRover
=================================================

LuaRover는 C++에서 루아에 접근하는 것만을 염두에 둔 간단한 라이브러리입니다.

사용 권한:
==========

이 라이브러리의 사용 권한은 Lua와 동일한 Lua License를 따릅니다.
Lua License의 내용은 COPYRIHGT 파일에 있습니다. (본질적으로 MIT License와
동일합니다.)

저작권자는 Ryu, Gwang(류광, http://occamsrazr.net/)입니다.

최신 정보 및 피드백
===================

최신 버전의 공지는 한국 루아 사용자 그룹
(http://groups.google.com/group/luausers-kr)에 올리겠습니다.

의견이나 질문은 그 곳이나 http://occamsrazr.net의 자유 게시판에
올려주세요.

*** 현재 버전 1.0.0-alpha는 충분한 테스트를 거치지 않은 상태이기 때문에
아래에 나온 내용과 다른 부분이 있을 수 있으며, 아래의 내용에서 언급하지
않은 버그들이 있을 수 있습니다. 시험용으로만 사용하시기 바랍니다~ ***

특징:
=====

* C++에서 루아에 접근하는 기능만 제공하며, 루아에서 C/C++에 접근하는
기능은 없습니다.
* 매크로와 { } 블록을 이용한 정형화된 표기법을 제공합니다. 이 표기법만
지키면 루아 스택이 깨지는 일은 (이론적으로) 생기지 않습니다.

사용법:
=======

현재는 라이브러리 형태가 아니라 헤더 파일 하나와 소스 파일 형태로
배포됩니다. 소스 파일(lua_rover.cpp)를 프로젝트에 포함시키고,
원하는 소스 파일에서 lua_rover.hpp)를 #include하면 사용 준비가 끝납니다.

Lua C API를 직접 사용할 것이 아닌 한 lua.hpp를 따로 #include할 필요는 없습니다.
그러나 lua_rover.hpp와 .cpp는 Lua의 헤더와 라이브러리를 사용하므로 컴파일러
또는 프로젝트에 Lua 라이브러리 관련 설정이 되어 있어야 합니다.

LuaRover를 사용하기 위한 수단들은 다음과 같습니다.

매크로 LUA_ROVER_WITH_FILE(filename)
------------------------------------
루아 환경(lua_State)를 생성하고 주어진 루아 파일을 불러들입니다. 이 시점에서
LG라는 변수가 생성됩니다.

반드시 { } 블록을 사용해야 합니다.

예:
LUA_ROVER_WITH_FILE("test.lua")
{
// 1...
}

매크로 LUA_ROVER_WITH_TABLE(table_spec)
---------------------------------------
LUA_ROVER_WITH_FILE 블록 안(위의 1) 에서 사용하며, table_spec으로 주어진
테이블에 접근할 수 있는 L이라는 변수를 생성합니다.

반드시 { } 블록을 사용해야 합니다.

예:
LUA_ROVER_WITH_FILE("test.lua")
{
LUA_ROVER_WITH_TABLE("t1")
{
int x = L["x"]; // test.lua의 t1.x의 값을 int 변수에 설정
}
}

LUA_ROVER_WITH_TABLE의 table_spec은 다음과 같은 형식을 지원합니다.

LUA_ROVER_WITH_TABLE("t1") : 전역 범위의 t1이라는 테이블을 L에 배정.
LUA_ROVER_WITH_TABLE("t1.f1") : 전역 범위 t1의 필드 f1을 L에 배정.
LUA_ROVER_WITH_TABLE("t1.f1.f2.f3") : 마침표를 이용해서 필드의
필드의 필드.... 를 임의로 지정할 수 있습니다.

LUA_ROVER_WITH_TABLE(".f1") : 첫 글자가 마침표이면 자신을 감싸고 있는
다른 LUA_ROVER_WITH_TABLE의 필드를 L에 배정합니다.

예: 1과 2는 동일한 의미입니다.

// 1
LUA_ROVER_WITH_TABLE("t1")
{
LUA_ROVER_WITH_TABLE(".f1")
{
int x = L["x"]; // t1.f1.x
}
}
// 2
LUA_ROVER_WITH_TABLE("t1.f1")
{
int x = L["x"]; // t1.f1.x
}

변수 LG
-------
LUA_ROVER_WITH_FILE에 의해 자동으로 생성되는 변수입니다. 루아 환경의
전역 범위에 접근하기 위한 수단이며, LUA_ROVER_WITH_TABLE 매크로도 내부적으로
이 변수를 사용합니다. 이 변수는 LUA_ROVER_WITH_FILE 안에서 유일하게 존재하며,
블록 안의 어느 곳에서도 사용할 수 있습니다.

사용 예:

LUA_ROVER_WITH_FILE("test.lua")
{
int gX = LG["x"]; // test.lua의 전역 변수 x의 값을 int 변수에 설정

LUA_ROVER_WITH_TABLE("t1.f1")
{
int x = L["x"]; // t1.f1.x
gY = LG["y"]; // 이 LG는 처음 나온 LG와 동일한 것임.
}
}

LG는 [] 연산자와 val<T>() 템플릿 함수를 지원합니다. 또한 배정 연산자와 값 변환
연산자들도 지원합니다.

[] 연산자는 전역 변수에 접근하기 위한 것입니다. 예를 들어 전역 변수 x에 접근하기
위해서는 LG["x"]라고 표기하면 됩니다. 구체적인 형식을 가진 변수에 LG["x"]를
배정하면 내부적으로 변환 연산자에 의해 해당 형식의 값이 추출됩니다.

예:
int x = LG["x"];

[] 연산자는 연결해서 사용할 수 있습니다. 다음은 루아의 t1.f1.f2.x에 접근하는
예입니다.

int x = LG["t1"]["f1"]["f2"]["x"];

val<T>()는 템플릿 함수 등 암묵적인 변환 연산자가 적용될 수 없는, 따라서 값의
형식을 명시해야 하는 상황을 위한 것입니다.

std::cout << LG["x"] << std::endl; // 오류

std::cout << LG["x"].val<int>() << std::endl;

현재 T로 가능한 형식은 int, double, std::string 입니다.

LG는 또한 배정 연산자도 지원합니다.

LG["x"] = 10;
LG["t1"]["f1"]["f2"]["x"] = 12.3;


변수 L
------
LUA_ROVER_WITH_TABLE에 의해 자동으로 생성되는 변수로, 해당 테이블의 필드
에 접근하기 위한 수단입니다. L은 각 LUA_ROVER_WITH_TABLE마다 새로 생성됩니다.

LUA_ROVER_WITH_FILE("test.lua")
{
int gX = LG["x"]; // test.lua의 전역 변수 x의 값을 int 변수에 설정
// int gX = L["x"]; // 에러 - 현재 범위에는 L이 없음
LUA_ROVER_WITH_TABLE("t1.f1")
{
int x = L["x"]; // t1.f1.x
gY = LG["y"]; // 이 LG는 처음 나온 LG와 동일한 것임.
}

LUA_ROVER_WITH_TABLE("t1")
{
int x = L["x"]; // t1.x 위의 L과는 다른 변수임.
gY = LG["y"]; // 이 LG는 처음 나온 LG와 동일한 것임.
}

}

L도 LG처럼 [] 연산자, val<T>() 함수, 배정 연산자, 변환 연산자들을 지원합니다.
작동 방식도 동일합니다. 단, L의 경우 기준은 전역 범위가 아니라 해당
LUA_ROVER_WITH_TABLE에서 적재한 테이블입니다. 위의 코드 예제에서 LG["x"]는
전역 변수 x를 지칭하지만, 첫 L["x"]는 t1.f2 의 필드 x를 지칭합니다.

예외 처리
---------
LuaRover는 잘못된 접근(예를 들면 존재하지 않는 전역 변수에 접근하거나,
테이블이 아닌 값에 대해 필드 접근을 시도하는 등)이 일어나면 LuaError 형식의
예외를 던집니다.

LuaError는 다음 두 메서드를 제공합니다.

const char* LuaError::what() - 간단한 오류 메시지 문자열을 돌려줍니다.
ErrorCode LuaError::code() - ErrorCode 열거형 오류 코드를 돌려줍니다.
ErrorCode 열거형은 lua_rover.hpp에 정의되어 있습니다.

예외 처리 예:

// 만일 test.lua에 non_exist라는 변수가 없으면
// "non_exist is Not Defined"가 출력됨
try
{
LUA_ROVER_WITH_FILE("test.lua")
{
int n = LG["non_exist"];
}
catch(LuaError e)
{
cout << e.what() << "\n";
}
}


고급 사용 팁
============

매크로 이름 커스텀화
--------------------
LUA_ROVER_WITH_TABLE이나 LUA_ROVER_WITH_FILE의 타이핑이 번거롭다면 짧은
버전을 직접 정의해서 쓰면 됩니다. 예를 들면:

#define WITH_F LUA_ROVER_WITH_FILE
#define WITH_T LUA_ROVER_WITH_TABLE

WITH_F("test.lua")
{
WITH_T("t1.f1")
{
int x = L["x"]; // t1.f1.x
gY = LG["y"]; // 이 LG는 처음 나온 LG와 동일한 것임.
}
}

변수 LG, L 이름 바꾸기
----------------------
LG이나 L이라는 이름이 마음에 들지 않는다면, lua_rover.hpp를 #include하기
'전에' LUA_ROVER_GLOBAL_ID와 LUA_ROVER_LOCAL_ID 매크로로 원하는 이름을
정의하면 됩니다.

예:

#define LUA_ROVER_GLOBAL_ID g_
#define LUA_ROVER_LOCAL_ID t_

#include "lua_rover.hpp"

WITH_F("test.lua")
{
WITH_T("t1.f1")
{
int x = t_["x"]; // t1.f1.x
gY = g_["y"]; // 이 LG는 처음 나온 LG와 동일한 것임.
}
}

다음과 같은 형태의 커스텀 헤더를 만들어 두고 사용하면 편할 것입니다.
// my_lua_rover.hpp
#ifndef MY_LUA_ROVER_HPP
#define MY_LUA_ROVER_HPP

#define LUA_ROVER_GLOBAL_ID g_
#define LUA_ROVER_LOCAL_ID t_

#include "lua_rover.hpp"

#define WITH_F LUA_ROVER_WITH_FILE
#define WITH_T LUA_ROVER_WITH_TABLE

#endif // #ifndef MY_LUA_ROVER_HPP

커스텀 헤더 사용 예:
// test.cpp
#include "my_lua_rover.hpp"

void f()
{
WITH_F("test.lua")
{
WITH_T("t1.f1")
{
int x = t_["x"];
gY = g_["y"];
}
}
}

루아 상태의 공유
----------------
LUA_ROVER_WITH_FILE 매크로는 블록의 시작에서 새로운 루아 상태를 생성하고
파일을 적재하며, 블록의 끝에서 루아 상태를 파괴합니다. 이런 방식은 스택이
잘못 되는 일을 방지할 수 있다는 점에서 안전하지만, 경우에 따라서는 비효율적
일 수 있습니다.

LUA_ROVER_WITH_TABLE이 LG라는 이름에 의존한다는 점을 이용해서 루아 상태를
공유하는 것이 가능합니다. 이를 위해서는 LUA_ROVER_WITH_FILE로 루아 상태를
여는 대신, 다음과 예처럼 LuaGlobal 형식의 인스턴스를 직접 생성하고 참조로 넘겨주면 됩니다.

#include "lua_rover.hpp"

using namespace LuaRover;

void load_graphics_options(LuaGlobal&);
void load_sound_options(LuaGlobal&);

int main()
{
LuaGlobal LG("options.lua");
load_graphcis_options(LG);
load_sound_options(LG);
}

void load_graphics_options(LuaGlobal& LG) // "LG"라는 이름이 중요함
{
// LUA_ROVER_WITH_TABLE이 작동하기 위해서는
// 이 시점에서 LG라는 이름의 LuaGlobal 인스턴스가 존재해야 함
LUA_ROVER_WITH_TABLE("graphics")
{
Graphics::set_resolution(L["res"]["w"], L["res"]["h"]);
// .. 기타 등등 ..
}
}


void load_sound_options(LuaGlobal& LG) // "LG"라는 이름이 중요함
{
// LUA_ROVER_WITH_TABLE이 작동하기 위해서는
// 이 시점에서 LG라는 이름의 LuaGlobal 인스턴스가 존재해야 함
LUA_ROVER_WITH_TABLE("sound")
{
Sound::set_main_volume(L["volume"]);
// .. 기타 등등 ..
}
}

물론, LUA_ROVER_GLOBAL_ID 매크로를 이용해서 LG를 다른 이름으로 바꾸었다면
그 이름을 사용해야 합니다.

류광

unread,
Dec 13, 2007, 11:06:37 AM12/13/07
to luausers-kr
앗 Readme.txt 파일에 문제가 있어서 '파일' 란에 압축 파일을 다시 올렸습니다. try .. catch 예제에서 중괄
호 블록이 잘못 지정되었고, 탭 들여쓰기가 망가진 부분이 있었습니다. 수정된 Readme.txt는 다음과 같습니다....
On 12월14일, 오전12시59분, "류광" <ryugw...@gmail.com> wrote:
> 테스트를 목적으로 하는 알파 버전입니다. '파일' 란에 압축 파일을 올려 두었습니다.
>
> ReadMe.txt 내용은 다음과 같습니다:
>
> =================================================
> C++을 위한 간단한 루아 접근 라이브러리 - LuaRover
> =================================================
>
> LuaRover는 C++에서 루아에 접근하는 것만을 염두에 둔 간단한 라이브러리입니다.
>
> 사용 권한:
> ==========
>
> 이 라이브러리의 사용 권한은 Lua와 동일한 Lua License를 따릅니다.
> Lua License의 내용은 COPYRIHGT 파일에 있습니다. (본질적으로 MIT License와
> 동일합니다.)
>
> 저작권자는 Ryu, Gwang(류광,http://occamsrazr.net/)입니다.
>
> 최신 정보 및 피드백
> ===================
>
> 최신 버전의 공지는 한국 루아 사용자 그룹
> (http://groups.google.com/group/luausers-kr)에올리겠습니다.
>
> 의견이나 질문은 그 곳이나http://occamsrazr.net의자유 게시판에

하얀고양이

unread,
Dec 13, 2007, 7:16:36 PM12/13/07
to luausers-kr
오오 당장 해봐야 겠습니다.

류광

unread,
Dec 14, 2007, 4:27:44 AM12/14/07
to luausers-kr
황당한 버그가 하나 있습니다.

LG["전역테이블"]["필드"] = 값;

은 되지만

LG["전역변수"] = 값;

은 오류가 나네요. 원래 테이블 접근용으로 만들던 것이어서 전역 변수의 설정은 미처 생각하지 못했습니다.... 조만간 수정본을
올리겠습니다.

그리고 정수 색인 접근의 편의를 위해 L 에 테이블의 최대 정수 색인을 돌려주는 멤버 함수(maxn이 적당하겠죠)를 추가할 필요
가 있을 것 같습니다... 이것까지 추가하고 alpha를 떼겠습니다.

On 12월14일, 오전9시16분, "하얀고양이" <agcr...@gmail.com> wrote:
> 오오 당장 해봐야 겠습니다.
Reply all
Reply to author
Forward
0 new messages