2013/02/04 - [ActionScript] - as2용 Dictionary 클래스 만들기 - 0


2013/02/07 - [ActionScript] - as2용 Dictionary 클래스 만들기 - 1




1. 기존 코드의 문제점



두개 이상의 Dictionary 에서 같은 객체를 참조하면 문제가 발생한다고 말했습니다.


객체 안에 고유한 인덱싱 값을 넣어서 활용하게 되는데, 그건 하나의 Dictionary 안에서만 고유하기 때문입니다.



그렇기 때문에 지금부터 할 일은 전체 VM 상에서 고유하게 만드는 일입니다.



방법은?


물론 당연히 static 명령어를 이용해서 처리할 수 있습니다.


자, 코드를 보시죠



dynamic class com.minarto.utils.Dictionary {
	private static var __count:Number = 0;
	
	
	public function Dictionary() {
		var id:Number = ++ __count;
		
		var c:Number = 0;
		
		this.__proto__.setValue = function($target, $value):Void {
			if ($target) {
				var dic = $target.__dictionary__ || ($target.__dictionary__ = { } );
				dic[id] || (dic[id] = ++ c);
				this[dic[id]] = $value;
			}
		};
		
		
		this.__proto__.getValue = function($target) {
			if ($target) {
				var dic = $target.__dictionary__;
				return	dic ? this[dic[id]] : dic;
			}
			return	$target;
		};
	}
	
	
	public function setValue($target, $value):Void {}
	
	
	public function getValue($target) {}
}




2.  고유한 인덱싱을 가지는 Dictionary



위의 코드에서 생성자 함수의 구현부를 보겠습니다.


private static var __count:Number = 0;
	
public function Dictionary() {
	var id:Number = ++ __count;
		
	var c:Number = 0;
		
	this.__proto__.setValue = function($target, $value):Void {
		if ($target) {
			var dic = $target.__dictionary__ || ($target.__dictionary__ = { } );
			dic[id] || (dic[id] = ++ c);
			this[dic[id]] = $value;
		}
	};
}



기존에는 참조할 각 객체의 고유함을 가지게 하기 위해서 c라는 클로저 변수를 사용했다면 이번에는 Dictionary 객체에도 그 방법을 적용한 겁니다.


그 다음에는 참조할 객체 안에 해시맵을 만듭니다.


해시맵 안에서 사용할 키값이 바로 Dictionary 의 id가 됩니다.


그 id로서 c 값을 가져오게 되고 그 값으로 Dictionary 의 키값으로 사용되어서 $value 값을 저장하게 되는 뭐 그런거죠...




3. 최적화를 해보자



setValue 함수를 이해했다면 굳이 getValue 함수는 설명이 필요 없을 듯 합니다.


getValue 함수 구현부 설명은 그럼 넘어가기로 하고, 최적화를 해보겠습니다.



Dictionary 클래스를 만들었으니 사용하려면 new 연산자로서 Dictionary 객체를 만들고선, 사용을 해야 합니다.



하지만 new 라는 연산자는 성능을 떨어뜨리는 녀석입니다.



다음의 최종 코드를 보겠습니다.



dynamic class com.minarto.utils.Dictionary {
	private static var __count:Number = 0;
	
	
	public function Dictionary() {
		create(this);
	}
	
	
	public function setValue($target, $value):Void {}
	
	
	public function getValue($target) {}
	
	
	public static function create($dic) {
		$dic || ($dic = {});
		
		var id:Number = ++ __count;
		
		var c:Number = 0;
		
		$dic.setValue = function($target, $value):Void {
			if ($target) {
				var dic = $target.__dictionary__ || ($target.__dictionary__ = { } );
				dic[id] || (dic[id] = ++ c);
				this[dic[id]] = $value;
			}
		};
		
		
		$dic.getValue = function($target) {
			if ($target) {
				var dic = $target.__dictionary__;
				return	dic ? this[dic[id]] : dic;
			}
			return	$target;
		};
		
		return	$dic;
	}
}



create 함수를 보시면 됩니다.


setValue, getValue 함수는 이미 설명을 했고, Dictionary 객체를 생성하는 부분을 보면 됩니다.


정확히는 Dictionary 객체가 아니지요...


	$dic || ($dic = {});

그냥 리터럴로 오브젝트를 만들어 버립니다. (편의를 위해 Dictionary 로 사용할 객체를 받을 수도 있도록 만들었습니다)


거기다가 바로 함수를 붙여버리죠...


단 이렇게 만들면, 코드 힌트를 포기해야 할 수도 있다는걸 기억하시기 바랍니다...


하지만 뭐 사용할 코드래봤자, setValue 와 getValue 가 전부라...

(사실 Dictionary 클래스 내의 비어있는 setValue / getValue 함수도 코드 힌트를 위해 남겨둔 거라고 보시면 됩니다)





다시 Dictionary 의 생성자 함수 구현부를 보면 create 함수에 자기 자신을 인자로 던져서 Dictionary 객체가 동작하도록 만든걸 보실 수 있을 겁니다.






4. 마치며...



이로서 as2용 Dictionary 클래스 만들기를 마칩니다.


포스팅으로도 코드를 올렸지만 다음 링크에 있는 구글 코드로 가시면 직접 확인하실 수 있습니다.



http://code.google.com/p/minarto-scaleform4/source/browse/trunk/as2/src/com/minarto/utils/Dictionary.as



첫번째 포스팅에서도 언급했었지만, 사실 이 포스팅은 Dictionary 에 초첨을 맞췄다기 보다는 플래시의 클로저와 객체 생성 프로세서에 관한 글이였다고 할 수 있습니다.




다음에는 무슨 글을 써야 하나...



Posted by 미나토

댓글을 달아 주세요