2008년 02월 04일
Lua Script with WPF
근래에 연구하고 있는 주제입니다. 아마 Lua, Ruby, Phython등등 동적 언어에 관심있는 분에게는 도움이 되지 않을까 생각해서 올립니다. 원래 동적 언어라는 것이 C++, C처럼 Standalone으로 쓰이도록 만들어졌다기 보다는 다른 프로그램을 확장하거나 동적으로 변경이 필요할때 적용하기 위해서 만들어진 것입니다. 제가 주로 사용하는 동적 언어는 Lua 인데 그 이유는 작고 빠르며 매우 유연한 프로그래밍 구조를 가지고 있고 다른 언어와의 융합이 쉽기 때문입니다. (Ruby도 좋은 언어입니다. 웹개발 하시는 분들은 Ruby를 공부해보시는 것도 좋을듯 합니다. Rails와 함께요)
최근 WPF(Windows Presentation Foundation)과 관련된 과제를 진행중인데 여기에 Lua를 붙여 XAML과 융합하는 방식을 연구하고 있습니다. 원래 WPF는 C#만을 사용하도록 되어 있어서 XAML의 이벤트 핸들링이나 XAML로는 불가능한 절차적 작업을 가능케 하는 용도로 사용되고 있습니다. 하지만 한가지 문제가 있다면 C#을 컴파일 할수있는 환경, 즉 VS2005이상이 깔린 PC에서만 작업이 가능하다는 문제가 있습니다. 게다가 C#소스를 수정할 때마다 프로그램 전체를 재 컴파일 해야 합니다. 이렇게 되므로 프로그램의 동적인 확장도 어렵습니다.
하지만 XAML과 WPF는 비교적 적은 노력으로 (이전의 MFC등과 비교했을때) 멋진 클라이언트 프로그램을 짤수있는 차세대 기술입니다. 따라서 굳이 컴파일 할 필요없이 소스의 수정만으로 바로 멋진 결과를 확인할수 있는 방법을 동적언어들이 제공해줄수 있습니다. 게다가 엄청 복잡한 엔터프라이즈 프로그램이 아닌 간단한 용도의 프로그램을 WPF로 만든다면 (위젯같은것을 만든다고 생각해보세요) 무겁게 컴파일 해야하는 C#이 필요한지 의심스럽기도 합니다.
저는 그래서 LuaInterface라는 물건을 이용하여 WPF의 로직적인 부분, 그러니까 전에 C#이 해결해야 하는 부분들을 Lua에서 대신할수 있도록 해주는 위젯 엔진을 개발하고 있습니다. LuaInterface는 .NET CLR 객체들을 Lua에서 매우 쉽게 핸들링할수 있도록 해줍니다. 그리고 그 역으로 Lua의 객체들을 C#에서 관리할수 있는 방법도 같이 제공해줍니다.
예를들어 c#으로 다음과 같은 WPF 객체를 만들었다고 합시다.
Button myButton = new Button();
이제 이것을 Lua로 보냅니다. 보내는 방법은 매우 간단한데 바로 LuaInterface가 제공하는 Lua 객체를 이용하는 것입니다.
Lua["myButton"] = myButton;
이제 Lua에서 다음과 같이 이벤트 핸들링을 할수 있습니다.
myButton.Click:Add(myLuaClickEventHandler)
function myLuaClickEventHandler(sender, args)
-- 이벤트 핸들링 코드
end
이렇게 하면 WPF 폼에서 myButton을 클릭했을때 발생하는 이벤트는 Lua의 myLuaClickEventHandler 에서 처리할수 있습니다.
이러한 방식의 장점은 만일 myButton같은 이벤트 객체가 매우 많을때 이들의 이벤트를 동적으로 떼고 붙이거나 확인하는 등의 변경작업을 Lua 스크립트 코드만을 수정하여 해결할수 있다는 것입니다. 메모장이나 에디트 플러스등으로 간단하게 루아 코드를 수정하고 프로그램을 재 실행하기만 하면 됩니다. 다시 VS를 띄워 프로젝트를 열고 컴파일해야 할 필요가 전혀 없습니다.
이런 일들이 가능한 이유는 .NET 의 마셜링과 어셈블리라는 것 때문입니다. 간단히 이야기하지면 .NET의 모든 프로그램은 자신이 가진 모든 자료형과 함수들에 대해서 "이것이 어떤 형태를 지니고 있다"는 것을 분명히 명시해 주는 설계도를 지니고 있습니다. LuaInterface 는 내부적으로 위 코드처럼 넘어온 .NET 객체들의 어셈블리 정보를 보고 "이것은 Button이라는 이름의 객체로 크기는 몇 바이트고 안의 함수와 변수는 이러이러한 것들이 몇개나 있다"는 것을 알아냅니다. 그리고 이를 바탕으로 루아의 자료형에 맞는 (보통은 Userdata 형태로 들어갑니다. Userdata는 Lua가 타 언어와 데이터를 공유하기 위해서 사용하는 자료형입니다.) 데이터로 마셜링(객체를 바이트의 스트림으로 변경시키거나 복구합니다.)을 행하여 전달하게 됩니다. 이의 반대도 마찬가지로 일어나게 됩니다. (이러한 일은 Reflection 네임스페이스의 객체를 이용함으로서 가능합니다.)
따라서 결과적으로 중간의 번역기 (LuaInterface) 같은 존재만 있다면 동적인 언어와 XAML그리고 WPF 를 같이 사용하는 것은 절대로 불가능한 일이 아니라는 것입니다. 이러한 동적인 언어의 활용은 Silverlight 2.0에서 지원될 것인데 여기서는 아이언 파이선, 루비, 파스칼 등의 언어를 C#대신 활용할수 있는 DLR(Dynamic Language Runtime)을 통해서 가능합니다. 그리고 이러한 방향이 바로 .NET이 추구하는 방향이기도 하며 제가 좋아하는 방법이기도 합니다. (새로운 언어일수록 같은 문제를 좀더 새로운 방식으로 해결할수 있기 때문입니다.)
물론 퍼포먼스를 고려하는 분들은 느려질수도 있지 않느냐 걱정하기도 합니다만 그런 부분들은 네이티브 코드로 짜면 되기 때문에 큰 문제는 되지 않습니다. 보통 퍼포먼스 문제와 관련된 것들은 그렇게 잦은 수정이 필요한 부분이 아니기 때문에 (눈에 잘 안보이는 부분들) 그냥 가장 빠르고 어려운 길로 하면 됩니다. 하지만 제가 강조하고 싶은건 쉽게 갈수 있는 방법을 굳이 어려운 언어로 할 필요가 없다는 것이지요. 게다가 우리가 많이 하는 와우를 보시면 와우에서 제공하는 이벤트와 UI모두가 위의 Lua로 짜여져있다는 것을 발견하실겁니다. 그리고 그 문제가 딱히 성능에 큰 영향을 미치지 않는다는 것도 알수 있을것입니다.
# by | 2008/02/04 15:46 | Technics | 트랙백





☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]