scaleform.minarto.com

Binding reboot - 1 본문

Communication

Binding reboot - 1

미나토 2013. 6. 13. 12:19


2013/06/11 - [Communication] - Binding reboot - 0





0. public static function set($key:String, $value:*):void



	
public static function set($key:String, $value:*):void {
	var a:Array, i:Number, l:Number, item:*, arg:Array;
	if($value == valueDic[$key])	return;
			
	valueDic[$key] = $value;
			
	a = bindingDic[$key];
	for (i = 0, l = a ? a.length : 0; i < l; ++ i) {
		item = a[i];
		arg = item.arg;
		arg[0] = $value;
		item.handler.apply(null, arg);
	}
}



set 은 주로 클라이언트가 사용하는 함수입니다.


서로 약속한 $key 값에 해당하는 값을 던져주죠...

클라이언트는 init 함수를 통해서 함수포인터는 얻었을 것이기 때문에 사용 방법이야 인보크 함수 사용하듯 하면 됩니다.


일단 


if($value == valueDic[$key])	return;


이 과정을 통해서 기존 값과 같다면 실행하지 않아서 성능 향상을 꾀합니다.


그리고 그 다음 구문은 당연히 바인딩 되어있는 함수들을 찾아서 차례대로 실행해 줍니다. 좀 더 성능을 꾀한다면 for in 문으로 돌릴 수도 있을 겁니다. 바인딩을 건 순서가 중요하지 않다면 말이죠...



그것 이외에 set 함수를 분석할 것은 없지만 이 set 함수가 다른 일반적인 인보크 함수의 용도와 다른 것은 이 set 함수는 UI 개발자도 자유롭게 사용할 수 있다는 겁니다



init 에 의해 클라이언트는 root.setValue 를 사용하겠지만, UI 개발자 또한 Binding.set 함수를 사용해서 얼마든지 해당 값을 넣어볼 수 있는 것이죠...



이런 방식은 런타임 디버깅에도 사용됩니다.


$key 값을 넣는 텍스트 필드와 $value 값을 넣는 텍스트 필드 두개로 이루어진 UI를 하나 만든다고 해보죠... 실행 버튼으로는 Number 란 이름을 가진 버튼과 String 란 이름을 가진 버튼을 만들어놓죠.


두 값을 넣은 다음 Number 란 버튼을 클릭하면 $value 텍스트필드의 text 값이 Number 타입으로 형변환 해서 Binding.set 되는 겁니다


String 버튼은 형변환 필요없이 되겠죠.



클라이언트가 아무런 작업을 하지 않아도 게임상에 띄워서 테스트해볼 수 있는 환경이 만들어지는 겁니다.



테스트 UI만 로드하지 않는다면 아무 코드도 수정하지 않고선 그대로 적용도 가능합니다.





1. public static function has($key:String, $handler:Function):Boolean


public static function has($key:String, $handler:Function):Boolean {
	var a:Array = bindingDic[$key];
	
	for ($key in a) if (a[$key].handler == $handler) return	true;
	return	false;
}



has 함수는 너무 간단해서 볼 것도 없네요.


바인딩이 걸려있는지 확인하는 함수입니다.


그냥 hasEventListener 의 습관이 남아서 만들긴 했는데... 사실 그다지 필요는 없는 함수이기 때문에 삭제해도 무방합니다 :^)




2. public static function add($key:String, $handler:Function, ...$args):void


public static function add($key:String, $handler:Function, ...$args):void {
	var a:Array = bindingDic[$key], i:*, item:*;
			
	$args.unshift(get($key));
			
	if(a){
		for (i in a){
			item = a[i];
			if (item.handler == $handler){
				item.arg = $args;
				return;
			}
		}
		item = {handler:$handler, arg:$args};
		a.push(item);
	}
	else{
		item = {handler:$handler, arg:$args};
		bindingDic[$key] = a = [item];
	}
}


add 함수는 바인딩을 거는 함수입니다.


CLIK 을 사용하신다면 아마도 UIComponent 의 configUI 함수에 등록을 할 겁니다



하지만 바인딩을 걸기만 해서는 아무런 변화가 없죠. 새로운 값이 들어오는 순간에만 바인딩 되기 때문입니다.


이런 식으로 해야겠지요.



import com.minarto.data.Binding;
var setValue:Function;
 
Binding.init(this);
Binding.set("kkk", 1111);

function f($v):void{
    trace($v)
}

f(Binding.get("kkk"));
Binding.add("kkk", f);


이런 식으로 Binding.get 함수를 통해 한번 실행해주고선 사용하면 UI가 로드됨과 동시에 실행이 한번 되겠죠.


이 방식이 불편하다면 다른 함수를 하나 만들어서 자동화 해도 될 것입니다.


public static function addNPlay($key:String, $handler:Function, ...$args):void {
	var a:Array = bindingDic[$key], i:*, item:*;
			
	$args.unshift(get($key));
			
	if(a){
		for (i in a){
			item = a[i];
			if (item.handler == $handler){
				item.arg = $args;
				return;
			}
		}
		item = {handler:$handler, arg:$args};
		a.push(item);
	}
	else{
		item = {handler:$handler, arg:$args};
		bindingDic[$key] = a = [item];
	}
			
	$handler.apply(null, $args);
}


이런 식으로 말이죠...




그리고 $args 인자를 통해서 추가 인자도 넣을 수 있도록 해놨습니다.



import com.minarto.data.Binding;
var setValue:Function;
 
Binding.init(this);
 
function f(...$v):void{
    trace($v)
}
Binding.add("kkk", f, 1,2,3,4);
 
 
Binding.set("kkk", 1111);
setValue("kkk", 2222);



//////////////////

1111,1,2,3,4

2222,1,2,3,4

////////////////////


사용하면 이렇게 결과가 나오는 것이죠.



del 함수부터는 다음 포스팅에...