오브제트 풀은 많은 수의 객체를 효과적으로 관리 할 수 있게 도와주는 솔루션 입니다. 아주 간단하게 설명 하면 프로세스는 다음과 같습니다.
- 오브젝트가 필요하면 풀에 오브젝트를 요청 한다.
- 사용가능 한 오브젝트가 있으면 오브젝트를 넘겨준다.
- 없다면 새로 만들어서 넘겨준다.
- 사용이 끝난 오브젝트는 다시 사용 할 수 있도록 풀에 반환한다.
- 1~4 과정을 반복한다.
이러한 오브젝트 풀을 사용함으로서 얻을 수 있는 장점은 지속적으로 발생하는 new 비용을 줄일 수 있고 이미 만들어 놓은 객체를 반환하므로 매우 빠르게 오브젝트를 재사용 할 수 있게 됩니다. 가장 흔하게 사용되는 예가 슈팅게임의 미사일이나 적 오브젝트들을 들 수 있습니다. 더 자세한 내용은 지돌스타님의 블로그에 자세히 설명 되어 있으니 방문해 보시기 바랍니다.
the HYPE framework
HYPE 프레임웍은 죠슈아 데이빗 형님이 만든 비쥬얼 프레임웍 입니다. 플래시를 이용해 멋지고 화려한 비쥬얼 효과를 쉽고 빠르게 만들 수 있도록 도와줍니다.
HYPE 프레임웍에는 유용한 클래스들이 많이 있는데 ObjectPool 클래스도 그 중 하나입니다. 본래 HYPE 의 ObjectPool 은 HYPE 프레임웍을 위해 만들어지기는 했으나 어차피 오브젝트 풀이라는게 오브젝트만 관리 할 수 있으면 되는 것 이므로 다른 여러 프로그램에서도 응용 할 수 있습니다.
위에 있는 예제 플래시는 2년전에 만든 연못으로 물 속의 물고기들이 바로 이 오브젝트 풀을 사용 하고 있습니다. 소스 부분을 보면서 어떤식으로 사용되는지 보도록 하겠습니다.
import hype.framework.core.ObjectPool; import hype.framework.core.TimeType; import hype.framework.rhythm.SimpleRhythm; var _redFishPool:ObjectPool = new ObjectPool([ RedFish ], 20); _redFishPool.onRequestObject = function(clip:ObjectLoader):void { clip.addEventListener(Event.COMPLETE, onCompleteRedFish) clip.load(); } function onCompleteRedFish(event:Event):void { var clip:ObjectLoader = event.currentTarget as ObjectLoader; // exit callback function, target Object, shape, shapeFlag var onExit:ExitView3DTrigger = new ExitView3DTrigger(onExitRedFish, clip, _view, true); onExit.start(); addChild(clip); } var rhythm:SimpleRhythm = new SimpleRhythm(addNextClip); rhythm.start(TimeType.TIME, 1); function addNextClip(r:SimpleRhythm):void { _redFishPool.request(); }
위 소스는 원 소스에서 오브젝트 풀에 관련된 부분은 가져왔습니다.
var _redFishPool:ObjectPool = new ObjectPool([ RedFish ], 20); _redFishPool.onRequestObject = function(clip:ObjectLoader):void { clip.addEventListener(Event.COMPLETE, onCompleteRedFish) clip.load(); }
RedFish 클래스의 객체를 20개 까지 만들어주는 오브젝트 풀을 생성 합니다. onRequestObject 는 함수는 오브젝트 풀에 요청이 들어올때 실행되는 콜백 함수 입니다. 해당 함수의 인자인 clip 은 요청에 의해 생성된 RedFish 의 객체 입니다. 예제의 ObjectLoader 는 RedFish 의 부모 클래스입니다. 해당객체가 생성된 후 초기화를 하기 위해서 onCompleteRedFish 핸들러를 사용 했습니다.
function onCompleteRedFish(event:Event):void { var clip:ObjectLoader = event.currentTarget as ObjectLoader; // // clip 초기화 // // 반환 트리거 등록 var onExit:ExitView3DTrigger = new ExitView3DTrigger(onExitRedFish, clip, _view, true); onExit.start(); addChild(clip); }
객체가 생성되면 위치나 크기등을 초기화 하고 반환 트리거를 등록 합니다. 이 트리커는 특정 상황이 되면 해당 객체를 풀로 반환 하도록 합니다. 물고기가 화면 밖으로 사라지는 것을 감지해서 트리거를 실행 시킵니다.
여기 까지가 기본적인 오브젝트 풀의 모습입니다. 이제 RedFish 의 오브젝트 풀인 _redFishPool 에 객체를 요청하기만 하면 됩니다. 저는 1초에 한마리씩 화면에 나오도록 설정 했습니다. 이를 위해 HYPE는 매우 유용한 클래스를 제공 합니다.
var rhythm:SimpleRhythm = new SimpleRhythm(addNextClip); rhythm.start(TimeType.TIME, 1); function addNextClip(r:SimpleRhythm):void { _redFishPool.request(); }
HYPE 프레임웍이 제공하는 SimpleRhythm 을 이용하면 이 처럼 간단하게 설정을 마칠 수 있습니다.
Conclusion
오브젝트 풀은 불필요한 객체 생성을 줄이고 효율적인 메모리 관리와 좀 더 나은 성능을 만들어 줍니다. HYPE 프레임웍은 이런 오브젝트 풀을 매우 손쉽게 사용 할 수 있도록 만들어 줍니다. HYPE 와 Starling 을 섞어서 슈팅게임을 만들 수도 있겠지요. 이 처럼 다양한 프레임웍을 믹스 해서 사용 하는 것도 작업을 더 튼튼하고 재미난게 만들어 주네요.
p.s. 디버그 플레이어에선 마우스 입력이 안되네요;;;