scaleform.minarto.com

스케일폼 프로그래밍에 있어서의 동기 / 비동기화 문제 본문

Core

스케일폼 프로그래밍에 있어서의 동기 / 비동기화 문제

미나토 2011. 11. 25. 16:27


오랜만의 다시 스케일폼 관련 포스팅이네요...

몇일전 스켈폼이 비전엔진과의 통합을 발표했습니다. 유니티도 한참 통합을 하고 있고요..(라이센스 방식은 어찌 될지 모르겠습니다)
겜회사에서의 일자리는 점점 더 넓어지는 가운데 도움되는 글이길 바라며...



1. 형 변환

아시다시피 as2에서는 new DisplayObject 로 DisplayObject 가 객체로 생성이 되질 않고, 아시다시피 다음과 같이 해야합니다

var instance:Class = Class(attachMovie(linkage id:String, instance name:String, instance depth:Number));

attachMovie 의 리턴값이 무비클립이기 때문에 해당 Class로 형변환을 해줘야만 해당 Class 의 api를 사용할 수 있습니다. 뭐, 당연한 이야기인데요... 


as2에 있어서는 저 instance의 값이 null 이 되는 경우가 많습니다. 그럼 런타임에서 에러가 속출하게 되죠... null 객체의 api를 접근하게 되니까요...


이유는 형변환이 바로 바로 이루어지지 않기 때문입니다.
as2의 기본 데이터형과 그에 따른 api 이외에는 바로 바로 동기화되어 형변환이 이루어지지 않습니다.

요컨데 MovieClip는 바로 쓸 수 있지만 MovieClip를 상속받은 A란 Class 를 만들면, 객체가 null 로 떨어지는 경우가 자주 발생한다는 뜻입니다.


이것이 늘 그런 것이라면 또 어떻게 처리를 해볼텐데 좀 지 멋대로(?) 이루어집니다.


이를 피하기(정확히는 조금이라도 예방하기 위해서는) 위해서는...

첫째, 형변환을 최대한 늦추는 방법이 있습니다.

var _mc:MovieClip = attachMovie(linkage id:String, instance name:String, instance depth:Number);
_mc._x = 100; 
_mc._y = 100; 
var mc:A = A(_mc);

뭐, 이런 겁니다... 기본 MovieClip 의 api로 값을 넣을 것은 최대한 미리 구문을 작성해놓고 나중에 형변환을 하면 위와 같은 현상을 최대한 줄일 수 있게 됩니다.
(플래시의 기본 api는 바로바로 접근 가능합니다)



둘째, 깊은 자식관계를 가지지 않게 컨테이너 구조를 가져가야 합니다.

as3 의 DisplayObjectContainer 형태로 계속해서 깊은 자식 관계를 가지게 되면 자식이 되면 될 수록(?) 형변환의 동기화가 잘 이루어지질 않습니다.
최대한 슬림하게(?)만드는 지혜가 필요합니다



셋째, 객체의 onLoad시에 해당 api를 이용할 수 있도록 프레임웍을 작성한다...

as2에서는 onLoad시가 되어야 상속받은 클래스의 api를 제대로 활용할 수 있습니다. 그렇기 때문에 아예 프레임웍을 프록시화하여 만들어버리면 위와 같은 일이 안생기겠죠...

프로그래밍은 어떻게든 할 수 있겠으나  이게 만만치가 않습니다.

스케일폼 작업시에 자주 쓰이는 런타임 공유 방식의 작업 스타일 때문인데, 런타임공유는 개발자가 직접 컨트럴 할 수가 없습니다. 언제 로드가 완료되고 어떤 놈을 먼저 부를지를 컨트럴하기가 쉽지가 않습니다.


저도 이부분을 프레임웍으로 해결해서 쓰려고 하다가 곧 스케일폼4.0으로 갈아타야 해서 굳이 작성을 하지 않았습니다.



2. c / c++ 과의 통신

c는 당연히 스케일폼보다 빠릅니다.

그런데, 만약 게임엔진에서 스케일폼으로 n개의 DisplayObject를 지우고 새로운 n개의 DisplayObject를 생성하라는 명령을 날렸다고 쳐보죠...

바로 문제가 생길 가능성이 있습니다.

새로운 n개의 DisplayObject 를 생성하라는 명령을 받는 순간까지 앞선 명령이었던 DisplayObject 삭제 명령을 처리하지 못했기 때문입니다.


이른 처리하려면 다음과 같이 해야합니다.

첫째, 데이터 모델을 따로 만들고 DisplayObject 객체에 명령을 직접 날리지 않게 한다

위의 방법이 동기화가 안일어나는건 DisplayObject 목록 갱신이 느리기 때문이므로 데이터 모델에서는 지워지고 생성되는 것을 처리하고 추후에 스켈폼에서 삭제/생성을 처리하는 방법입니다.


둘째, 명령을 두번이상 연속해서 받는 경우를 줄일 것

지우고 생성하는 명령이 포함된 통신 api를 하나 더 만들어 하나의 명령어로 처리하게 하는 방법입니다. 결국 한번의 명령이 들어오는 것이니가요...


셋째, 지우기 보다는 visble = false를 하는 방법

플래시 개발자에게는 꽁수로 보일 수 있겠지만, removeMovieclip보다 속도가 빠르기 때문에, 동기화 문제가 아니여도 스켈폼 개발시에 자주 쓰게 됩니다.
as2에서는 오브젝트풀링을 하기 힘들기 때문에 객체 재활용을 위해서 쓸 수도 있는 방법입니다.




3. 줄이며...

제가 아직 udk통합버전을 사용하고 있기 때문에, as3를 지원하는 scaleform4를 사용하면 조금 더 나은 개발환경을 제공하게 될지도 모릅니다만 스켈폼을 하다보면 뭐랄까... 난 분명히 as로 개발을 하고 있는데 플래시가 아닌 느낌이 듭니다.


히카님의 표현을 빌리자면, 언어적인 쎈스가 다릅니다. (꼭 이부분 때문에 말한건 아닙니다만...)


플래시 개발자들은 웹앱을 만들 때의 방식으로만 스켈폼을 개발하려고 한다면 분명 힘든 점이 많이 생길겁니다. 분명 as를 잘 하는 사람이 잘 만들 수는 있으나, 어느정도의 노하우가 필요하다는 걸 말씀드리고 싶네요