scaleform.minarto.com

직접 Event Model 을 만들어보자 - 0 본문

Core

직접 Event Model 을 만들어보자 - 0

미나토 2013. 4. 8. 12:40



scaleform 의 as2용 CLIK 은 as3의 이벤트 모델을 가져다 쓰고 있습니다.


정확히는 오토데스크에서 (혹은 CLIK 을 만든 gs스키너 그룹에서) 완전히 직접 만들었다고 보기는 힘듭니다.


이미 flex 1 시절부터 Component 들이 있었고 비슷한 방법으로 구현을 했었거든요.



오히려 제가 봤을 땐, CLIK은 좀 복잡하고 비효율적으로 구현한 편입니다.



CLIK 의 EventDispatcher 클래스를 보겠습니다



	public static function initialize(target:Object):Void {
		if (_instance == undefined) { _instance = new EventDispatcher(); }
		target.dispatchEvent = _instance.dispatchEvent;
		target.dispatchQueue = _instance.dispatchQueue;
		target.hasEventListener = _instance.hasEventListener;
		target.addEventListener = _instance.addEventListener;
		target.removeEventListener = _instance.removeEventListener;
		target.removeAllEventListeners = _instance.removeAllEventListeners;
		target.cleanUpEvents = _instance.cleanUpEvents;
		_global.ASSetPropFlags(target, "dispatchQueue", 1);
	}

initialize 함수만 일단 살펴보죠...


일단 EventDispatcher 객체를 하나 생성을 해서 거기에 연결된 함수를 타겟에 연결하는군요...


그냥 prototype 을 써도 될텐데 말이죠...


그리고 왜 이렇게 함수는 많나요...


dispatchEvent, hasEventListener, addEventListener, removeEventListener 정도만 있으면 되는거 아닌가요...



뭐 물론 그들이 만들어놓은 VM은 독자적인 것이니 혹시 저런 식으로 코딩을 해야만 빨리질 지도 모르죠...


하지만 그냥 as2 문법적으로만 본다면 이상한게 사실입니다.



제가 만든 코드를 보시죠...


원본 코드는 여기에 있습니다


https://code.google.com/p/minarto-scaleform4/source/browse/trunk/as2/src/com/minarto/events/EventDispatcher.as




class com.minarto.events.EventDispatcher {
	public static function initialize($target):Void {
		$target.__events__ = { };
		_global.ASSetPropFlags($target, "__events__", 1);
		$target.dispatchEvent = EventDispatcher.prototype.dispatchEvent;
		$target.hasEventListener = EventDispatcher.prototype.hasEventListener;
		$target.addEventListener = EventDispatcher.prototype.addEventListener;
		$target.removeEventListener = EventDispatcher.prototype.removeEventListener;
	}
	
	
	private var __events__ = { };
	
	
	public function hasEventListener($type:String):Boolean {
		return	__events__[$type];
	}
	
	
	public function addEventListener($type:String, $handler:Function, $scope):Void {
		var listeners:Array, i, arg;
		
		if (!$type || !$handler)	return;
		
		listeners = __events__[$type];
		for (i in listeners) {
			arg = listeners[i];
			if ($handler === arg[1] && $scope === arg[2]) {
				return;
			}
		}
		if (!listeners) {
			listeners = [];
			__events__[$type] = listeners;
		}
		
		listeners.push(arguments);
	}
	
	
	public function removeEventListener($type:String, $handler:Function, $scope):Void {
		var listeners:Array, i, arg;
		
		if ($type) {
			if ($handler) {
				listeners = __events__[$type];
				for (i in listeners) {
					arg = listeners[i];
					if ($handler === arg[1] && $scope === arg[2]) {
						listeners.splice(i, 1);
						if (!listeners.length) {
							delete	__events__[$type];
						}
						return;
					}
				}
			}
			else {
				delete	__events__[$type];
			}
		}
		else {
			__events__ = { };
		}
	}
	
	
	public function dispatchEvent($e):Void {
		var listeners:Array, i:Number, c:Number, arg;
		
		if (!$e)	return;
		
		$e.target || ($e.target = this);
		
		listeners = __events__[$e.type];
		c = listeners ? listeners.length : 0;
		for (i = 0; i < c; ++ i) {
			arg = listeners[i];
			arg[1].call(arg[2], $e);
		}
	}
}




일단 오늘은 코드만 보이겠습니다. 설명은 다음 포스팅에...