삽질하는플머

Delphi web script 갖고 놀기

탐구생활/Delphi
DWScript 

개발자의 블로그는 여기

지원하는 델파이 최소버전이 2009이다. 터보델파이 이후로는 무거워서 손이 잘 안가게 되는데... 아무튼 핑계김에 미루어두었던 XE2 설치. 
 




업데이트 3까지 진행하고 환경설정을 익숙하게 맞추어준다. 




SynEdit SVN 설치. 

 
DWScript 개발자의 블로그에는 작년 12월 26일 크리스마스 선물로 SynEdit SVN에 패치를 올렸다는 글이 있다. 
http://delphitools.info/2011/12/26/christmas-present-for-synedit-users/ 

하이라이팅 속도가 많이 빨라졌다고 하고 무엇보다 DWScript의 예제가 이 버전을 기준으로 하니 이걸로 내려받아 설치하자. 

svn co https://synedit.svn.sourceforge.net/svnroot/synedit/SynEdit SynEdit



세상일이 다 그렇듯, 단박에 설치되는 법이 없다. 델파이의 컴파일러는 안시파일의 코드페이지를 시스템의 설정에 따라 판단하는 희안한 행동을 하기 때문에, 코드 내에서 유니코드를 사용한 경우 일일이 BOM을 붙여 UTF-8 임을 알려주어야 한다. SynEdit.pas, SynEditHighlighter.pas, SynEditSearch.pas, SynHighlighterJava.pas, SynHighlighterXML.pas 가 그러한데... 이렇게 해도 CASE문에서 이유없는 중복에러가 발생한다. 자세한 건 XE2에 좀 더 익숙해지면 알아보도록 하고, 일단 설치만 되도록 패치를 만들어 보았다. 




DWScript 테스트

dwscript-2.2 를 받아 압축을 푼다. XE용 패키지가 있으니 그대로 사용한다. 
데모를 살펴보니 Hello 라는 예제가 보인다. 열어보자. 

var s : String = ''Hello World!';
ShowMessage(s);



위와 같은 파스칼 스크립트를 입력받고 실행시키는 예제이다. 실행시키면 "Hello World!" 라고 찍힌 메시지박스가 나타난다. 재미있군. 
이제 오늘의 하이라이트! pas2js 를 갖고 놀아 보자.
 
http://delphitools.info/2011/09/28/taming-the-flock-with-object-pascal/ 

본문 내 링크에서 demo.zip 을 내려받아 압축을 푼다. JSCodeGenDemo.dproj 를 열고 컴파일하면 짜잔~~



이 프로그램은 인디의 idHTTPServer 를 사용해 독립 웹서버로 동작한다. <%pas2js ... %> 태그 사이에 파스칼 스크립트로 코드를 적어주면 이 부분을 자바스크립트로 변환해 클라이언트로 내려주게 된다. 과감하게 Run 버튼을 눌러보자. 



웹브라우저가 열리며 마우스 이동과 클릭에 반응하는 멋진 canvas 화면이 나타난다. 웹페이지의 소스보기를 하면 파스칼 스크립트가 자바스크립트로 변환되어 전송된 것을 볼 수 있다. 물론 브라우저를 띄우지 않아도 Compile 버튼을 눌러 변환된 자바스크립트를 얻을 수 있다. 

파스칼 스크립트 내 "asm .. end" 구문은 조금 별난 개념으로, 자바스크립트를 직접 호출하는데 사용된다.
간단한 예를 들어보자. 메시지 창을 띄우는 ShowMessage() 함수를 DWScript로 구현한다면 다음과 같이 할 수 있다. 

<%pas2js

procedure ShowMessage(msg: String);
begin
  asm
    alert(msg);
  end;
end;

ShowMessage('테스트야 테스트');
%>



위 내용은 다음과 같이 변환된다. 

function ShowMessage(msg) {
    alert(msg);
  };
ShowMessage("테스트야 테스트");



파스칼에서 외부 링크된 함수를 불러오는 것 처럼, external 구문을 써서 자바스크립트의 alert 함수를 직접 사용할 수도 있다. 

<%pas2js

procedure alert(msg: Variant); external;

alert('테스트야 테스트');
%>



변환된 내용은 다음과 같다. 

alert("테스트야 테스트");



이 외에도 문자열을 나타내는 따옴표를 쌍따옴표와 섞어 사용할 수 있는 등 델파이의 문법과는 약간씩 달라 헷갈리기는 하지만, 파스칼로 건드리는 HTML5 코딩이라는 점 만으로도 충분히 갖고 놀아볼만한 가치가 있다고 생각된다. 

아래 화면은 Delphitools.info 의 또 다른 예제를 위의 변환기로 컴파일해 이 블로그의 HTML편집기능으로 직접 써넣은 것이다. 
HTML5를 지원하는 최신 브라우저에서 무리없이 동작할 것이다. 실로 아름답지 않은가... (아이폰에서도 동작은 하는데 많이 느림...)




 

델파이 새 버전. RadStudio XE2 발표회 후기

탐구생활/Delphi
2011년 8월 12일, 델파이 새버전 RadStudio XE2 의 발표회가 있었다. 
소문만 무성하던 파이어몽키의 모습이 궁금하기도 했고, 페북에 링크된 개발자님들도 많이들 참가하신다고 해서 월~목 까지 폭풍야근, 금요일 업무를 제끼고 간만에 코엑스로 나들이를 했다. 조금 늦은 후기지만, 기억이 더 엷어지기 전에 그 날의 느낌들을 끄적여두자. 


행보관도 찿기 힘든 구석자리... 파릇파릇 린님, 푹 익은 현호님과 함께 짱박힘. 



발표회는 오전 10시부터 오후 5시까지 진행되었고 각 섹션은 다음과 같다. 

첫번째 시간은 XE2 에 대한 소개. 
두번째, 세번째 시간은 기대했던 파이어몽키에 대한 내용. 
네번째 시간은 64비트 환경에서의 프로그래밍에 대한 소개.
다섯번째 시간은 라이브바인딩이라는 새로운 데이터베이스 접근방법에 대한 소개.
여섯번째 시간은 데이터스냅에 대한 이야기.
일곱번째 시간은 XE2에서 제공하는 모바일솔루션 짚어보기. 


발표자는 엠베카데로 아태지역 수석 전도사 고든-리. 전도사라고 하니까 왠지 종교집단 느낌이... 
암튼 이 분 혼자서 네번째 섹션 하나 빼고 하루종일 발표와 데모를 진행하는 괴물같은 체력을 내뿜었다. 


뒷풀이 장소에서. 맨 왼쪽이 데브기어 대표님, 그 옆이 강사였던 강철체력 고든 리 님.  



사실 내가 사용해 본 가장 최신의, 그리고 가장 애용하는 버전의 델파이는 터보델파이(2006) 이다.
게임이 밥벌이인데다 요새는 PHP 코드를 더 많이 만지고 있고, 한때 이슈였던 유니코드 역시 델파이5 가 현역이던 2000년 초반에 미친듯 삽질을 했었기에, 적어도 내 입장에서는 업그레이드에 대한 별다른 이유를 찾지 못하고 있었다. 때문에 발표회에 참가하기 전 까지는 "가봐야 뭐 별 거 있겠어~" 정도가 솔직한 심정이었는데... "이런 XXX!! 어썸!!! 생각보다 괜찮네!!!!"

이 날 사용되었던 XE2는 베타 8버전으로서 시연중 몇몇 상황, 특히 파이어몽키 기반의 어플들에서 오류가 발생하기도 하였다. 
하지만 충분히 매력적인 물건이고 "지금까지 잊고 있던 업그레이드에 욕망을 한꺼번에 불러일으키는 물건이다."
물론 그 이유는 파이어몽키.  

잠깐 옆으로 새서, 아이폰 앱을 취미삼아 만지작거리면서 (물론 파스칼로) 가장 신기했던 점은 OpenGL로 뿌려지는 화면 위에 라벨이나 에디트같은 다른 코코아 컨트롤을 올려도 그들 사이에 Z-Order 나 각각의 투명도가 그대로 유지된다는 것이었다. 윈도에서 3D 가속을 받는 화면위에 윈도 컨트롤들을 올려본 개발자라면 이 말에 동의할텐데... 핸들이 없는 라벨등의 경우는 말할것도 없고 핸들을 가진 에디트같은 컨트롤들도 창모드 말고 풀스크린에서는 아예 표시도 되지 않는다. 게다가 배경은 칙칙한 윈도 기본색이 되고. 이 때문에 웹브라우저 컨트롤을 게임화면에 임베딩하기 위해 눈물을 머금고 성능을 포기하면서 창모드를 고수하는 경우도 많이 있었다. 웹킷을 3D 환경에 랜더링하는 Awesomium 같은 제품이 (예전엔 오픈소스였는데...) 관심을 끄는 것도 이런 열악한 환경 때문. 

너무 멀리갔다. 아무튼 이렇게 iOS에서 OpenGL화면과 UIKit의 컨트롤들이 자연스럽게 어우러지는 것은 이미 iOS의 화면표시 자체가 GPU의 가속을 받고 있고 UIKit도 그 기반에서 만들어졌기 때문인데, 이 부럽기 그지없는 환경을 드디어 우리 윈도 프로그래머들도 누리게 되었다. 파이어몽키는 버튼이나 에디트같은 UI 요소들이 OS가 제공하는 리소스에 의존하지 않고, 화면에 그려질 때는 GPU 가속을 받도록 완전히 새로 만들어진 UI 프레임워크이기 때문이다. 


저 컨트롤들은 핸들이 없어. 윈도프로시저도 없어. 스파이로 안잡혀.




반투명에 회전도 자유로워~


게다가 놀라운것은 이 프레임워크를 멀티플랫폼의 전초기지로 사용했다는 점인데...

파스칼을 사용하며 멀티플랫폼을 지원하는 라자루스의 경우 LCL(에반게리온 떠올리는 당신은 덕후!)이라는 레이어를 두고 여기서 Windows, QT, GTK 등 각 UI세트에 해당하는 위젯셋을 구현하는 방식인데, 때문에 각 플랫폼에서 공통적으로 지원하는 기능 이상을 만들기 쉽지 않다. 아무리 QT가 발전해 3D 신세경을 보여줘도 윈32가 이를 지원하지 않는 이상 LCL에서 이런 멋진 결과를 공통적으로 구현하기는 어렵다는 이야기.

엠베카데로가 KSDev의 VGScene를 인수하면서 만들어낸 해법은 조금 더 스케일이 컸다. 아예 UI 플랫폼을 다시 만들고 이것을 다른 OS에서도 동작시키는 것. 사실 각 OS별로 출력은 그렇다고 해도 입력할 때 글자조합이나 커서이동 처리가 모두 제각각이라 꿈꾸기 쉽지 않은 길일텐데... 아무튼 그 길로 갔다. 윈도 시스템과 찰떡처럼 결합된 VCL은 그냥 윈도 전용으로 남겨두고 멀티플랫폼은 아예 새로 만든 파이어몽키를 기반으로 함으로서 기존 델파이 개발자는 자신에게 익숙한 환경에서 만든 제품을 다른 OS에서도 동일한 UX로 제공하는 것이 가능해졌다. 

물론 첫 버전인만큼 기대만큼의 완성도에는 미치지 않는다. 윈도에서 IME 조합문자 표시는 베타10에 와서야 구현되었고 그나마 경계부분 커서 처리나 일본 IME에서의 조합중 커서이동 미구현, 생뚱맞은 후보창 위치 등 아직은 오류투성이이다. 거기에 아랍어, 태국어등 출력조합 문자열에서의 커서 처리도 VGScene 시절의 문제가 그대로 남아있다. 하지만 생각해보라. 이 문제들이 영원히 해결되지 않을까? 허접 프로그래머인 나조차도 윈도 3D 환경에서 다국어처리에 몇 달 안걸렸는데... (그것도 업무 외 시간에 아들놈 피해 도서관과 게임방을 전전하면서...)

출력은 이미 쓸만한 수준이고 입력마저 깔끔해진다면... 게다가 이 UX가 모든 OS에서 보장된다면... 어떤 세상이 열릴까... 
파이어몽키에 대한 PT 첫머리에 "파이어몽키는 게임엔진이 아니다" 라고 했지만, 이 물건이야말로 게임 UI 엔진에 목마른 많은 게임 개발자들에게 복음이 될 수 있다. XE2 프로버전의 경우 요즘 각광받는 스케일폼의 1/10 정도의 가격이 될 것이며 IDE에서 직접 컨트롤을 배치하고 무엇보다 액션스크립트가 아닌 C++, 또는 파스칼로 구동코드를 만들 수 있기 때문이다. 어디 게임 뿐일까. 플래시를 능가하는 RIA에 빠른 실행속도. 지하철 천정에 매달려 열차 도착을 알리는 윈도 XP들이 자유 운영체제인 리눅스로 바뀔 날도 멀지 않은 듯 하다. 


일단 내 감상문은 여기까지. 
XE2의 다른 기능들에 대해서는 솔직히 남에게 떠들만큼 알지도 못하고 쓸 일도 별로 없으니 출시 이후 쏟아질 리뷰들을 기대하자.
그나저나... 파이어몽키같은 물건이 일반화되면... 메시지 갈구리질이나 문자출력 API 걷어내는 기법은 박물관에나 가야겠군~~ 
 

xmlrpc-epi 로 만든 RPC 서버에서 압축전송된 요청 다루기

탐구생활/WEB 관련
델파이와 PHP 에서 XLMRPC 를 가지고 노는 이야기는 오래전에 위키에 끄적인 적이 있는데... 지금은 날아가버렸다. 
백업된 문서 찾아다 블로그에 정리해야겠다. (... 고 생각한지 벌써 일년이 훌쩍... ㅠㅠ) 

xmlrpc-epi 는 예전에 살펴본 php-xmlrpc 와 기능면에서 거의 같으면서도 C로 만들어진 확장이라 속도가 좀 더 빠르다. 
사용법도 비슷해서 include("xmlrpc.inc"); 를 include("xmlrpc_emu.inc"); 라고 끝에 "_emu" 만 붙여주면 된다. 
무엇보다 대부분의 PHP 배포판에 기본적으로 포함되어있다는 것이 장점이다. 심지어는 시놀로지의 NAS에도 들어있다. 
게다가 나는 팔랑귀이므로 뭐가 조금이라도 좋다고 하면 써봐야 직성이 풀린다. 

 다만 무슨 일인지 우분투 10.04에서는 빠져있는데, 아래와 같이 설치하고 아파치를 재구동하면 올라온다.  (예전에는 들어 있었는데...)

sudo apt-get install php5-xmlrpc



WAMP 에서는 트레이를 클릭하고 PHP -> PHP Extensions -> php_xmlrpc 확장을 선택하면 된다. 





xmlrpc

core library version xmlrpc-epi v. 0.51
php extension version 0.51
author Dan Libby
homepage http://xmlrpc-epi.sourceforge.net
open sourced by Epinions.com



http://xmlrpc-epi.sourceforge.net/ 에서 xmlrpc-epi-php-0.51.tar.gz 를 다운받아 압축을 풀고 util 디렉토리를 include 경로에 포함시키면 사용준비는 완료. 


 

PHP+MySQL+xmlrpc-epi 로 만든 XMLRPC 기반의 데이터 서버와 델파이로 정보를 주고 받는 중인데, DB값의 특성상 키와 값으로 쌍을 이루는 "구조체" 형식을 선호하다 보니 전송 데이터가 상당히 커지게 되었고, 이거 필드에서 제대로 써먹을 수 있을지 슬쩍 겁이나기 시작했다. 

일단 받는 정보부터 압축해보자. PHP.INI 를 다음과 같이 설정하고
 

zlib.output_compression = on
zlib.output_compression_level = 9 



zlib
........

DirectiveLocal ValueMaster Value
zlib.output_compression On On
zlib.output_compression_level 9 9
zlib.output_handler no value no value



RPC 함수 호출시 HTTP 헤더의  Accept-encoding 에 "gzip,deflate" 라고 적어주면 gzip으로 압축된 정보가 날아온다. deflate로 날아온 정보는 ZLib로 바로 풀리고 gzip의 경우는 
DelphiZLib 의 ZLibExGZ 유니트를 사용하면 되므로 일단 한 숨 돌렸는데...
저장하기 위해 서버로 보낼 정보도 만만치 않게 크기 때문에 마찬가지로 압축을 해주기로 하면서 고민이 시작된다.



HTTP 헤더의 Content-Encoding 에 deflate, 또는 gzip 을 적어주고 XML을 압축한 뒤 서버를 호출하니 다음과 같은 에러가 나온다. 

32700: parse error. not well formed. 
error occurred at line 1, column 1, byte index 0



데이터가 요사스러워 첫줄 첫번째 컬럼 제일 앞바이트부터 에러가 난다고 툴툴거리고 있다.
저 에러는 C확장 내부에서 내는 것으로서 한마디로 압축된 그대로 넘겨받았다는 이야기. 


흠... 설정에 output_xxx 만 있을 때 부터 알아봤어야 하는데... 들어오는 정보는 직접 풀어줘야하나보다. 


서버 객체가 정의된 xmlrpcs_emu.inc 파일의 177 라인을 살펴보니 전달된 HTTP_RAW_POST_DATA 를 날것 그대로 던져주고 있다. 
여기에 클라에서 전달받은 Content-encoding 값으로 압축여부를 판단해 압축을 풀어주는 코드를 추가해보자. 

    // public. service the xmlrpc request
    function service() {
       Header("Content-type: text/xml; Content-length: " . strlen($payload));
 
       global $HTTP_RAW_POST_DATA;
       $data=$HTTP_RAW_POST_DATA;
 

      // 데이터가 압축되어있는지 살핀다. 압축되어있다면 풀자. 
         if(isset($_SERVER['HTTP_CONTENT_ENCODING']))
             $content_encoding = str_replace('x-', '', $_SERVER['HTTP_CONTENT_ENCODING']);
         else
             $content_encoding = '';
 
         if ($content_encoding == 'gzip' && function_exists('gzinflate') && $degzdata = @gzinflate(substr($data, 10))) {
             //echo 'GZip decompress!';
             $data = $degzdata;
         } else
         if ($content_encoding == 'deflate' && function_exists('gzuncompress') && $degzdata = @gzuncompress($data)) {
             //echo 'Deflate decompress!';
             $data = $degzdata;
         }



        // call server
       echo xmlrpc_server_call_method($this->xmlrpc_server, $data, $this->dmap, 
                                      array(output_type => "xml", version => "xmlrpc", encoding => "UTF-8"));
    }



녹색으로 둘러친 부분이 추가한 내용이다. 이제 함수호출 정보를 gzip, 또는 deflate 로 압축해 던져도 제대로 반응하게 된다.  

XML은 텍스트로 된 정보이므로 압축률이 높다. 크기가 커질수록 효율은 더욱 좋아진다.
3천바이트 가량의 XML이 1/5인 600바이트 정도로 줄어들어 왔다갔다 하는 것을 보면 답답했던 속이 뻥~ 뚫릴 것이다. 



ps. php-xmlrpc 에는 압축 전송된 요청을 풀어주는 코드가 이미 들어있다.
     따라서 이 고민은 "똑같은 PHP에서 XMLRPC 사용인데 xmlrpc-epi 는 왜 안되는거야!!" 하는 사람에게만 유효하다. 



GNU Gettext for Delphi and C++ Builder

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

친구 부탁으로 진행했던 3D 맛보기 세미나.

탐구생활/Delphi
3D란 무엇인가. 행렬과 벡터. 예제 살펴보기라는 세가지 단락으로 한시간 정도 정신없이 떠들었음. 
환경은 델파이와 OpenGL. 

다른 인간 부탁이었으면  생깠을텐데 항상 고마운 친구라... 사실 이런건 준비하는 사람에게 더 도움이 되는 일이기도 하고... 
강사자질도 없는 버벅 버벅 대왕이라 오히려 악의 구렁텅이로 이끈 건 아닌지 걱정... 
진행했던 세미나 중 유일하게 한시간을 넘김. (최단기록은 논문발표... 7분...)

전반부는 말로 때우고, 후반부는 예제의 주석을 풀어가며 기능을 설명하는 방식으로  진행했음. 


발표에 사용한 ppt 파일과 델파이로 만든 예제를 묶어서 올려 둠. 
  

2011.4.23.세미나.zip