2011-11-04 4 views
3

저는 루아 스크립팅을 사용하는 C++ 게임의 디자인/스켈레톤 코딩 단계에 있습니다.하지만 디자인 문제가 있습니다 :여러 엔터티에 대해 Lua 스크립트를 공유/재사용하는 방법은 무엇입니까?

게임은 같은 종류의 엔티티를 여러 개 가지고 있습니다. 같은 스크립트. 단일 lua_state에서 같은 유형의 엔티티간에 스크립트를 공유 할 수있는 간단한 방법이 있습니까? 나는이 질문을 인터넷에서 몇 번만 물어볼 수 있었다. 다른 lua_state에서 같은 스크립트를로드하는 것이 좋은지 아닌지에 대한 의견을 여러 번 읽었습니다. 대안에 대한 심층적 인 피드백이 아닙니다.

간단하고 방탄하지만, 생성 된 동일한 엔티티 유형의 각 인스턴스에 동일한 바이트 코드의 추가 사본을로드, 컴파일 및 저장하는 것은 비극적 인 낭비이므로 더 똑똑하다고 생각합니다. 해결책.

이들은 내가 생각한 두 가지 해결책입니다. 저는 프로그래밍이나 C 또는 OO 개념에 익숙하지 않지만 루아와 특히 루아/C API에 관해서는 여전히 배우고 있습니다. 내 아이디어가 건전하지만 난 루아 스크립트에서 OO를 구현하고 각 엔티티는 루아 객체에 의해 표현 될 수있다 그들 :

  1. 을 구현하는 방법에 대한 갈 것이라고하는 방법도 확실하지 않다 생각; 모든 루아 논리가 객체에 작용합니다. 이것은 또한 단일 환경으로 지구 환경을 변화시킬 수있는 이점 (또는 "이익")을 가질 것입니다.

  2. setfenv를 사용하여 각 엔티티를 자체 환경에서 캡슐화하고 전역 공간의 모든 기능 참조를 복사합니다. 내가 이해하는 바와 같이, env는 디폴트 글로벌 테이블과 다른 테이블이지만, setfenv를 살펴 봤지만 어떻게 할 것인지 모른다.

답변

4

1과 2는 같은 동전의 다른면들이다. 그것은 단순히 객체가 어디에 있는지의 문제입니다. 유형 1에서 객체는 Lua 스크립트의 명시적인 부분입니다. 즉 스크립트는 객체를 설정하는 방법을 결정합니다.

유형 2에서는 객체가 환경입니다. 그것은 여전히 ​​Lua 테이블이지만 외부 코드에 의해 생성 된 테이블입니다. 스크립트는 외부 코드가 허용하는 방식을 제외하고는이 객체의 범위를 벗어날 수 없습니다.

유형 1을 구현하는 가장 쉬운 방법은 Luabind입니다. 루아가 도출 할 수있는 C++ 클래스로 AI 객체를 가졌습니다. 해당 AI에 대한 "주 스크립트"를 실행하면 해당 클래스의 인스턴스가 만들어집니다. 제어하는 엔티티의 이름과 같은 스크립트 매개 변수를 전달할 수 있습니다. 제어 할 때 사용할 수있는 참조 일 수도 있습니다.

유형 2는 매우 간단합니다. 먼저 빈 테이블을 만들고 사용자가 액세스 할 수있게하려는 전역 변수를 채워 새 환경을 만듭니다. 이것들은 게임 상태 (게임 내 다른 객체를 찾는 것 등), 문제의 실체를 움직이는 방법 등등을위한 것입니다. metatable 트릭을 사용하면 효과적으로이 값을 변경 가능하지 않고 일정하게 만들 수 있으므로 사용자가 나중에 수정할 수 없습니다.

그런 다음 lua_loadstring 또는 lua_loadfile으로 스크립트를로드합니다. 이것은 루아 스크립트를 나타내는 루아 스택에 함수를 넣는다. 그런 다음이 테이블을 lua_setfenv이라는 스크립트 함수의 환경으로 적용합니다. 그런 다음 원하는 스크립트 (엔티티 이름 등)를 전달하여 해당 스크립트를 실행할 수 있습니다.

+0

저는 아이디어 2가 더 좋습니다. 스크립트에서 여러 객체를 보지 않아도되도록하고 싶습니다.실행중인 스크립트의 각 복사본에 대해 환경을 설정하는 데 필요한 metatable 마법을 설명 할 수 있습니까? 또한 lua_loadfile을 사용하려는 이유를 이해하지 못합니다. 내가 이해하는 한, 스크립트를 실행하지 않고 스크립트를 컴파일하기 만하므로 함수 선언 같은 것은 평가되지 않습니다. – stands2reason

+1

@stand2reason : 바로 이것이 왜 lua_dofile 대신에 호출하는 이유입니다. 왜냐하면 당신은'lua_dofile'을 할 수없고 환경을 제공 할 수 없기 때문입니다. 스크립트 자체는 단지 기능에 불과합니다. 해당 함수를 환경 내에서 실행하려고합니다. 그리고 스택에있는 함수에만 환경을 첨부 할 수 있습니다. 따라서 함수를 스택에'lua_loadfile'으로로드 한 다음 환경을 첨부 한 다음 함수를 실행해야합니다. –

+0

명확히하기 위해 setfenv는 스택에서 테이블을 가져 와서 실행하려고하는 것에 대한 새로운 _G로 만듭니다. 메타 테이블을 사용하고 있다면이 테이블을 빈 테이블로 시작하지 않으시겠습니까? 함수를 공유하기 위해 메타 테이블을 설정하는 방법을 설명 할 수 있습니까? – stands2reason

관련 문제