<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
   <channel>
      <title>dieBuster RSS</title>
      <description>Pipes Output</description>
      <link>http://pipes.yahoo.com/pipes/pipe.info?_id=cba0b68269a9dc3085c07a2c0232e733</link>
      <atom:link rel="next" href="http://pipes.yahoo.com/pipes/pipe.run?_id=cba0b68269a9dc3085c07a2c0232e733&amp;_render=rss&amp;page=2" />
      <pubDate>Fri, 24 Feb 2012 09:38:22 +0000</pubDate>
      <generator>http://pipes.yahoo.com/pipes/</generator>
      <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/DiebusterRss" /><feedburner:info uri="diebusterrss" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
         <title>BS.Pool : 객체를 풀링하기</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/gaAWIcctXFo/</link>
         <description>풀링(Pooling)이란? 전통적인 OOP 언어에서는 클래스를 바탕으로 인스턴스를 생성한 뒤 이 인스턴스에게 일을 시키게 됩니다. 헌데 new 를 통해 인스턴스의 비용은 적지 않습니다. 만약 동일한 인스턴스를 그때그때 일을 시키기 위해 생성하지 않고 한 번 생성된 인스턴스를 재활용할 수는 없을까라고 생각하여 만든게 &amp;#8230; &lt;a rel="nofollow" target="_blank" href="http://zero.diebuster.com/zero/?p=20"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">http://zero.diebuster.com/zero/?p=20</guid>
         <pubDate>Thu, 02 Feb 2012 00:28:25 +0000</pubDate>
         <content:encoded><![CDATA[<p><span id="more-20"></span></p>
<h2>풀링(Pooling)이란?</h2>
<p>전통적인 <strong>OOP</strong> 언어에서는 클래스를 바탕으로 인스턴스를 생성한 뒤 이 인스턴스에게 일을 시키게 됩니다. 헌데 <strong>new</strong> 를 통해 인스턴스의 비용은 적지 않습니다. 만약 동일한 인스턴스를 그때그때 일을 시키기 위해 생성하지 않고 한 번 생성된 인스턴스를 재활용할 수는 없을까라고 생각하여 만든게 바로 프로그래밍적인 풀링입니다. 따라서 풀링이 성립하려면 다음과 같은 조건을 만족해야 합니다.</p>
<ol>
<li>생성된 인스턴스는 적절한 초기화를 시키면 재활용할 수 있다. 즉 값 객체 등 재활용이 불가능하도록 설계되었거나 특정 역할을 수행하면 더 이상 작동할 수 없는 타입의 객체는 풀링할 수 없다.</li>
<li>풀링이 속도에 인스턴스를 인출(<strong>get</strong>)하거나 풀링으로 인스턴스를 반납(<strong>collect</strong>)이 생성(new)하는 비용보다 싸야한다.</li>
<li>풀링은 미리 갯수를 한정짓고 사용하는 고정타입과 자유롭게 늘어나는 유동타입이 있다.</li>
</ol>
<p>한 마디로 풀링이 가능해야하고 <strong>new</strong> 보단 성능 상의 잇점이 있어야 한다는 겁니다.</p>
<h2>풀에서 가져오기</h2>
<p>풀을 구현하는 방법은 정말이지 다양합니다. 하지만 이 포스트에서는 가장 간단한 형태의 유동타입풀을 구현할 예정입니다. 일단 배열인스턴스를 관리할 풀을 생성하는데, 풀 자체도 배열입니다.</p>
<pre>
var arrayPool;
arrayPool = [];
</pre>
<p>이제부터 배열 인스턴스를 저 <strong>arrayPool</strong> 에 넣었다 뺐다 하는 거죠. 우선 풀에서 인스턴스를 가져와 봅시다. 이를 <strong>arrayGet</strong> 함수를 통해 정의해보죠.</p>
<pre>
var arrayPool = [];
function arrayGet(){
	if( arrayPool.length ){
		return arrayPool.pop();
	}else{
		return [];
	}
}

var arr1 = arrayGet();
</pre>
<p>코드가 매우 간단합니다. 풀에 뭔가 있다면 그걸 하나 꺼내주고 없다면 생성하여 줍니다.<br />
최초 상태에서는 <strong>arrayPool</strong> 에 아무것도 들어있지 않으므로<br />
else 구문이 실행되어 새로운 배열을 생성하여 반환하게 됩니다.</p>
<h2>풀에게 반납하기</h2>
<p>위 예에서 생성한 <strong>arr1</strong> 을 실컷 사용하고 이제 다시 <strong>pool</strong> 에게 되돌려보내야 할 때가 되었습니다. 반납을 위해 <strong>arrayCollect</strong> 함수를 정의해 보겠습니다.</p>
<pre>
function arrayCollect( $array ){
	$array.length = 0;
	arrayPool.push( $array );
}
</pre>
<p>우선 인자로 받아온 배열은 <strong>length = 0</strong> 을 통해 초기화를 시킵니다. 그 뒤 <strong>arrayPool</strong> 에 넣어주는 것이죠.</p>
<h2>구현된 풀의 원리</h2>
<p>위에서 구현한 풀링은 <strong>arrayPool</strong> 이란 배열을 일종의 스택으로 사용하고 있습니다. 마지막에 반납한게 가장 먼저 인출되는 구조죠. 거기에 더해 만약 인출을 요청했는데 풀링에 아무것도 안남아있는 경우는 새로 생성하여 반납하게 되므로 사실 무한히 생성할 수 있는 구조입니다. 또한 반납 시에도 어떤 배열이라도 받아주기 때문에 딱히 <strong>arrayGet</strong> 을 통해 가져간 배열이 아니라도 상관없습니다. 간단히 요약하면 다음과 같이 됩니다.</p>
<ol>
<li>인출시 <strong>pop</strong>, 반납시 <strong>push</strong> 를 사용하므로 배열의 구조 상 가장 고속의 메서드를 사용하여 성능 상 잇점을 발휘한다.</li>
<li>인출될 객체의 수에 대한 제한이 없고, 반납을 반드시 시키지 않아도 무방하다.</li>
<li>미반납한 배열은 <strong>GC</strong>(가비지컬렉팅)를 통해 제거되며 이 때 풀링은 별도의 참조를 갖고 있지 않으므로 <strong>GC</strong> 를 방해하지 않는다.</li>
</ol>
<p>전체 풀의 코드를 정리하면 아래와 같습니다.</p>
<pre>
var arrayPool;

arrayPool = {

_pool: [],
$: function(){
	if( _pool.length ){
		return _pool.pop();
	}else{
		return [];
	}
},
_: function( $array ){
	$array.length = 0;
	_pool[_pool.length] = $array;
}

};

//인출
var arr1 = arrayPool.$();

//반납
arrayPool._( arr1 );
</pre>
<h2>bs.Pool</h2>
<p>기본적으로 <strong>bs.Pool</strong> 은 위에서 구현된 원리로 움직입니다만, <strong>bs.Class</strong> 를 통해 정의된 어떤 클래스에라도 간단히 <strong>Pool</strong> 기능을 추가할 수 있도록 되어있습니다. 또한 최초 인스턴스 인출 시 <strong>Pool</strong> 용 배열을 생성하도록 되어있으므로 초기화 비용을 줄여줍니다. 코드는 위의 정리된 버전과 대동소이하므로 생략합니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/gaAWIcctXFo" height="1" width="1"/>]]></content:encoded>
         <category>01. JS Base</category>
      <feedburner:origLink>http://zero.diebuster.com/zero/?p=20</feedburner:origLink></item>
      <item>
         <title>BS.d : 클로저 쓰기</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/1L2-ToWSF9g/</link>
         <description>함수의 작동 클로저란 단어는 그 이름만으로 머리를 아프게 하는 속성이 있습니다. 클로저의 설명이 복잡하고 까다로운 이유는 함수가 실행될 상황을 정확히 이해시키지 않고 무리하게 설명해서 입니다. 따라서 먼저 함수가 어떻게 작동하는지를 정확히 이해해야 합니다. 함수는 함수의 시그니처(이름, 인자 등을 선언한 곳)와 &amp;#8230; &lt;a rel="nofollow" target="_blank" href="http://zero.diebuster.com/zero/?p=19"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">http://zero.diebuster.com/zero/?p=19</guid>
         <pubDate>Wed, 01 Feb 2012 01:41:15 +0000</pubDate>
         <content:encoded><![CDATA[<p><span id="more-19"></span></p>
<h2>함수의 작동</h2>
<p>클로저란 단어는 그 이름만으로 머리를 아프게 하는 속성이 있습니다. 클로저의 설명이 복잡하고 까다로운 이유는 함수가 실행될 상황을 정확히 이해시키지 않고 무리하게 설명해서 입니다. 따라서 먼저 함수가 어떻게 작동하는지를 정확히 이해해야 합니다.</p>
<p>함수는 함수의 시그니처(이름, 인자 등을 선언한 곳)와 몸체(함수 내부의 내용)를 포함한 하나의 정의를 메모리에 생성합니다. <strong>js</strong>는 이러한 함수를 자유롭게 생성하거나 파기할 수 있습니다. 하지만 이건 함수를 생성할 때의 얘기고, 함수를 실행할 때는 다른 일이 일어납니다.</p>
<p>함수를 호출할 때마다 그 함수가 실행할 동안 사용할 메모리를 별도로 생성합니다.</p>
<p>따라서 함수를 백번 호출하면 이러한 함수 실행용 메모리도 백개 만들어집니다.<br />
각 함수의 호출이 독립적으로 실행되는 이유는 각 호출마다 사용하는 메모리가 각각이기 때문입니다.</p>
<p><strong>js</strong>는 전역에 있는 코드조차 함수가 실행 중입니다. <strong>js</strong>의 코드는 어디에서 어떻게 작성하든 무조건 어떤 함수가 실행 중인 상태에서 그 내부에 코드를 실행한다고 할 수 있습니다.<br />
함수를 생성하는 코드도 항상 어떤 함수가 실행 중인 그 내부에서 생성된 것이죠.</p>
<p>전역 함수가 실행 중이다 라는 느낌은 아래의 코드와 같이 표현할 수 있습니다.</p>
<pre>
〈script type=&quot;text/javascript&quot;&gt;
function test( $msg ){
	alert( $msg );
}
test( '안녕' );
〈/script&gt;
</pre>
<p>위의 코드는 일견 전역에 <strong>test</strong>를 생성하고 실행한다라는 느낌으로 보이시겠지만 실체는 다음에 가깝습니다.</p>
<pre>
//script의 모든 코드를 전역함수에 넣어버리고
function window(){
	function test( $msg ){
		alert( $msg );
	}
	test( '안녕' );
}

//그 전역함수를 실행한다.
window();
</pre>
<p>즉 <strong>js</strong>코드를 어디에서 작성했던 사실 <strong>js</strong>는 무조건 어떤 함수의 실행 중이라는 거죠. 이러한 관점에서 보면 <strong>test</strong>함수조차 <strong>window</strong>라는 함수가 실행되는 상태에서 생성된 것입니다.</p>
<h2>함수가 생성되는 시점</h2>
<p>앞의 예는 전역 코드도 함수 실행 중이란 점을 알려드리기 위한 의사코드라 내용을 진행하기 적당하지 않으니 다른 코드를 예시로 보겠습니다.</p>
<pre>
function running( $msg ){
	return function test(){
		alert( $msg );
	};
}

var greeting = running( '안녕' );
greeting(); //안녕
</pre>
<p>위의 코드에서 <strong>test</strong>함수가 생성되는 시점을 생각해보겠습니다.</p>
<ol>
<li>우선 <strong>test</strong>가 생성되려면 <strong>running</strong> 함수를 호출해야 합니다.</li>
<li><strong>running</strong>함수가 호출되면<strong> running</strong> 함수 실행을 위한 별도의 메모리 공간을 생성합니다.</li>
<li>이 별도의 메모리공간에 인자로 받은 값을 <strong>$msg = &#8216;안녕&#8217;;</strong> 라는 형태로 저장해둡니다. 사실 함수가 실행 시 생성되는 메모리공간은 손쉽게 <strong>{ }</strong> 라고 이해하시면 됩니다.</li>
<li>이제 <strong>test</strong>함수를 생성합니다.</li>
</ol>
<p>위의 단계에서 요점은</p>
<ol>
<li>함수가 생성될 때는 다른 함수가 실행 중이고</li>
<li>이 실행 중인 함수를 위해 별도의 실행메모리가 생성된 상태일 뿐더러,</li>
<li>그 안에 값(<strong>$msg</strong>)도 적당히 들어있다는 점입니다.</li>
</ol>
<h2>함수가 생성될 때 일어나는 일</h2>
<p>함수가 생성되는 시점에 감싸고 있는(실행 중인) 함수를 위한 별도의 메모리 공간이 있다는 사실은 이제 충분히 인지됩니다.<br />
그럼 이게 <strong>test</strong>함수가 생성되는 것과 무슨 관계가 있냐는거죠.<br />
<strong>test</strong>함수는 생성될 때 이 <strong>running</strong>함수의 실행용 메모리를 참조로 잡아버립니다. 원래 함수 호출 시 실행을 위해 잠시 메모리를 확보하여 사용된 후 파기되어야 할 메모리 공간인데, 이것을 test함수의 정의에서 참조로 잡아버립니다. 따라서 <strong>running</strong>함수의 호출이 완전히 완료된 후에도 그 메모리는 파기되지 않고 새로 생성된 <strong>test</strong>함수의 정의에 참조로 잡힙니다.<br />
따라서 <strong>test</strong>함수의 정의는 다음과 같은 느낌이 됩니다.</p>
<pre>
testDefinition = {
	...다양한 test함수의 내용

	__parent__: running함수 호출시 생성된 메모리
};
</pre>
<p>이걸 보다 구체적으로 느낌이 오게 코드로 다듬으면 아래와 같아집니다.</p>
<pre>
testDefinition = {
	인자: null,
	지역변수: null,
	내용: alert( $msg ),
	__parent__: { $msg: '안녕' }
};
</pre>
<p>이러한 <strong>test</strong>함수의 정의가 만들어진다는 관점에서 앞의 예제 코드를 다시 보죠.</p>
<pre>
function running( $msg ){
	return function test(){
		alert( $msg );
	};
}

var greeting = running( '안녕' );
greeting(); //안녕
</pre>
<p>이제와 다시 생각해보면 <strong>greeing</strong>에 할당된 <strong>test</strong>함수의 정의에는 &#8216;안녕&#8217;이라는 값을 갖는 객체가 아예 포함되어있다는걸 알 수 있습니다.<br />
따라서 마지막줄에 <strong>greeing()</strong>을 호출하면</p>
<ol>
<li><strong>test</strong>함수에 내용인 <strong>alert( $msg )</strong>를 실행하려고 하는데</li>
<li><strong>$msg</strong>를 지역변수나, 인자의 이름에서 찾아봤더니 없습니다.</li>
<li>그럼 이제 <strong>__parent__</strong>를 뒤지게 됩니다.</li>
<li><strong>__parent__</strong>를 보니 <strong>$msg</strong>라는 키가 존재하고 그 값이 &#8216;안녕&#8217;입니다.</li>
<li>따라서 <strong>alert</strong>은 &#8216;안녕&#8217;을 출력하게 됩니다.</li>
</ol>
<h2>클로저란</h2>
<p>위의 예에서 <strong>test</strong>함수 정의에 있는 <strong>__parent__</strong>에 할당된 <strong>running</strong> 실행 시 생성된 메모리공간 이라고 할 수 있습니다.<br />
즉 <strong>{ $msg : &#8216;안녕&#8217; }</strong> 에 해당됩니다. <strong>js</strong>는 함수의 코드를 실행할 때 등장하는 변수의 이름을 찾을 때 자동으로 자신의 지역변수공간에 선언된 키가 있는지 확인하고 없으면 <strong>__parent__</strong>를 검색하도록 작동합니다. 따라서 클로저를 정의하자면 아래와 같습니다.</p>
<p><strong>함수가 생성될 시점에 실행 중인 함수의 호출용 메모리 공간</strong></p>
<p>머 간단한 거죠.</p>
<h2>클로저를 사용하는 이유</h2>
<p>이미 예제를 통해 충분히 설명드린 셈인데 <strong>greeting</strong>함수는 별다른 인자없이 &#8216;안녕&#8217;을 출력합니다.</p>
<p>즉 어떤 함수를</p>
<ol>
<li>고정된 인자 값이나</li>
<li>지역 변수 값을 확정한 채 사용하고 싶을 때</li>
</ol>
<p>클로저를 사용합니다.</p>
<h2>bs.d</h2>
<p><strong>bs.d</strong>는 클로저를 처리하는 함수입니다. 가변인자로 들어온 값을 이용해 간단히 동적인 규모의 클로저를 생성하도록 되어있습니다. 우선 소스를 보겠습니다.</p>
<pre>
bs.d = function( $end/*:Function, ...param*/ )/*:Function*/{
	var arg, context;
	if( arguments.length &gt; 1 ){
		if( arguments[1] === '@' ){
			arg = arguments[2];
		}else if( arguments[1] == '@context' ){
			context = arguments[2];
			if( arguments[3] === '@' ){
				arg = arguments[4];
			}else{
				arg = this.Arg( arguments, 3 );
			}
		}else{
			arg = this.Arg( arguments, 1 );
		}
		return function(){
			if( arguments.length ){
				$end.apply( context, bs.Arg( arguments, 0, 0, arg ) );
			}else{
				$end.apply( context, arg );
			}
		};
	}else{
		return function(){
			if( arguments.length ){
				$end.apply( context, arguments );
			}else{
				$end.call( context );
			}
		};
	}
};
</pre>
<p>코드는 간단한 편이 아니라서 오히려 호스트코드로 설명을 드리는 편이 이해하기 쉽습니다.</p>
<p>1. 우선 인자로 <strong>함수, 인자1, 인자2..</strong> 스타일로 사용할 수 있습니다.</p>
<pre>
//1. 함수, 인자1, 인자2... 스타일
var greeting = bs.d( alert, '안녕' );

greeting(); //안녕
</pre>
<p>2. <strong>@context</strong>구문을 이용하면 함수가 실행 시 자동으로 반영할 컨텍스트를 넘길 수 있습니다.</p>
<pre>
//this에 정의된 msg를 출력한다.
function test(){
	alert( this.msg );
}

//msg키를 갖고 있는 객체를 생성한다.
var context = { msg:'안녕' };

bs.d( test, '@context', context ); //안녕
</pre>
<p>이 코드가 안녕을 출력하는건 내부적으로 <strong>test.call( context );</strong> 형태가 되었기 때문입니다.</p>
<p>3. <strong>@context구문과 인자를 동시에</strong> 보낼 수도 있습니다.</p>
<pre>
//this.msg와 인자를 동시출력한다.
function test( $added ){
	alert( this.msg + $added );
}

//msg키를 갖고 있는 객체를 생성한다.
var context = { msg:'안녕' };

bs.d( test, '@context', context, '!!!' ); //안녕!!!
</pre>
<h2>추가기능</h2>
<p><strong>bs.d</strong>를 통해 생성된 함수는 이 외에도 더 가변적으로 사용될 수 있는데 추가적인 인자가 들어와도 처리해준다는 점입니다. 예를 들어 가변인자를 처리하는 함수를 생각해보죠.</p>
<pre>
//고정인자 $added외에 추가적인 인자를 받음
function test( $added ){
	var result;
	//추가인자를 묶어서 문자열로 만든다.
	if( arguments.length &gt; 1 ){
		result = Array.prototype.slice.call( arguments, 1 );
	}else{
		result = '추가인자 없음';
	}
	alert( $added + '::' + result );
}

//일단 생성하자.
var greeting = bs.d( test, '안녕' );

//1.그대로 호출한다.
greeting(); //안녕::추가인자 없음

//2.인자를 넣어서 호출한다.
greeting( '바보', '!!' ); //안녕:바보,!!
</pre>
<p>위와 같이 매우 손쉽게 생성된 함수에 인자를 추가적으로 보낼 수 있습니다. 이러한 특성을 이용하여 이벤트의 리스너등에 활용하게 됩니다.</p>
<pre>
function test( $msg, $event ){
	alert( $msg + '::' + $event.target.id );
}
document.getElementById('aa').addEventListener( 'onclick', bs.d( test, '안녕' ) );

//aa를 클릭하면 - 안녕::aa
</pre>
<p>예제는 <strong>addEventListener</strong>를 사용하므로 <strong>FF</strong>나 <strong>CR</strong>에서 작동됩니다만, <strong>html</strong>상의 <strong>aa</strong>를 클릭하면 위와 같은 출력이 일어납니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/1L2-ToWSF9g" height="1" width="1"/>]]></content:encoded>
         <category>02. JS Sys</category>
      <feedburner:origLink>http://zero.diebuster.com/zero/?p=19</feedburner:origLink></item>
      <item>
         <title>BS.updater[] : 배열을 문자열로</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/Vc7tAKuBzFo/</link>
         <description>배열로 문자열 만들기 배열을 곰곰히 고찰해보면 다음과 같은 특징이 있습니다. 1. Object를 기본으로 하고 있으므로 자유롭게 key-value를 잡을 수 있다(즉 Object임) 이 특성을 이용하면 다음과 같은 일이 가능합니다. 2. join을 이용해 손쉽게 문자열로 합칠 수 있다. 이건 당연하다면 당연하지만 join이 &amp;#8230; &lt;a rel="nofollow" target="_blank" href="http://zero.diebuster.com/zero/?p=18"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">http://zero.diebuster.com/zero/?p=18</guid>
         <pubDate>Tue, 31 Jan 2012 05:32:14 +0000</pubDate>
         <content:encoded><![CDATA[<p><span id="more-18"></span></p>
<h2>배열로 문자열 만들기</h2>
<p>배열을 곰곰히 고찰해보면 다음과 같은 특징이 있습니다.</p>
<p>1. <strong>Object</strong>를 기본으로 하고 있으므로 자유롭게 <strong>key-value</strong>를 잡을 수 있다(즉 <strong>Object</strong>임)</p>
<p>이 특성을 이용하면 다음과 같은 일이 가능합니다.</p>
<pre>
//배열을 선언한다.
var arr = [];

//마음대로 키를 잡는다
arr.left = 0;
arr.top = 1;
</pre>
<p>2. <strong>join</strong>을 이용해 손쉽게 문자열로 합칠 수 있다.</p>
<p>이건 당연하다면 당연하지만 <strong>join</strong>이 <strong>js</strong>의 네이티브 함수라 실행속도가 빠르다는 점은 의미가 있습니다. 다른 구조를 사용한 합치기보다는 우수하다고 할 수 있겠죠. 예를 들어 보겠습니다.</p>
<pre>
// 문자열에 담아서 합치는 경우
var str1 = 'test1';
var str2 = 'test2';
alert( str1 + str2 );

//오브젝트에 담아서 합치는 경우
var str = { s1:'test1', s2:'test2' };
alert( str.s1 + str.s2 );

//배열에 담아서 합치는 경우
var arr = ['test1', 'test2'];
alert( arr.join( '' ) );
</pre>
<p>위의 예에서 배열의 경우에만 네이티브 함수를 사용하여 문자열을 합치게 됩니다.</p>
<h2>bs.updater</h2>
<p>위의 내용을 기본으로 하여 수정 시에 자동으로 문자열 합치기를 수행하고 이를 캐쉬에 잡아 성능을 높이도록 개선한 것인 바로 <strong>bs.updater</strong>입니다.<br />
아래의 소스를 일단 보죠. 매우 짧습니다.</p>
<pre>
bs.Class(

'updater[]', function(){
	this._isUpdate/*:int*/ = 1;
	this._string/*:String*/ = '';
	this.prev/*:updater*/ = null;
},

'_update', function()/*:void*/{
	this._isUpdate = 1;
	if( this.prev ){
		this.prev._update();
	}
},

'_toString', function()/*:void*/{
	this._string = this.join('');
},

'toString', function()/*:String*/{
	if( this._isUpdate ){
		this._isUpdate = 0;
		this._toString();
	}
	return this._string;
}

);
</pre>
<p>위의 클래스 정의를 보면 생성자 함수에서 <strong>_isUpdate, _string, prev</strong> 에 해당되는 속성을 정의하고 있습니다. 각 속성의 의미는 다음과 같습니다.</p>
<ol>
<li><strong>_isUpdate :</strong> 이미 업데이트가 되었는지 아닌지를 체크하는 값. 만약 1 이면 업데이트가 필요하다는 뜻이 되고, 0 이면 이미 업데이트가 된 상태라는 의미임.</li>
<li><strong>_string :</strong> 업데이트 완료되면 배열을 문자열로 만든 뒤 이를 캐쉬로 잡아두고 이후 문자열 요청에 대해서는 이 캐쉬된 문자열로 응답하여 속도를 높임.</li>
<li><strong>prev :</strong> 만약 연결된 객체가 있다면 업데이트를 연쇄적으로 일으키기 위한 참조 변수.</li>
</ol>
<p><strong>updater</strong>란 결국 배열을 문자열로 만드는 과정을 자동화하여 캐쉬를 잡아두는 클래스입니다. 다음과 같이 사용할 수 있습니다.</p>
<pre>
var css0 = bs.New( 'updater' );

//css에 들어갈 내용을 기술한다.
css0.push( 'left:', 50, 'px;top:', 100, 'px' );

//css0[1]의 50은 left를 의미하므로 left키에 1번 인덱스를 설정
css0.left = 1;
//css0[3]의 100은 top를 의미하므로 top키에 1번 인덱스를 설정
css0.top = 3;

//설정이 완료되었으므로 left와 top을 변경해본다.
css0[css0.left] = 60;
css0[css0.top] = 60;
//_update를 호출하여 변경사항을 반영한다.
css0._update();

alert( css0 ); //left:60px;top:60px
</pre>
<p><strong>updater</strong>의 사용처</p>
<p>근데 이런 걸 어디에 쓰냐면 이미 예제에서 살짝 힌트를 보여드렸는데 트위너에 보낼 때 귀찮은 문자열-숫자 변환작업도 필요없어지고 여러 가지로 잇점이 많습니다. 사실 <strong>updater</strong>는 많은 <strong>bs</strong>함수의 기저클래스로 사용되고 있습니다. 매우 간단한 <strong>rgb</strong>클래스를 살펴보겠습니다.</p>
<pre>
bs.Class(

'rgb[]:updater', null,

//팩토리함수
'@$', function(
	$ref/*:updater*/,
	$r/*:Number*/,
	$g/*:Number*/,
	$b/*:Number,
	$a/*:Number*/
)/*:rgb*/{
	var result, a;
	result = bs.New( 'rgb' );
	result.$prop( 'prev',$ref,'r',1,'g',2,'b',3,'a',4);
	if( arguments.length == 4 ){
		a = 1;
	}else{
		a = arguments[4];
	}
	result.push( 'rgb(',$r,',',$g,',',$b,',', a,')');
	return result;
},

'set', function()/*:rgb*/{
	var i, j;
	for( i = 0, j = arguments.length ; i &amp;lt; j ; i = i + 2 ){
		this[this[arguments[i]]] = arguments[i + 1];
	}
	this._update();
	return this;
}

);
</pre>
<p>이 클래스는 <strong>rgb</strong>값을 받아서 <strong>css</strong>용으로 <strong>rgb(255,100,200)</strong> 같은 값을 출력해주는 용도로 설계되었습니다. 아래와 같이 <strong>set</strong>을 사용하면 자동으로 <strong>update</strong>가 일어납니다.</p>
<pre>
//rgb 인스턴스를 생성한다.
var rgb = bs.rgb.$( null, 255, 100, 100 );

//녹색과 청색을 재설정한다.
alert( rgb.set( 'g', 170, 'b', 300 ) ); //rgb(255,170,300);
</pre>
<p>약간 멍하셨을 수도 있겠지만 <strong>set</strong>은 내부적으로</p>
<ol>
<li><strong>_update</strong>를 호출해서 업데이트가 필요한 상황으로 만들었고</li>
<li>자기 자신을 반환합니다.</li>
<li>따라서 <strong>alert( rgb )</strong>와 마찬가지 상태가 되는데,</li>
<li><strong>alert</strong>는 문자열을 받아야 함으로 자동으로 <strong>rgb.toString()</strong> 을 호출하게 됩니다.</li>
<li>이 때 업데이트가 필요한 상황을 인지하여 <strong>rgb</strong>의 <strong>_toString()</strong>이 호출되어 문자열을 생성하게 됩니다.</li>
</ol>
<p>이런 과정으로 작동하게 되는 방식이 바로 <strong>updater</strong>클래스입니다.</p>
<p>이상 살펴본 바와 같이 배열에 키를 결합하여 인덱스를 관리하는 아이디어는 매우 재밌는 형태를 만들어냅니다.<br />
(이후 소개할 <strong>bs</strong>클래스는 <strong>updater</strong>를 합성한 경우가 많기 때문에 이번 글을 이해하시면 향 후 도움이 많이 됩니다 ^^)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/Vc7tAKuBzFo" height="1" width="1"/>]]></content:encoded>
         <category>02. JS Sys</category>
      <feedburner:origLink>http://zero.diebuster.com/zero/?p=18</feedburner:origLink></item>
      <item>
         <title>BS Class : 클래스 만들기</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/MYU9okfVoV0/</link>
         <description>모든 인스턴스는 Object js에서 간과하면 안되는 점은 new로 생성된(리터럴 포함) 모든 인스턴스는 전부 Object라는 점입니다. Object는 근본적으로 key-value로 무한히 값을 저장할 수 있는 hashmap입니다. 따라서 js에서 클래스의 개념은 그저 hashmap인 Object에게 적당히 key-value를 복사해준다로 요약할 수 있습니다. 이것을 속성 복사를 &amp;#8230; &lt;a rel="nofollow" target="_blank" href="http://zero.diebuster.com/zero/?p=17"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">http://zero.diebuster.com/zero/?p=17</guid>
         <pubDate>Fri, 27 Jan 2012 05:05:52 +0000</pubDate>
         <content:encoded><![CDATA[<p><span id="more-17"></span></p>
<h2>모든 인스턴스는 Object</h2>
<p><strong>js</strong>에서 간과하면 안되는 점은 <strong>new</strong>로 생성된(리터럴 포함) 모든 인스턴스는 전부 <strong>Object</strong>라는 점입니다. <strong>Object</strong>는 근본적으로 <strong>key-value</strong>로 무한히 값을 저장할 수 있는 <strong>hashmap</strong>입니다. 따라서 <strong>js</strong>에서 클래스의 개념은 그저 <strong>hashmap</strong>인 <strong>Object</strong>에게 적당히 <strong>key-value</strong>를 복사해준다로 요약할 수 있습니다. 이것을 속성 복사를 통한 상속이라고도 하고 간단히 복사 합성이라고도 합니다.</p>
<h2>메서드를 빌려쓰는 원리</h2>
<p><strong>js</strong>는 애시당초 메모리를 절약하고자 디자인 되었으므로 다른 <strong>Object</strong>의 속성이나 함수를 자신의 <strong>key-value</strong>에 잡아빌려쓰기 용이한 언어 구조를 갖고 있습니다. 예를 들어 아래와 같은 함수를 생각해 보겠습니다.</p>
<pre>
function hello(){
	alert( 'hello, ' + this.name );
}
</pre>
<p>간단히 어떤 <strong>Object</strong>의 <strong>name</strong>속성에 근거하여 인사를 출력해주는 메서드입니다. 보통 <strong>oop</strong>언어에서 <strong>this</strong>가 언급되면 특정 클래스의 소유물이 됩니다. 즉 아래와 같은 느낌입니다.</p>
<pre>
class some1{
	var name;
	function hello(){
		alert( 'hello, ' + this.name );
	}
}
</pre>
<p><strong>oop</strong>언어에서 저런 형태가 되는 이유는 <strong>this</strong>가 <strong>class</strong>의 범위에 자동으로 바인딩되기 때문입니다. 이 개념은 매우 편리하지만 반대로 얘기하면 <strong>some1</strong>, <strong>some2</strong>, <strong>some3</strong>.. 등의 클래스에서 <strong>hello</strong>가 필요해도 그것을 공유할 방법이 없어 매번 새로 정의해야 한다는 뜻입니다. 이는 메모리 상의 명백한 낭비입니다. <strong>oop</strong>언어라면 이런 불편함을 상속구조나 인자를 건내주는 유틸함수 등을 사용해서 해결합니다만,</p>
<p>1. 상속이란 부모의 인스턴스를 같이 생성하므로 메모리면에서 불리하고<br />
2. 유틸함수에 인자를 넘기면 이미 캡슐화가 깨지기 때문에</p>
<p>실질적으로 다른 클래스의 메서드를 빌려쓰는 방식은 성립하지 않습니다. <strong>internal</strong>클래스를 선언한 뒤 인스턴스를 하나 만들어 공유시키는 방식을 쓰고 변수를 <strong>internal</strong>로 선언하는게 그나마 괜찮은 방법입니다만 이도 빌려쓴 게 아니라 도우미가 등장한 꼴입니다.</p>
<p><strong>js</strong>에서는 진정으로 저 함수 하나를 여러 클래스 또는 인스턴스가 돌려쓸 수 있는데 그 이유는 <strong>this</strong>의 바인딩이 무조건 동적으로 일어나기 때문입니다. 예를들어 두 개의 생성자 함수에서 <strong>hello</strong>를 공유해보죠.</p>
<pre>
function hello(){
	alert( 'hello, ' + this.name );
}

function some1( $name ){
	this.name = $name;
	this.hello = hello;
}

function some2( $name ){
	this.name = $name + ', good!';
	this.hello = hello;
}
</pre>
<p>위의 예에서 <strong>some1</strong>과 <strong>some2</strong>는 완전히 <strong>hello</strong> 하나를 빌려쓰는 꼴이 됩니다. 아예 선언 자체도 안하고 <strong>key-value</strong>에 잡아주기만 하는 것이죠. 이후 아래와 같이 잘 작동하게 됩니다.</p>
<pre>
var s1 = new some1( 'hanekawa' );
s1.hello(); // hello, hanekawa

var s2 = new some2( 'gahara' );
s2.hello(); // hello, gahara, good!
</pre>
<h2>복사 합성의 장단점</h2>
<p>이러한 복사 방식의 상속은 프로토타입체인에 <strong>key-value</strong>를 인스턴스 별로 추가 생성하는 비용이 발생합니다. 만약 아래와 같은 프로토타입을 사용한다면 각 인스턴스별로 추가적인 <strong>hello</strong> 키 선언이 불필요해지므로 <strong>key</strong>한 개만큼의 메모리를 절약할 수 있습니다.</p>
<pre>
//1. 일단 각 생성자를 만든다.
function some1( $name ){
	this.name = $name;
}

function some2( $name ){
	this.name = $name + ', good!';
}

//2. 프로토타입의 대상을 만든다.
parent = {
	hello: function(){
		alert( 'hello, ' + this.name );
	}
};

//3. 이제 각 함수의 프로토타입을 바인딩하자.
some1.prototype = parent;
some2.prototype = parent;

//4. 작동을 확인해본다.
var s1 = new some1( 'hanekawa' );
s1.hello(); // hello, hanekawa

var s2 = new some2( 'gahara' );
s2.hello(); // hello, gahara, good!
</pre>
<p>이 방식에서는 <strong>s1</strong>, <strong>s2</strong>에 <strong>hello</strong>라는 키가 선언되지 않습니다. 따라서 메모리는 그만큼 절약됩니다. 위의 예에서는 고작 <strong>hello</strong>하나지만 십수개의 메서드를 키에 복사하고 인스턴스도 수 백개가 생성될 예정이라면 절약폭은 적지 않습니다. 하지만 메모리를 덜 쓰는 만큼 <strong>hello</strong>를 호출할 때마다 다음과 같은 일이 일어납니다.</p>
<p>1. 우선 <strong>s1</strong>의 <strong>key-value</strong>를 전부 검사한다.<br />
2. <strong>hello</strong>를 발견하지 못했다.<br />
3. <strong>s1.__proto__</strong>에 지정된 <strong>parent</strong>를 검색 대상으로 바꾼다.<br />
4. <strong>parent</strong>의 <strong>key-value</strong>를 검사한다.<br />
5. <strong>hello</strong>를 찾았다!<br />
6. 이제 <strong>s1.__proto__.hello.call( s1 );</strong> 을 실행한다.</p>
<p>즉 2,3,4 과정이 발생하게 됩니다. 이에 비해 속성 복사를 한 경우는 다음과 같이 됩니다.</p>
<p>1. 우선 <strong>s1</strong>의 <strong>key-value</strong>를 전부 검사한다.<br />
2. <strong>hello</strong>를 찾았다!<br />
3. 이제 <strong>s1.hello.call( s1 );</strong> 을 실행한다.</p>
<p>따라서 hello를 자주 호출해야 하는 경우는 복사한 쪽이 압도적으로 성능 상의 잇점을 갖게 됩니다. 따라서 프로토타입체인을 쓸 것이냐 아니면 속성을 복사할 것이냐는 정답이 존재하는 것이 아니라 사용되는 빈도나 생성될 인스턴스의 양에 따라 의사결정을 해야하는 문제입니다.</p>
<h2>bs가 지원하는 Class함수</h2>
<p><strong>bs</strong>는 태생이 철저한 성능 위주의 라이브러리입니다. 따라서 오직 복사 합성 방식을 고수합니다. 단 <strong>jq</strong>서브셋을 만들어내는 형태처럼 인스턴스의 기저를 배열로 할 지 아니면 <strong>Object</strong>로 할지는 선택할 수 있습니다. 어짜피 배열도 <strong>Object</strong>이기 때문에 큰 차이는 없습니다만, 인덱스 자동생성과 <strong>length</strong>관리가 때때로 편리하니까요.</p>
<p>우선 문법을 살펴보겠습니다.</p>
<pre>
bs.Class(
	'클래스이름', 생성자함수,
	'메서드명1', 메서드,
	'메서드명2', 메서드,...
);
</pre>
<p>매우 간단한 구조를 통해 클래스를 생성할 수 있습니다. 실제로 <strong>some1</strong>을 옮겨 보면 아래와 같습니다.</p>
<pre>
bs.Class(

'some1', function(){
	this.name = '';
},
'hello', function(){
	alert( 'hello, ' + this.name );
}

);
</pre>
<p>또한 여기서 인스턴스를 얻는 방법은 아래와 같습니다.</p>
<pre>
var s1 = bs.New( 'some1' );
s1.hello(); //hello,
</pre>
<p>이렇게 생성된 s1인스턴스에는 <strong>hello</strong>라는 키가 잡혀서 함수의 참조가 복사 되어있습니다. 이름을 정해준 적이 없으니 당연하게도 <strong>name</strong>속성은 빈 값입니다. <strong>New</strong>함수에 추가적으로 속성을 지정할 수 있게 되어있습니다.</p>
<pre>
var s1 = bs.New( 'some1', 'name', 'hanekawa' );
s1.hello(); //hello, hanekawa
</pre>
<p>이 외에도 <strong>bs.Class</strong>는 다음과 같은 다양한 선언 및 기능을 제공합니다.</p>
<p>1. 배열을 기반으로 하는 인스턴스를 생성하는 클래스를 선언하려면 클래스 이름 뒤에 []를 붙인다.</p>
<pre>bs.Class( 'some1[]', ...</pre>
<p>2. 다른 클래스의 속성을 복사하고 싶다면 콜론으로 연결한다.</p>
<pre>bs.Class( 'some2:some1', ...</pre>
<p>3. 상속이 아니라 복사의 대상이므로 여러 개로 부터 복사할 수 있다.</p>
<pre>bs.Class( 'some2:some1:a:b:c', ...</pre>
<p>4. 선언된 클래스는 <strong>bs</strong>.으로 참조할 수 있다.</p>
<pre>
bs.Class( 'some1', ... );
var some1Class = bs.some1;
</pre>
<p>5. 메서드의 이름 앞에 <strong>@</strong>를 붙이면 <strong>static</strong>메서드가 된다.</p>
<pre>
bs.Class( 'some1', bs.Class(

'some1', function(){
	this.name = '';
},
'@hello', function( $name ){ //스태틱으로 선언!
	alert( 'hello, ' + $name );
}

);

bs.some1.hello( 'hanekawa' ); //hello, hanekawa
</pre>
<p><strong>bs</strong>의 <strong>Class</strong>, <strong>Method</strong>, <strong>New</strong> 함수는 각각 클래스의 생성과 인스턴스의 생성에 관여하지만 구현은 단순하여 구지 소스를 포스팅하지 않았습니다. 위에서 언급한 시그니처를 이해하시면 누구나 손쉽게 구현할 수 있는 수준이라 생략했습니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/MYU9okfVoV0" height="1" width="1"/>]]></content:encoded>
         <category>01. JS Base</category>
      <feedburner:origLink>http://zero.diebuster.com/zero/?p=17</feedburner:origLink></item>
      <item>
         <title>BS Stop : 정지 시키기</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/Dmc_mbjLAlk/</link>
         <description>런타임에러(Runtime Error) js에는 컴파일 과정이 없기 때문에 런타임에러가 매우 흔하게 발생됩니다. 런타임에러란 실행 중에 돌연 발생하게 되는 것입니다. 따라서 완성된 것처럼 보이고 싶은 입장에서는 감추고 싶어집니다. 이러한 개발자의 마음을 이해하듯 js에도 try..catch로 대변되는 에러 감추기 장치가 마련되어있습니다. 하지만 컴파일에러를 확인할 &amp;#8230; &lt;a rel="nofollow" target="_blank" href="http://zero.diebuster.com/zero/?p=16"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">http://zero.diebuster.com/zero/?p=16</guid>
         <pubDate>Wed, 25 Jan 2012 15:03:16 +0000</pubDate>
         <content:encoded><![CDATA[<p><span id="more-16"></span></p>
<h2>런타임에러(<strong>Runtime Error</strong>)</h2>
<p><strong>js</strong>에는 컴파일 과정이 없기 때문에 런타임에러가 매우 흔하게 발생됩니다.<br />
런타임에러란 실행 중에 돌연 발생하게 되는 것입니다. 따라서 완성된 것처럼 보이고 싶은 입장에서는 감추고 싶어집니다. 이러한 개발자의 마음을 이해하듯 <strong>js</strong>에도 <strong>try..catch</strong>로 대변되는 에러 감추기 장치가 마련되어있습니다. 하지만 컴파일에러를 확인할 수 없는 이상 런타임에러를 감추면 영원히 에러를 잡을 수 없게 되고 그럼 더 극악한 단계인 컨텍스트 에러로 넘어가버립니다.</p>
<p>따라서 <strong>js</strong>에서 가장 적합한 전략은 런타임에러가 발생하는 즉시 정지시키기 입니다.<br />
즉시 정지시키는 방법은 크게 두 가지 입니다. 우선 <strong>try</strong>를 쓰지 않는 것입니다. 실천하기 쉽죠. 두번째는 뭔 잘못되었다고 판단될 때 <strong>throw</strong>하는 것입니다.</p>
<h2>잘못된 시점</h2>
<p>하지만 뭔가 잘못된 건 어떻게 알 수 있나요?<br />
그것은 예측하는 것입니다. 예를 들어 <strong>jq</strong>를 이용해 <strong>HTMLList</strong>를 반환하는 간단한 함수를 생각해보죠.</p>
<pre>
function getHTMLList( $selector ){
	return $( $selector ).get();
}
</pre>
<p>이 함수는 문제가 없어보이지만 사실은 여러 가지를 가정하고 있습니다. 예를 들어 <strong>$selector</strong>가 적합한 값이 올거라고 기대하는 거죠. 만약 아래와 같이 인자에 아무것도 안넣거나 이상한 값을 넣으면 어찌 되나요?</p>
<pre>
alert( getHTMLList() ); //인자가 없다
alert( getHTMLList( 3 ) ); //인자가 숫자
alert( getHTMLList( {} ) ); //인자가 객체
</pre>
<p>요점은 이런 과정이 런타임에러를 일으키기 전에 혹은 기대한 바대로 함수가 작동안하기 전에 예측할 수 있다는 점입니다. 따라서 다음과 같이 미리 막으면 됩니다.</p>
<pre>
function getHTMLList( $selector ){
	if( $selector &amp;&amp; typeof( $selector ) == 'string' ){
		return $( $selector ).get();
	}
}
</pre>
<h2>호출한 측의 에러도 감추지 않기</h2>
<p>하지만 이것은 에러를 숨긴 꼴이 됩니다. 왜냐면 잘못된 인자를 보낸 시점에서 이미 그 <strong>getHTMLList</strong>함수를 호출한 측에 문제가 있기 때문입니다. 따라서 잘못된 인자로 함수를 호출하는 쪽도 수정하지 않으면 안됩니다만, 이렇게 하면 마치 해당 <strong>$selector</strong>에 해당되는 <strong>HTML</strong>이 없는 것처럼 가려지는 효과가 발생합니다. 따라서 즉시 에러를 발생시켜 함수를 호출한 쪽도 디버깅해야합니다.</p>
<pre>
function getHTMLList( $selector ){
	if( $selector &amp;&amp; typeof( $selector ) == 'string' ){
		return $( $selector ).get();
	}else{
		throw Error( 'getHTMLList::invaild $selector - ' + $selector );
	}
}
</pre>
<p>위의 예는 에러를 감추지 않고 즉시 발생시키는 요령 중 하나입니다.</p>
<p><strong>bs </strong>에서는 이러한 절차를 일반화시키고 <strong>_debug </strong>라는 속성을 도입하여 디버깅시와 릴리즈시를 구분지어 행동하게 합니다.</p>
<pre>
var bs = {

//debug 모드 설정

_debug: 'throw',
debugThrow: function(){
	this._debug = 'throw';
},
debugLogging: function(){
	this._debug = 'logging';
},
debugNone: function(){
	this._debug = null;
},

//정지 함수

Stop: function(){
	if( this._debug == 'throw' ){
		throw Error( this._join.call( arguments, ',' ) );
	}else if( this._debug == 'logging' ){
		this.Log( this._join.call( arguments, ',' ) );
	}
}

};
</pre>
<p>다음과 같이 사용됩니다.</p>
<pre>
bs.debugThrow();

function getHTMLList( $selector ){
	if( $selector &amp;&amp; typeof( $selector ) == 'string' ){
		return $( $selector ).get();
	}else{
		bs.Stop( 'getHTMLList::invaild $selector - ' + $selector );
	}
}
</pre><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/Dmc_mbjLAlk" height="1" width="1"/>]]></content:encoded>
         <category>01. JS Base</category>
      <feedburner:origLink>http://zero.diebuster.com/zero/?p=16</feedburner:origLink></item>
      <item>
         <title>BS Arg : 인자를 정리하기</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/0aqdGdylsIs/</link>
         <description>js에서 가변인자의 의미 js는 원하던 원치 않던 무조건 가변인자를 지원합니다. 오히려 함수에 인자를 명시적으로 선언할 경우 가변인자의 특정 차례에 있는 값을 인자의 이름에 매핑하는 과정을 일으켜 부하를 일으키는 식입니다. 예를들어 아래와 같은 경우를 생각할 수 있습니다. 이 경우 수 많은 &amp;#8230; &lt;a rel="nofollow" target="_blank" href="http://zero.diebuster.com/zero/?p=15"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">http://zero.diebuster.com/zero/?p=15</guid>
         <pubDate>Wed, 25 Jan 2012 01:11:05 +0000</pubDate>
         <content:encoded><![CDATA[<p><span id="more-15"></span></p>
<h2>js에서 가변인자의 의미</h2>
<p><strong>js</strong>는 원하던 원치 않던 무조건 가변인자를 지원합니다. 오히려 함수에 인자를 명시적으로 선언할 경우 가변인자의 특정 차례에 있는 값을 인자의 이름에 매핑하는 과정을 일으켜 부하를 일으키는 식입니다. 예를들어 아래와 같은 경우를 생각할 수 있습니다.</p>
<pre>
//인자를 선언
function test( a, b, c, d, e, f, g, h, i ){
	alert( f );
}
</pre>
<p>이 경우 수 많은 인자를 명시적으로 선언했지만 결국 사용되는건 <strong>f</strong> 뿐입니다. 하지만 <strong>js</strong>는 내부적으로 <strong>arguments</strong> 리스트를 생성하고 인자의 이름에 맞게 하나하나 복사하는 과정을 거칩니다. 따라서 쓸데없이 <strong>a,b,c,d,e,g,h,i</strong> 에 <strong>arguments </strong>를 복사하는 부하를 걸게 됩니다. 결국 아래와 같이 쓰는 편이 정답입니다.</p>
<pre>
//인자를 선언
function test( /*a, b, c, d, e, f, g, h, i*/ ){
	var f;
	f = arguments[5];
	alert( f );
}
</pre>
<p>어짜피 내부의 <strong>[[scope]] </strong>상에서는 인자에 선언하나 지역변수로 선언하나 동일한 공간에 이름이 등록됩니다. 따라서 딱 필요한 만큼만 복사해서 사용하도록 해야겠죠.<br />
위와 같은 이유로 고성능을 노린다면 <strong>arguments </strong>리스트 자체를 이용하는 스타일이 많이 사용되는데 함수들이 서로 이러한 인자 체계를 갖는 경우 서로에게 인자의 일부를 전달해야하는 경우가 자주 발생합니다.</p>
<div style="text-align:center;margin-bottom:20px;font-size:11px;">
<img src="https://lh6.googleusercontent.com/-hV5P91yFtLU/Tx9_zAWGLMI/AAAAAAAAAno/AsoXYSiitwY/s500/15_0.png"><br />선언된 인자가 추가적인 부하를 발생시키는 과정</div>
<h2>인자의 일부를 전달하는 경우</h2>
<p>예를들어 다음과 같은 함수를 생각해보겠습니다.</p>
<pre>
var bind = {};
function addArray( $name /*, data... */ ){
	var temp;
	temp = [];
	temp.push.apply( temp, ... ); //	bind[$name] = temp;
}
</pre>
<p>위의 함수에서는 <strong>bind</strong>라는 <strong>Object</strong>에 특정 이름으로 배열을 넣어주고 있습니다. 처음 인자인 <strong>$name</strong>의 경우는 짜피 명시적으로 선언해야 하기 때문에 인자의 이름을 부여했습니다만 그 이후의 인자는 결국 해당 배열의 데이터가 될 것이라, 길이나 이름을 줄 수 없습니다. 이 경우 <strong>push</strong>에 어떻게 해야 <strong>apply</strong>할 수 있을까요?<br />
방법은 인자를 분해하여 첫번째 인자만 제거하는 것입니다. 이 인자를 제거하는 예는 다양하게 구현할 수 있지만 <strong>jq</strong>등에서 흔하게 등장하는 방법은 <strong>Array.prototype.slice</strong>를 이용하는 방법입니다. 아래와 같이 구현됩니다.</p>
<pre>
var bind = {};
function addArray( $name /*, data... */ ){
	var temp;
	temp = [];
	temp.push.apply( temp, Array.prototype.slice.call( arguments, 1 ) );
	bind[$name] = temp;
}
</pre>
<p><strong>slice</strong>가 해당 인덱스로부터 시작하는 새로운 배열을 반환한다는 점을 착안해서 만든 스타일입니다. 이를 약간 더 개선하여 시작인덱스와 종료인덱스를 보내게 개선한 함수는 아마도 아래와 같을 것 입니다. 단 종료인덱스를 선택적으로 보낼 수 있게 했습니다.</p>
<pre>
function Arg( $arguments, $start, $end ){
	if( $end ){}else{ // $end가 없는 경우
		$end = $arguments.length;
	}
	return Array.prototype.slice.call( $arguments, $start, $end );
}
</pre>
<p>이렇게 되면 앞의 <strong>addArray</strong>함수도 아래와 같이 바뀝니다.</p>
<pre>
var bind = {};
function addArray( $name /*, data... */ ){
	var temp;
	temp = [];
	temp.push.apply( temp, Arg( arguments, 1 ) );
	bind[$name] = temp;
}
</pre>
<h2>bs의 Arg</h2>
<p>이러한 개념에 앞 부분에 인자를 추가하거나 길이 검사를 더 엄정하게 하는 등의 기능을 추가한 버전이 <strong>bs</strong>의 <strong>Arg</strong>함수입니다.</p>
<pre>
var bs = {

_slice: Array.prototype.slice,
_concat: Array.prototype.concat,
_argNull: [],

Arg: function(
	$arguments/*:arguments*/,
	$start/*:uint = 0*/, $end/*:uint = 0*/,
	$front/*:Array*/
)/*:Array*/{
	var i, j, result, temp;
	i = $arguments.length;
	if( i ){
		i = arguments.length;
		if( i === 2 ){
			return this._slice.call( $arguments, $start );
		}else if( i === 3 ){
			return this._slice.call( $arguments, $start, $end + 1 );
		}else{
			if( $end ){
				$end = $end + 1;
			}else{
				$end = i;
			}
			if( this.Type( $front, 'Array' ) ){
				temp = $front;
			}else{
				temp = [];
				for( i = 0, j = $front.length ; i &lt; j ; i = i + 1 ){
					temp[i] = $front[i];
				}
			}
			return temp.concat( this._slice.call( $arguments, $start, $end ) );
		}
	}else{
		return this._argNull;
	}
}

}
</pre>
<p>마지막 인자로 <strong>front</strong>라는 배열을 받아들여 반환할 인자의 앞 부분에 붙여주는 기능이 추가되어있습니다. 인자의 길이가 0일 때 반환하는 <strong>_argNull</strong>의 경우 하나의 빈 배열입니다.<br />
왜 <strong>null</strong>을 반환하지 않고 빈 배열을 반환하는가에 대해 설명드리면 <strong>func.apply( null, null );</strong> 구문이 <strong>FF</strong>나 <strong>CR</strong>에서는 문제없지만 <strong>IE</strong>에서는 에러가 됩니다. 따라서 <strong>IE</strong>까지 대응하려면 <strong>apply</strong>에 반드시 빈 배열로 보내야합니다. <strong>func.apply( null, [] );</strong> 이렇게 되어야하죠.</p>
<p>이제 실제로 사용해보면 다음과 같습니다.</p>
<pre>
var bind = {};
function addArray( $name /*, data... */ ){
	var temp;
	temp = [];
	temp.push.apply( temp, bs.Arg( arguments, 1 ) );
	bind[$name] = temp;
}
</pre><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/0aqdGdylsIs" height="1" width="1"/>]]></content:encoded>
         <category>01. JS Base</category>
      <feedburner:origLink>http://zero.diebuster.com/zero/?p=15</feedburner:origLink></item>
      <item>
         <title>BS Type : 형(type) 판별</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/fUajgzKWtjU/</link>
         <description>숫자, 문자열, 참거짓 등 기본 형이 아닌 new 나 new 에 상응하는 리터럴을 통해 생성된 객체타입은 typeof 를 사용해도 ‘object‘ 나 ‘function‘으로 나올 뿐입니다. 그렇다고 instanceof 를 쓰자니 매번 프로토타입체인을 타고 결과에 일치할 때까지 constructor 를 검색할 비용이 두럽습니다. constructor 를 &amp;#8230; &lt;a rel="nofollow" target="_blank" href="http://zero.diebuster.com/zero/?p=14"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">http://zero.diebuster.com/zero/?p=14</guid>
         <pubDate>Thu, 19 Jan 2012 01:27:55 +0000</pubDate>
         <content:encoded><![CDATA[<p><span id="more-14"></span><br />
숫자, 문자열, 참거짓 등 기본 형이 아닌 <strong>new</strong> 나 <strong>new</strong> 에 상응하는 리터럴을 통해 생성된 객체타입은 <strong>typeof</strong> 를 사용해도 ‘<strong>object</strong>‘ 나 ‘<strong>function</strong>‘으로 나올 뿐입니다.</p>
<p>그렇다고 <strong>instanceof</strong> 를 쓰자니 매번 프로토타입체인을 타고 결과에 일치할 때까지 <strong>constructor </strong>를 검색할 비용이 두럽습니다.</p>
<p><strong>constructor</strong> 를 쓰려고 했더니 반드시 형을 판별하는 쪽에서 해당 객체의 생성자 함수를 알고 있어야한다는 제약이 생깁니다(이건 <strong>instanceof</strong> 도 마찬가지입니다만 ^^)</p>
<p>그래서 어쩔수 없이 남은 건 <strong>Object.prototype.toString</strong> 입니다. <strong>bs</strong> 에서는 다음과 같은 <strong>Type </strong>함수를 제공합니다.</p>
<pre>
var bs = {

_toString: Object.prototype.toString,
Type: function( $target/*:**/, $type/*:String*/ )/*:Boolean|**/{
	if( $type ){
		return this._toString.call( $target ) === '[object ' + $type + ']';
	}else{
		$type = this._toString.call( $target );
		$target.$type = $type.substring( 8, $type.length - 1 );
		return $target;
	}
}

}
</pre>
<p>이를 통해 성능 상의 이슈를 최소화 한 채로 형 판별 시 해당 형의 이름을 문자열로 조회할 수 있습니다.</p>
<pre>
alert( bs.Type( [], 'Array' ) ); //true 출력

alert( bs.Type( new Custom(), 'Custom' ) ); //true 출력
</pre>
<p>또한 <strong>Type</strong> 함수는 더욱 빠른 형 판별을 위해 강제로 형을 입혀주는 용도로 사용할 수 있습니다.</p>
<pre>
var temp;

//1. 배열 생성
temp = [];

//2. 형 처리
bs.Type( temp );

//3. 형 비교
alert( temp.$type === 'Array' ); //true 출력
</pre>
<p>위와 같은 방법을 통하면 여러 번 형을 조회할 때 가장 빠른 형 판별이 가능하지만 특정한 키(<strong>$type</strong>)를 덮어쓰게 되는 위험성이 있습니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/fUajgzKWtjU" height="1" width="1"/>]]></content:encoded>
         <category>01. JS Base</category>
      <feedburner:origLink>http://zero.diebuster.com/zero/?p=14</feedburner:origLink></item>
      <item>
         <title>BS $, _ : 변수선언을 금지시키기</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/w-t-OYoMFUw/</link>
         <description>전역변수 공간도 더럽히기 싫고 비효율적인 메모리관리도 싫은데 지역변수를 잔뜩 잡아서 ec를 무겁게 하기도 싫다면 어떤 선택지가 있을까요? bs에서는 간단히 이러한 쓰고버릴(?) 별도의 변수공간을 제공합니다. jq스타일로 인자가 하나만 오면 해당 키의 값을 반환하고 두 개 오면 키에 값을 넣어줍니다. bs는 이러한 &amp;#8230; &lt;a rel="nofollow" target="_blank" href="http://zero.diebuster.com/zero/?p=13"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">http://zero.diebuster.com/zero/?p=13</guid>
         <pubDate>Wed, 18 Jan 2012 14:11:49 +0000</pubDate>
         <content:encoded><![CDATA[<p><span id="more-13"></span><br />
전역변수 공간도 더럽히기 싫고 비효율적인 메모리관리도 싫은데 지역변수를 잔뜩 잡아서 <strong>ec</strong>를 무겁게 하기도 싫다면 어떤 선택지가 있을까요?</p>
<p><strong>bs</strong>에서는 간단히 이러한 쓰고버릴(?) 별도의 변수공간을 제공합니다. <strong>jq</strong>스타일로 인자가 하나만 오면 해당 키의 값을 반환하고 두 개 오면 키에 값을 넣어줍니다.</p>
<p><strong>bs</strong>는 이러한 데이터 공간에서 꺼내거나 생성시키는 경우 <strong>$함수</strong>를 사용하고 키를 제거하기 위해서 <strong>_함수</strong>를 사용합니다. 간단히 아래와 같이 구현할 수 있습니다.</p>
<pre>
var bs = {

_bind: {},
$: function( $name/*:String*/, $value/*:**/ )/*:*/{
	if( arguments.length === 2 ){
		return this._bind[$name] = $value;
	}else{
		return this._bind[$name];
	}
},
_: function( $name/*:String*/ )/*:void*/{
	delete this._bind[$name];
}

}
</pre>
<p>이 간단한 구현을 통해 필요한 변수를 <strong>bs</strong>에 생성하여 사용할 수 있게 되므로 전역이름공간을 더럽히지 않을 수 있습니다.</p>
<pre>
// test1에 배열을 할당한다.
bs.$( 'test1', ['h','e','l','l','o'] );

alert( bs.$( 'test1' )[1] ); //'e' 출력

// test1을 제거한다.
bs._( 'test1' );

alert( bs.$( 'test1' ) ); //undefined 출력
</pre>
<p>이러한 별도의 변수 공간은 단지 1차적인 키만 선언하지 않고 복잡한 계층구조에도 이용됩니다.</p>
<pre>
bs.$( 'test1', {
	name: 'test1',
	action: func1
	data: {key:435643}
} );

alert( bs.$( 'test1' ).data.key ); //435643 출력
</pre><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/w-t-OYoMFUw" height="1" width="1"/>]]></content:encoded>
         <category>01. JS Base</category>
      <feedburner:origLink>http://zero.diebuster.com/zero/?p=13</feedburner:origLink></item>
      <item>
         <title>BS Logger : 가볍게 로깅하기</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/LXccO3vClX0/</link>
         <description>자바스크립트를 디버깅하기 위해 파어이폭스 등 개발자를 위한 콘솔을 제공하는 브라우저의 기능을 이용합니다만, 그렇다고 해도 현재 살펴보고 싶은 값은 로그로 출력해 확인하고 싶을 때가 많습니다. 이 경우 브라우저 디버거가 지원하는 console 객체를 이용하는 방법도 있지만 간단히 &amp;#60;div&amp;#62;의 innerHTML만으로도 console을 쉽게 대체할 수 &amp;#8230; &lt;a rel="nofollow" target="_blank" href="http://zero.diebuster.com/zero/?p=12"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">http://zero.diebuster.com/zero/?p=12</guid>
         <pubDate>Wed, 18 Jan 2012 03:22:18 +0000</pubDate>
         <content:encoded><![CDATA[<p><span id="more-12"></span><br />
자바스크립트를 디버깅하기 위해 파어이폭스 등 개발자를 위한 콘솔을 제공하는 브라우저의 기능을 이용합니다만, 그렇다고 해도 현재 살펴보고 싶은 값은 로그로 출력해 확인하고 싶을 때가 많습니다.</p>
<p>이 경우 브라우저 디버거가 지원하는 <strong>console </strong>객체를 이용하는 방법도 있지만 간단히 <strong>&lt;div&gt;</strong>의 <strong>innerHTML</strong>만으로도 <strong>console</strong>을 쉽게 대체할 수 있습니다.</p>
<p>하지만 <strong>innerHTML</strong>은 내용이 길어질 수록 점점 무거워지는 단점이 있으므로 적당한 길이에서 차단해야 합니다.</p>
<p>이러한 제약으로 인해 <strong>bs</strong>에서는 내부에 로그기록을 배열로 내장하고 이 배열을 일정부분만 잘라서 로그로 표시하게 됩니다.</p>
<pre>
var bs = {

Log: function( $logger/*:HTMLElement*/, $length/*:uint = 10*/ )/*:void*/{
	if( $length ){}else{
		$length = 10;
	}
	this._log = [];
	this.Log = function( $log/*:String*/ )/*:void*/{
		var temp, i, j, log;
		temp = this._log;
		log = this._log = [];
		for( i = 0, j = $length ; i &lt; j ; i += 1 ){
			log[i] = temp[i+1];
		}
		log[j] = $log;
		$logger.innerHTML = log.join( '&lt;br&gt;' );
	};
}

}
</pre>
<p>위에서 한 번에 innerHTML에 표시될 양은 $length에 지정된 만큼이므로 내용이 무한이 길어지면서 폭주하는 일을 방지합니다. 다음과 같이 초기화하여 사용할 수 있습니다.</p>
<pre>
bs.Log( document.getElementById( 'console' ), 10 );

bs.Log( 'test1' );
bs.Log( 'test2' );
...
</pre>
<p>아마도 곧 차기 버전에서는 <strong>circle Stack</strong>을 이용하는 쪽으로 개선될 듯 합니다.<br />
<strong>circle Stack</strong>과 관련된 내용은 <strong><a rel="nofollow" target="_blank" href="http://www.diebuster.com/flash/7">여기</a></strong>를 참고하세요.</p>
<p>©2012 bsidesoft.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/LXccO3vClX0" height="1" width="1"/>]]></content:encoded>
         <category>01. JS Base</category>
      <feedburner:origLink>http://zero.diebuster.com/zero/?p=12</feedburner:origLink></item>
      <item>
         <title>JS 블로그 운영시작합니다.</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/50nrEXADahU/</link>
         <description>현실적으로 플래시의 세력은 급격하게 줄어들고 있습니다. 물론 플렉스가 아파치로 넘어가고, 유니티 등의 다양한 툴에서 플래시 출력을 지원하는 등 새로운 기회는 여전히 다가오고 있습니다. 하지만 현 시점에서 JS(자바스크립트)가 매우 중요해지고 있다는 점은 누구나 인식할 수 있는 수준입니다. 따라서 다이버스터도 원래의 플래시 &amp;#8230; &lt;a rel="nofollow" target="_blank" href="http://zero.diebuster.com/zero/?p=11"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">http://zero.diebuster.com/zero/?p=11</guid>
         <pubDate>Wed, 18 Jan 2012 02:26:43 +0000</pubDate>
         <content:encoded><![CDATA[<p><span id="more-11"></span><br />
현실적으로 플래시의 세력은 급격하게 줄어들고 있습니다.<br />
물론 플렉스가 아파치로 넘어가고, 유니티 등의 다양한 툴에서 플래시 출력을 지원하는 등 새로운 기회는 여전히 다가오고 있습니다.</p>
<p>하지만 현 시점에서 JS(자바스크립트)가 매우 중요해지고 있다는 점은 누구나 인식할 수 있는 수준입니다. 따라서 다이버스터도 원래의 플래시 개발을 다루는 <strong><a rel="nofollow" target="_blank" href="http://www.diebuster.com/flash">dieBuster Flash</a></strong>와 별도로 <strong>dieBuster Zero</strong>에서는 JS만 전문적으로 포스팅하게 됩니다. 특히 <strong>bs</strong>라 불리는 제 라이브러리를 작성하면서 느낀 여러 가지 실무적인 코드를 중심으로 포스팅할 예정입니다.</p>
<p><strong>P.S<br />
</strong>제 회사인 비사이드소프트도 올해 JS시장을 집중적으로 투자하고 있는데, 그 일환으로 <strong><a rel="nofollow" target="_blank" href="http://js.bsidesoft.com">JS이야기</a></strong>라는 사이트도 병행하여 운영하는 중입니다. <strong>JS이야기</strong>는 위의 메뉴를 통해서도 들어가실 수 있습니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/50nrEXADahU" height="1" width="1"/>]]></content:encoded>
         <category>00. JS</category>
      <feedburner:origLink>http://zero.diebuster.com/zero/?p=11</feedburner:origLink></item>
      <item>
         <title>Away3D 3.6</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/nMO71HqrxN0/510</link>
         <description>제가 번역한 책이 곧 출간되는군요. 파워플 멤버 모두 수고 많았음. 그간 날 믿고 잘 따라와줘서 고맙고 ^^ 팀원들 모두에게 좋은 선물과 기억이 되길.</description>
         <guid isPermaLink="false">http://www.diebuster.com/flash/?p=510</guid>
         <pubDate>Wed, 21 Dec 2011 10:27:00 +0000</pubDate>
         <content:encoded><![CDATA[<p><img src="https://lh5.googleusercontent.com/-ykbTINTGuSc/TvGzPebmynI/AAAAAAAAAbk/yTEVitt6lTI/s512/Away3D%2525203.6%252520Essentials%252520%2525ED%252595%25259C%2525EA%2525B5%2525AD%2525EC%252596%2525B4%2525ED%25258C%252590_%2525ED%252591%25259C%2525EC%2525A7%2525801.jpg" alt=""/></p>
<p>제가 번역한 책이 곧 출간되는군요.</p>
<p>파워플 멤버 모두 수고 많았음. 그간 날 믿고 잘 따라와줘서 고맙고 ^^</p>
<p>팀원들 모두에게 좋은 선물과 기억이 되길.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/nMO71HqrxN0" height="1" width="1"/>]]></content:encoded>
         <category>4 3D</category>
      <feedburner:origLink>http://www.diebuster.com/flash/510</feedburner:origLink></item>
      <item>
         <title>HipHop Virtual Machine for PHP - Ajaxian</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/gRmSNeZIDOs/hiphop-virtual-machine-for-php</link>
         <description>PHPの VM時代開幕!(PHP의 VM시대 개막!)</description>
         <guid isPermaLink="false" />
         <pubDate>Sun, 11 Dec 2011 08:46:06 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://ajaxian.com/archives/hiphop-virtual-machine-for-php" title="HipHop Virtual Machine for PHP - Ajaxian"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fajaxian.com%2F" alt=""/><a rel="nofollow" target="_blank" href="http://ajaxian.com/archives/hiphop-virtual-machine-for-php">HipHop Virtual Machine for PHP - Ajaxian</a></cite><p>Topics .NET (69) 3D (7) Accessibility (57) Adobe (94) Advertising (3) Ajax (386) Ajaxian.com Announcements (16) Android (5) Animation (5) Announcements (104) Appcelerator (3) Apple (20) Aptana (30) Ar...</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://ajaxian.com/archives/hiphop-virtual-machine-for-php"><img src="http://b.hatena.ne.jp/entry/image/http://ajaxian.com/archives/hiphop-virtual-machine-for-php" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - HipHop Virtual Machine for PHP - Ajaxian" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - HipHop Virtual Machine for PHP - Ajaxian" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://ajaxian.com/archives/hiphop-virtual-machine-for-php"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111211#bookmark-71613141">hika00</a>  PHPの VM時代開幕!(PHP의 VM시대 개막!)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/gRmSNeZIDOs" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://ajaxian.com/archives/hiphop-virtual-machine-for-php</feedburner:origLink></item>
      <item>
         <title>자바스크립트 코딩 기법과 핵심 패턴</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/6W8xd_pQkXU/</link>
         <description>자바스크립트 코딩 기법과 핵심 패턴 스토얀 스테파노프 지음 / 김준기, 변유진 번역 / 인사이트 이 책을 처음 서점에서 보곤 인사이트가 대단하다는 생각을 안할 수가 없었습니다. 나름 유명한 책인데 정말 책 내용상 몇 권 안팔릴 책이라 이게 역서로 나오긴 무리겠다라고 생각했던 책이거든요. 그걸 떡하니 역서로 내다니 참 인사이트..대단합니다. 이 책은 제목에는 패턴이라고 되어있습니다만 사실 패턴 책은 [...]</description>
         <guid isPermaLink="false">http://book.diebuster.com/book/?p=308</guid>
         <pubDate>Sat, 03 Dec 2011 13:27:01 +0000</pubDate>
         <content:encoded><![CDATA[<div style="text-align:center;margin-bottom:10px;"><a rel="nofollow" target="_blank" href="http://www.aladin.co.kr/shop/wproduct.aspx?ISBN=8966260152&#038;ttbkey=ttbhika001342002&#038;COPYPaper=1"><img src="http://image.aladin.co.kr/product/1368/9/cover/8966260152_1.jpg" alt="" title="&#x00c790;&#x00bc14;&#x00c2a4;&#x00d06c;&#x00b9bd;&#x00d2b8; &#x00cf54;&#x00b529; &#x00ae30;&#x00bc95;&#x00acfc; &#x00d575;&#x00c2ec; &#x00d328;&#x00d134;" style="border:1px solid #666;margin-bottom:5px;"/><br />
자바스크립트 코딩 기법과 핵심 패턴<br />
스토얀 스테파노프 지음 / 김준기, 변유진 번역 / 인사이트</a></div>
<p>이 책을 처음 서점에서 보곤 인사이트가 대단하다는 생각을 안할 수가 없었습니다. 나름 유명한 책인데 정말 책 내용상 몇 권 안팔릴 책이라 이게 역서로 나오긴 무리겠다라고 생각했던 책이거든요. 그걸 떡하니 역서로 내다니 참 인사이트..대단합니다.</p>
<p>이 책은 제목에는 패턴이라고 되어있습니다만 사실 패턴 책은 아닙니다.</p>
<p>이 책은 뭐랄까 제 안에서 딱히 정의하자면 현대 자바스크립트 언어론 이라 불러야할 듯합니다. 더글라스 크락포드의 javascript good part이래로 프로토타입 언어를 어떻게 다룰지 집중적으로 조명한 책은 매우 드물었습니다. 클로저나 프로토타입 자체에 대한 설명을 하고 그 개념을 설명하기 위한 정도의 샘플은 많은 책들에 있지만, 그래서 실무적으로 정말 어떻게 쓰는게 좋은지 나쁜점은 무엇인지를 정확하게 짚어가는 책은 거의 없었죠.</p>
<p>그런 면에서 이제 더글라스의 책을 과거의 유물로 만들 다음 세대의 책이라 불러도 좋은 정도의 책이 역서로 나왔다는 사실이 매우 기쁩니다.</p>
<p>(너무 기뻐서 이번에 이 책으로 스터디도 합니다!)</p>
<p>흥분해서 책의 내용에 대해서 얘길 못했군요 ^^;</p>
<p>이 책은 자바스크립트의 동적 특성, 함수언어적인 특성, 프로토타입적인 특성을 차근차근 설명하고, 그 특성을 다른 OOP언어형태나 제어형 구문에 대입하면 어떤 식으로 활용해야 좋은지, 혹은 나쁜지를 매우 세세하게 다루고 있습니다. 또한 자바스크립트 언어 자체의 특성에서 기인한 기법도 충실히 다루고 자바스크립트를 개발하기 위한 툴이나 환경, 코드 관리에 대해서도 어느 정도는 다루고 있습니다.</p>
<p>기존 GOF의 디자인패턴을 예로 들어 아키텍쳐를 짤 때 자바스크립트 식의 구조는 어떻게 잡아야하는지도 가르치는 그야말로 훌륭한 책입니다(여전히 흥분 중)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/6W8xd_pQkXU" height="1" width="1"/>]]></content:encoded>
         <category>Books</category>
      <feedburner:origLink>http://book.diebuster.com/book/?p=308</feedburner:origLink></item>
      <item>
         <title>비즈니스 모델의 탄생</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/Zwj3NuWlnjI/</link>
         <description>비즈니스 모델의 탄생 알렉산더 오스터왈더, 예스 피그누어 지음 / 유효상 번역 / 타임비즈 경영학 과정에서 사업기획과 관련된 부분만 모아놓은 듯한 책입니다. 현대 경영학을 이해하기 쉽게 풀어내고 동시에 사업기획에 어떻게 적용할 것인가를 잘 정리했습니다. 아내가 보려고 사왔지만 제가 틈틈히 보면서 즐거워하고 있습니다. 그나저나 이 책은 도식화가 짱인듯. 번역하신 분도 대단히 고생했을 듯합니다. 가볍게 사업기획과 관련된 기초지식을 [...]</description>
         <guid isPermaLink="false">http://book.diebuster.com/book/?p=307</guid>
         <pubDate>Sat, 03 Dec 2011 13:12:02 +0000</pubDate>
         <content:encoded><![CDATA[<div style="text-align:center;margin-bottom:10px;"><a rel="nofollow" target="_blank" href="http://www.aladin.co.kr/shop/wproduct.aspx?ISBN=8992939949&#038;ttbkey=ttbhika001342002&#038;COPYPaper=1"><img src="http://image.aladin.co.kr/product/1338/92/letslook/8928607191_fs.jpg" alt="" title="&#x00be44;&#x00c988;&#x00b2c8;&#x00c2a4; &#x00baa8;&#x00b378;&#x00c758; &#x00d0c4;&#x00c0dd;" style="border:1px solid #666;margin-bottom:5px;"/><br />
비즈니스 모델의 탄생<br />
알렉산더 오스터왈더, 예스 피그누어 지음 / 유효상 번역 / 타임비즈</a></div>
<p>경영학 과정에서 사업기획과 관련된 부분만 모아놓은 듯한 책입니다. 현대 경영학을 이해하기 쉽게 풀어내고 동시에 사업기획에 어떻게 적용할 것인가를 잘 정리했습니다. 아내가 보려고 사왔지만 제가 틈틈히 보면서 즐거워하고 있습니다.</p>
<p>그나저나 이 책은 도식화가 짱인듯. 번역하신 분도 대단히 고생했을 듯합니다.</p>
<p>가볍게 사업기획과 관련된 기초지식을 쌓고 싶으신 분들에게 추천합니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/Zwj3NuWlnjI" height="1" width="1"/>]]></content:encoded>
         <category>Books</category>
      <feedburner:origLink>http://book.diebuster.com/book/?p=307</feedburner:origLink></item>
      <item>
         <title>뇌를 자극하는 C# 4.0 프로그래밍</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/FLlEZBLelI4/</link>
         <description>뇌를 자극하는 C# 4.0 프로그래밍 박상현 지음/한빛미디어 c#을 순수하게 언어론으로 다루고 있는 책입니다. 친절하기도 하고 언어의 각 부분에 대해 잘 설명해주려고 노력한 저자의 노고가 느껴집니다. 반대로 닷넷은 거의 다루지 않고 있기 때문에 언어 자체를 이해하기는 좋지만 어플을 작성하기엔 무리입니다. 하지만 닷넷에 대한 책은 많이 있습니다. 바로 직전에 리뷰한 Programming .NET 3.5 같은 책을 참고하면 됩니다. [...]</description>
         <guid isPermaLink="false">http://book.diebuster.com/book/?p=313</guid>
         <pubDate>Sat, 03 Dec 2011 13:02:22 +0000</pubDate>
         <content:encoded><![CDATA[<div style="text-align:center;margin-bottom:10px;"><a rel="nofollow" target="_blank" href="http://www.aladin.co.kr/shop/wproduct.aspx?ISBN=8979148518&#038;ttbkey=ttbhika001342002&#038;COPYPaper=1"><img src="http://image.aladin.co.kr/product/1284/41/cover/8979148518_1.jpg" alt="" title="&#x00b1cc;&#x00b97c; &#x00c790;&#x00adf9;&#x00d558;&#x00b294; C# 4.0 &#x00d504;&#x00b85c;&#x00adf8;&#x00b798;&#x00bc0d;" style="border:1px solid #666;margin-bottom:5px;"/><br />
뇌를 자극하는 C# 4.0 프로그래밍<br />
박상현 지음/한빛미디어</a></div>
<p>c#을 순수하게 언어론으로 다루고 있는 책입니다. 친절하기도 하고 언어의 각 부분에 대해 잘 설명해주려고 노력한 저자의 노고가 느껴집니다.<br />
반대로 닷넷은 거의 다루지 않고 있기 때문에 언어 자체를 이해하기는 좋지만 어플을 작성하기엔 무리입니다.<br />
하지만 닷넷에 대한 책은 많이 있습니다. 바로 직전에 리뷰한 <a rel="nofollow" target="_blank" href="http://book.diebuster.com/book/?p=306">Programming .NET 3.5</a> 같은 책을 참고하면 됩니다.</p>
<p>c# 4.0에 지원되는 람다와 같은 최신 기능을 구체적으로 설명하고 있습니다. 책이 <a rel="nofollow" target="_blank" href="http://book.diebuster.com/book/?p=21">이펙티브 c#</a>과 같은 관점으로 언어의 최적화쪽을 다루지 않는 건 아쉽지만 초보자를 위한 구성이라 그럴거라 생각합니다. 전반적으로 만족하고 있습니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/FLlEZBLelI4" height="1" width="1"/>]]></content:encoded>
         <category>Books</category>
      <feedburner:origLink>http://book.diebuster.com/book/?p=313</feedburner:origLink></item>
      <item>
         <title>Programming .NET 3.5</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/LiuhM-pmM6E/</link>
         <description>Programming .NET 3.5 제시 리버티, 알렉스 호로비츠 지음/ 한용희 번역 / ITC .NET FRAMEWORK 는 여러 가지 서비스를 제공하지만 실무적인 개발자 입장에선 역시 어떤 기능을 어떤 방식으로 제공하는가가 가장 궁금합니다. 닷넷은 코드형 프로그래밍을 위한 클래스 구조물도 물론 제공하지만 XAML로 대표되는 XML선형언어를 통해 놀랍도록 코드없이도 세부적인 사항을 정의할 수 있는 특징이 있습니다. 다른 언어도 여러 가지 [...]</description>
         <guid isPermaLink="false">http://book.diebuster.com/book/?p=306</guid>
         <pubDate>Sat, 03 Dec 2011 12:55:42 +0000</pubDate>
         <content:encoded><![CDATA[<div style="text-align:center;margin-bottom:10px;"><a rel="nofollow" target="_blank" href="http://www.aladin.co.kr/shop/wproduct.aspx?ISBN=8963510069&#038;ttbkey=ttbhika001342002&#038;COPYPaper=1"><img src="http://image.aladin.co.kr/product/364/12/cover/8963510069_1.jpg" alt="" title="Programming .NET 3.5" style="border:1px solid #666;margin-bottom:5px;"/><br />
Programming .NET 3.5<br />
제시 리버티, 알렉스 호로비츠 지음/ 한용희 번역 / ITC</a></div>
<p>.NET FRAMEWORK 는 여러 가지 서비스를 제공하지만 실무적인 개발자 입장에선 역시 어떤 기능을 어떤 방식으로 제공하는가가 가장 궁금합니다. 닷넷은 코드형 프로그래밍을 위한 클래스 구조물도 물론 제공하지만 XAML로 대표되는 XML선형언어를 통해 놀랍도록 코드없이도 세부적인 사항을 정의할 수 있는 특징이 있습니다. 다른 언어도 여러 가지 선형 언어를 제공하지만 XAML은 그런 언어 중에는 개인적으로 최고라고 생각합니다.</p>
<p>이 책은 그러한 XAML을 중심으로 닷넷의 다양한 기능을 설명합니다. 중간중간 양념으로 c#을 쓰는 느낌이랄까요. 복잡한 프로그래밍 개념이 없어도 XML로 구축하는 강력한 윈도우즈 어플리케이션의 세계로 빠져보실 수 있습니다.</p>
<p>사실 개인적으로 요즘 다시 깊이 닷넷에 빠지고 있는데(실은 XNA스튜디오 때문이긴 하지만) 딱히 현재 윈도우즈를 버릴 것도 아니고 윈도우즈에서 닷넷 어플을 만드는 것처럼 쉽게 되는 것도 없고.. 이제 와서 맥을 커버할 것도 아닌데(아이폰은 커버하지만 ^^) 역시 닷넷인가 싶습니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/LiuhM-pmM6E" height="1" width="1"/>]]></content:encoded>
         <category>Books</category>
      <feedburner:origLink>http://book.diebuster.com/book/?p=306</feedburner:origLink></item>
      <item>
         <title>NHN은 이렇게 한다! 자바스크립트 UI 개발과 Jindo 프레임워크</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/FOxr6_wIvx8/</link>
         <description>NHN은 이렇게 한다! 자바스크립트 UI 개발과 Jindo 프레임워크 손병대, 박재성 지음/위키북스 이 책은 NHN의 자바스크립트 프레임웍인 Jindo에 대해 설명하는 책입니다. 책 자체는 국내서임을 고려하면 상당히 깊은 부분까지 다루고 있는 좋은 책입니다. Jindo 자체에 대한 설명이라기보다 현대 자바스크립트를 실무에서 사용하는 여러 가지 방법에 대해 설명하는 쪽입니다. 물론 그 중심에 Jindo를 활용하는 호스트코드 예시를 사용합니다만 날 자바스크립트 [...]</description>
         <guid isPermaLink="false">http://book.diebuster.com/book/?p=301</guid>
         <pubDate>Sat, 03 Dec 2011 12:20:50 +0000</pubDate>
         <content:encoded><![CDATA[<div style="text-align:center;margin-bottom:10px;"><a rel="nofollow" target="_blank" href="http://www.aladin.co.kr/shop/wproduct.aspx?ISBN=8992939949&#038;ttbkey=ttbhika001342002&#038;COPYPaper=1"><img src="http://image.aladin.co.kr/product/1344/97/cover/8992939949_1.jpg" alt="" title="NHN&#x00c740; &#x00c774;&#x00b807;&#x00ac8c; &#x00d55c;&#x00b2e4;! &#x00c790;&#x00bc14;&#x00c2a4;&#x00d06c;&#x00b9bd;&#x00d2b8; UI &#x00ac1c;&#x00bc1c;&#x00acfc; Jindo &#x00d504;&#x00b808;&#x00c784;&#x00c6cc;&#x00d06c;" style="border:1px solid #666;margin-bottom:5px;"/><br />
NHN은 이렇게 한다! 자바스크립트 UI 개발과 Jindo 프레임워크<br />
손병대, 박재성 지음/위키북스</a></div>
<p>이 책은 NHN의 자바스크립트 프레임웍인 Jindo에 대해 설명하는 책입니다. 책 자체는 국내서임을 고려하면 상당히 깊은 부분까지 다루고 있는 좋은 책입니다.<br />
Jindo 자체에 대한 설명이라기보다 현대 자바스크립트를 실무에서 사용하는 여러 가지 방법에 대해 설명하는 쪽입니다. 물론 그 중심에 Jindo를 활용하는 호스트코드 예시를 사용합니다만 날 자바스크립트 코드도 다수 포함되어 기본 설명에 충실합니다.</p>
<p>하지만 Jindo 그 자체는 Jquery 짝퉁일 뿐입니다. 왜 만들었냐고 물어보면 오픈소스를 쓰면 회사 맘대로 기능을 추가하거나 고치기 어렵기 때문이죠.<br />
모든 아이디어와 설계론을 싹다 배껴서 적당히 한 두가지 수정했다고 NHN의 프레임웍이라 불러달라는건 농담에도 정도가 있습니다.<br />
회사 입맛대로 고쳐가는 프레임웍을 공개해서 오픈소스라 불러달라는건 더 질나쁜 농담이죠.</p>
<p>하고 싶은 말은 많지만, 북리뷰 포스팅은 여태 중도를 지켜왔는데 간만에 흥분해보네요.</p>
<p>오픈소스 생태계를 구축하고 오픈소스 그 자체를 지켜간다는건 특정 회사가 입맛대로 굴리는 소스 좀 공개했다고 되는게 아니죠. 책은 기껏 잘 써놓고 Jindo와 오픈소스, 제이쿼리 같은 것과 비교해서 우습고도 분노스러운 결과물이 되었다는..</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/FOxr6_wIvx8" height="1" width="1"/>]]></content:encoded>
         <category>Books</category>
      <feedburner:origLink>http://book.diebuster.com/book/?p=301</feedburner:origLink></item>
      <item>
         <title>Loop와 getTimer</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/y8f1CAXfMi4/502</link>
         <description>전에 작성한 포스트 중 다음과 같은 글이 있습니다. Non blocking loop 이 글에서 동기화 로직인 루프로 인해 프로그램이 타임아웃으로 다운되거나 먹통이 되는 현상을 어떻게 처리하는지 살펴봤습니다. 오늘은 약간 다른 접근을 해보려고 합니다. 동기화 로직인 for나 while을 사용해도 적절한 시점에 빠져 나오는 기법입니다. 이 방법을 사용하면 특정 반복구문 하나가 시간을 계속 끌지 않게 되어 스크립트 타임아웃이 [...]</description>
         <guid isPermaLink="false">http://www.diebuster.com/flash/?p=502</guid>
         <pubDate>Sat, 26 Nov 2011 05:04:00 +0000</pubDate>
         <content:encoded><![CDATA[<p>전에 작성한 포스트 중 다음과 같은 글이 있습니다.</p>
<p><a rel="nofollow" target="_blank" href="http://www.diebuster.com/flash/180">Non blocking loop</a></p>
<p>이 글에서 동기화 로직인 루프로 인해 프로그램이 타임아웃으로 다운되거나 먹통이 되는 현상을 어떻게 처리하는지 살펴봤습니다.</p>
<p>오늘은 약간 다른 접근을 해보려고 합니다.</p>
<p>동기화 로직인 for나 while을 사용해도 적절한 시점에 빠져 나오는 기법입니다.</p>
<p>이 방법을 사용하면 특정 반복구문 하나가 시간을 계속 끌지 않게 되어 스크립트 타임아웃이 일어나지 않습니다. 단지 먹통 자체는 그대로 일어납니다.</p>
<p><span id="more-502"></span></p>
<h4>간단한 while구문</h4>
<p>동기화로 먹통을 만드는 간단한 while구문을 하나 작성해보죠.</p>
<pre>
var count:int, arr:Array;

arr = [];

while( count &amp;lt; 10000000 ){

	arr[count] = count;
	count = count + 1;

}
</pre>
<p>간단하지만 컴터의 cpu성능에 따라 꽤나 먹통으로 만들어줍니다. 게다가 15초를 넘어가면 타임아웃이니 더 큰 숫자를 넣어야 할 경우는 어찌해야 하냐는 거죠.</p>
<h4>하지만 시간은 흐른다.</h4>
<p>그렇습니다. 컴터는 반복처리를 하느라 먹통이지만 시간은 흐릅니다. 타이머는 내부적으로 avm2가 갖고 있는 속성이라기보다 플래시 플레이어 수준에서 OS에게 받아오는 값입니다(그래서 getTimer호출은 비용이 꽤 듭니다)</p>
<p>따라서 동기화로직을 처리하는건 avm2의 사정이고 OS수준에서의 시간은 계속 흐르고 있으므로 루프 중에도 시간을 조회해보면 갱신되고 있습니다. 그걸 코드로 표현하면 아래와 같겠죠.</p>
<pre>
var count:int, arr:Array;

arr = [];

while( count &amp;lt; 10000000 ){

	arr[count] = count;
	count = count + 1;

	switch( count ){
	case 1000000: case 2000000: case 3000000: case 4000000: case 5000000:
	case 6000000: case 7000000: case 8000000: case 9000000:
		trace( getTimer() );
	}
}
</pre>
<p>백만카운터니 십만단위로 시간을 체크해봅시다. 그럼 trace에 찍힌 값이 점점 증가하고 있는걸 알 수 있습니다. 만약 여러분의 컴터가 너무 고속이거나 저속이라면 적당히 카운터를 조정하세요.</p>
<p>위의 결과를 보면 while중에도 여전히 getTimer를 이용해 탈출할 수 있다는 사실을 알 수 있습니다. 최초 시작시간으로 부터 1초가 지나면 탈출하게 작성하면 다음과 같습니다.</p>
<pre>
var count:int, arr:Array, start:uint;

arr = [];
start = getTimer();

loop: while( count &amp;lt; 10000000 ){

	arr[count] = count;
	count = count + 1;
	switch( count ){
	case 1000000: case 2000000: case 3000000: case 4000000: case 5000000:
	case 6000000: case 7000000: case 8000000: case 9000000:
		if( getTimer() &amp;gt; start + 1000 ){
			break loop;
		}
	}
}
</pre>
<h4>루프를 빠져 나온 뒤의 문제</h4>
<p>루프는 타임아웃이 걸리기 전에 탈출할 수 있지만 그렇다고 문제가 해결된 것은 아닙니다. 왜냐면 스크립트 엔진은 우리가 생각하는 것보다 지능적이라서 단일 반복문이 타임아웃거리는 상황만 감시하는게 아니라 명령스택 전체를 감시하기 때문입니다.</p>
<p>위의 상황에서 2십만번째에 탈출해도 다시 2십만 1에서 시작하려고 하면 다음과 같은 형태가 됩니다.</p>
<pre>
while(...){
	...
}
while(...){
	...
}
</pre>
<p>혹은 함수로 호출해도 마찬가지입니다.</p>
<pre>
function loop():Boolean{
	while(...){
		...
	}
	return ( 여전히 반복해야 하나? )
}

function action():void{
	if( loop() ){
		action();
	}
}

action();
</pre>
<p>이런식으로 빙빙 돌려 중첩 루프가 아니게 만들어도 똘똘한 스크립트엔진은 한 번에 실행될 동기구문의 전체 스택을 파악하여 시간을 감시하기 때문에 여전히 타임아웃이 걸리게 됩니다.</p>
<h4>비동기와의 결합</h4>
<p>따라서 결국 끊어야 합니다. 동기화 실행의 한계는 여전히 있는 거죠. 그럼 기존에 다뤘던 넌브로킹 루프와의 차이는 뭘까요?</p>
<p>만약 while안에서 getTimer로 끊어내지 않는다면 개발자가 매번 여러 가지 상황에 따라 반복할 횟수를 정해야 합니다. 또한 그러한 횟수는 기계의 성능에 따라 달라지기 때문에 설정 값 자체가 쓸모 없게 되는 경우도 발생합니다. 넌브로킹 루프의 샘플을 개선해봅시다.</p>
<p>기존 소스를 보면 두번째 인자로 리미트를 받습니다. 한프레임에서 얼마나 실행할지를 지정하는 것이죠. 하지만 이게 바로 문제의 근원입니다.</p>
<pre>
class nonBlockingLoop{

	var looper:Shape = new Shape;

	public function nonBlockingLoop(){}

	public function loop( $counter:int, $limit:int, $runner:Function, ...$param ):void{
		var counter:int;
		looper.addEventListener( Event.ENTER_FRAME, function( $e:Event ):void{
			var i:int;
			while( i++ &amp;lt; $limit ){
				if( counter &amp;lt; $counter ){
					//$param.unshift( counter ); 필요하면 counter도 넘...
					if( $param.length ){ //rest인자는 null인 경우가 없음
						$runner.apply( null, $param );
					}else{
						$runner();
					}
					++counter;
				}else{
					looper.removeEventListener( $e.type, arguments.callee );
				}
			}
		});
	}
}
</pre>
<p>리미트에 적당한 값을 지정하는건 컴터마다 성능이 다르기 때문에 불가능하기 때문입니다. 따라서 가장 적합한 값은 숫자가 아니라 시간입니다. 두번째인자를  $limit에서 $limitTime으로 변경해보겠습니다.</p>
<pre>
class nonBlockingLoop{

	var looper:Shape = new Shape;

	public function nonBlockingLoop(){}

	public function loop( $counter:int, $limitTime:int, $runner:Function, ...$param ):void{
		var counter:int;
		looper.addEventListener( Event.ENTER_FRAME, function( $e:Event ):void{
			var start:int;

			start = getTimer();
			while( getTimer() &amp;lt; start + $limitTime ){
				if( counter &amp;lt; $counter ){
					if( $param.length ){
						$runner.apply( null, $param );
					}else{
						$runner();
					}
					++counter;
				}else{
					looper.removeEventListener( $e.type, arguments.callee );
				}
			}
		});
	}
}
</pre>
<p>루프에서 시간을 체크하는 로직으로 변경하여 더 이상 컴터마다 카운터를 따로 지정해야하는 애매함을 제거하고 공통적으로 시간당 처리능력에 따라 적절히 분산되는 코드로 변경되었습니다.<br />
호스트 코드로 보면 다음과 같습니다.</p>
<pre>
var looper:nonBlockingLoop = new nonBlockingLoop;

function test( $val1:String, $val2:int ):void{
	trace( $val1, $val2 );
}

looper.loop( 999999, 5000, test, '안녕', 37 ); //반복하다 5초가 넘어가면 다음 프레임으로 넘긴다.
</pre>
<h4>결론</h4>
<p>동기화 로직 중에 시간을 이용해 빠져나오는 기술은 개별 컴터의 성능을 따로 측정하지 않아도 일정한 부하만 주며 반복작업을 처리할 수 있게 해주는 강력한 방법입니다.<br />
일단 동기화 로직 중에 빠져나올 근거가 단순한 변수 외에도 시간을 사용할 수 있다는 점 자체만 해도 매우 다양한 알고리즘을 짤 수 있게 합니다. 꼭 <a rel="nofollow" target="_blank" href="http://www.diebuster.com/flash/180">Non blocking loop</a> 와 이어서 보시길 바랍니다 ^^</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/y8f1CAXfMi4" height="1" width="1"/>]]></content:encoded>
         <category>3 흐름제어</category>
      <feedburner:origLink>http://www.diebuster.com/flash/502</feedburner:origLink></item>
      <item>
         <title>Playing: 3D Monster Truck Tower on FunFastGame.com</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/sKWfBJVQWKA/3d-monster-truck-tower.html</link>
         <description>flash11 game</description>
         <guid isPermaLink="false" />
         <pubDate>Fri, 25 Nov 2011 15:39:14 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://www.funfastgame.com/game/4357/3d-monster-truck-tower.html" title="Playing: 3D Monster Truck Tower on FunFastGame.com"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fwww.funfastgame.com%2F" alt=""/><a rel="nofollow" target="_blank" href="http://www.funfastgame.com/game/4357/3d-monster-truck-tower.html">Playing: 3D Monster Truck Tower on FunFastGame.com</a></cite><p>More Yakuza 5 details unfoldNov 25, 2011  Upcoming sequel set for PS3 featuring new engine; Sega to search for &quot;Miss ...Ragnarok Odyssey landing in Japan February 2012Nov 25, 2011  PS Vita entry in lo...</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://www.funfastgame.com/game/4357/3d-monster-truck-tower.html"><img src="http://b.hatena.ne.jp/entry/image/http://www.funfastgame.com/game/4357/3d-monster-truck-tower.html" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Playing: 3D Monster Truck Tower on FunFastGame.com" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Playing: 3D Monster Truck Tower on FunFastGame.com" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://www.funfastgame.com/game/4357/3d-monster-truck-tower.html"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111126#bookmark-69185121">hika00</a>  flash11 game</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/sKWfBJVQWKA" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://www.funfastgame.com/game/4357/3d-monster-truck-tower.html</feedburner:origLink></item>
      <item>
         <title>Introducing open source evoSpicyParticleEngine « simppa.fi/blog</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/tcZKcUL8GEI/</link>
         <description>flash11용 open source particle engine</description>
         <guid isPermaLink="false" />
         <pubDate>Fri, 25 Nov 2011 04:15:55 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://www.simppa.fi/blog/introducing-open-source-evospicyparticleengine/" title="Introducing open source evoSpicyParticleEngine &#xab; simppa.fi/blog"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fwww.simppa.fi%2F" alt=""/><a rel="nofollow" target="_blank" href="http://www.simppa.fi/blog/introducing-open-source-evospicyparticleengine/">Introducing open source evoSpicyParticleEngine « simppa.fi/blog</a></cite><p><a rel="nofollow" target="_blank" href="http://www.simppa.fi/blog/introducing-open-source-evospicyparticleengine/"><img src="http://cdn-ak.b.st-hatena.com/entryimage/69105405-1322194582.jpg" alt="Introducing open source evoSpicyParticleEngine &#xab; simppa.fi/blog" title="Introducing open source evoSpicyParticleEngine &#xab; simppa.fi/blog" class="entry-image"/></a></p><p>In this post I’m going to explain some of my findings when playing around with Adobe’s Stage3D and particles. I have pushed the current version of particle engine called evoSpicyParticleEngine into Gi...</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://www.simppa.fi/blog/introducing-open-source-evospicyparticleengine/"><img src="http://b.hatena.ne.jp/entry/image/http://www.simppa.fi/blog/introducing-open-source-evospicyparticleengine/" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Introducing open source evoSpicyParticleEngine &#xab; simppa.fi/blog" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Introducing open source evoSpicyParticleEngine &#xab; simppa.fi/blog" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://www.simppa.fi/blog/introducing-open-source-evospicyparticleengine/"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111125#bookmark-69105405">hika00</a>  flash11용 open source particle engine</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/tcZKcUL8GEI" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://www.simppa.fi/blog/introducing-open-source-evospicyparticleengine/</feedburner:origLink></item>
      <item>
         <title>(en) Alternativa3D 8.17 Custom materials, shaders and intersectionRay | Flastar</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/DmAM9bCdSBQ/1223</link>
         <description>alternativa 8.x でカスタム材質を作る方法と光線交差点処理(alternativa 8.x 에서 커스텀 재질을 만드는 방법과 광선교차점 처리)</description>
         <guid isPermaLink="false" />
         <pubDate>Mon, 07 Nov 2011 11:49:17 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://flastar.ru/blog/flastarposts/1223" title="(en) Alternativa3D 8.17 Custom materials, shaders and intersectionRay | Flastar"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fflastar.ru%2F" alt=""/><a rel="nofollow" target="_blank" href="http://flastar.ru/blog/flastarposts/1223">(en) Alternativa3D 8.17 Custom materials, shaders and intersectionRay | Flastar</a></cite><p><a rel="nofollow" target="_blank" href="http://flastar.ru/blog/flastarposts/1223"><img src="http://cdn-ak.b.st-hatena.com/entryimage/66541117-1320666576.jpg" alt="(en) Alternativa3D 8.17 Custom materials, shaders and intersectionRay | Flastar" title="(en) Alternativa3D 8.17 Custom materials, shaders and intersectionRay | Flastar" class="entry-image"/></a></p><p>In this lesson I’ll show you how to create custom materials and shaders with Alternativa3D 8.17.0. (clickable) When you develop molehill-projects, often arise situtations when you need more features i...</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://flastar.ru/blog/flastarposts/1223"><img src="http://b.hatena.ne.jp/entry/image/http://flastar.ru/blog/flastarposts/1223" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - (en) Alternativa3D 8.17 Custom materials, shaders and intersectionRay | Flastar" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - (en) Alternativa3D 8.17 Custom materials, shaders and intersectionRay | Flastar" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://flastar.ru/blog/flastarposts/1223"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111107#bookmark-66541117">hika00</a>  alternativa 8.x でカスタム材質を作る方法と光線交差点処理(alternativa 8.x 에서 커스텀 재질을 만드는 방법과 광선교차점 처리)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/DmAM9bCdSBQ" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://flastar.ru/blog/flastarposts/1223</feedburner:origLink></item>
      <item>
         <title>FlashJS - opensource HTML5 game engine with API similar to Flash one</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/GvVUquuKUAU/</link>
         <description>html5を as3のように開発すること!!(html5를 as3처럼 개발하기!!)</description>
         <guid isPermaLink="false" />
         <pubDate>Thu, 03 Nov 2011 15:21:28 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://flashjs.com/" title="FlashJS - opensource HTML5 game engine with API similar to Flash one"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fflashjs.com%2F" alt=""/><a rel="nofollow" target="_blank" href="http://flashjs.com/">FlashJS - opensource HTML5 game engine with API similar to Flash one</a></cite><p>Write AS code into HTML FlashJS is JavaScript graphics and game development engine with API similar to Flash one. It`s HTML5 game development tool, based on verified for years Flash methodology. Just ...</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://flashjs.com/"><img src="http://b.hatena.ne.jp/entry/image/http://flashjs.com/" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - FlashJS - opensource HTML5 game engine with API similar to Flash one" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - FlashJS - opensource HTML5 game engine with API similar to Flash one" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://flashjs.com/"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111104#bookmark-66041777">hika00</a>  html5を as3のように開発すること!!(html5를 as3처럼 개발하기!!)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/GvVUquuKUAU" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://flashjs.com/</feedburner:origLink></item>
      <item>
         <title>test06_filter_Effect.html</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/YvrjerE8vKM/test06_filter_Effect.html</link>
         <description>RED2Dの多様なフィルター效果をテストして見られるページです. RED2Dは flash11用 2D framework です(RED2D의 다양한 필터효과를 테스트해 볼 수 있는 페이지 입니다. RED2D는 flash11용 2D framework 입니다)</description>
         <guid isPermaLink="false" />
         <pubDate>Mon, 24 Oct 2011 07:58:07 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://webseon.cafe24.com/blog/test06_filter_Effect/test06_filter_Effect.html" title="test06_filter_Effect.html"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fwebseon.cafe24.com%2F" alt=""/><a rel="nofollow" target="_blank" href="http://webseon.cafe24.com/blog/test06_filter_Effect/test06_filter_Effect.html">test06_filter_Effect.html</a></cite><p>To view this page ensure that Adobe Flash Player version 0.0.0 or greater is installed.</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://webseon.cafe24.com/blog/test06_filter_Effect/test06_filter_Effect.html"><img src="http://b.hatena.ne.jp/entry/image/http://webseon.cafe24.com/blog/test06_filter_Effect/test06_filter_Effect.html" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - test06_filter_Effect.html" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - test06_filter_Effect.html" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://webseon.cafe24.com/blog/test06_filter_Effect/test06_filter_Effect.html"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111024#bookmark-64523165">hika00</a>  RED2Dの多様なフィルター效果をテストして見られるページです. RED2Dは flash11用 2D framework です(RED2D의 다양한 필터효과를 테스트해 볼 수 있는 페이지 입니다. RED2D는 flash11용 2D framework 입니다)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/YvrjerE8vKM" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://webseon.cafe24.com/blog/test06_filter_Effect/test06_filter_Effect.html</feedburner:origLink></item>
      <item>
         <title>2011.10.20 일본에서 사온 3권의 책</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/mJqmLe0nS44/</link>
         <description>매번 일본 여행을 다녀올 때 마다 심하게 책을 지르고 오는 듯하여 이번엔 고심하고 또 고심하여 싼 책이지만 가치가 있는 게 뭘까 한참을 서점에서 뒤적거리며 샀습니다. 사실은 바케모노가따리의 애니메이션 컴플릿북을 사왔어야 하는데 시간도 없고 마침 간 서점엔 품절이었습니다. 암튼 하나씩 소개해보겠습니다. PhoneGap 입문 가이드 사실 개인적으로 모바일 개발에서 플래시를 사용할 생각은 전혀 없습니다. GPU가 관여한다면 오픈지엘기반으로 [...]</description>
         <guid isPermaLink="false">http://book.diebuster.com/book/?p=288</guid>
         <pubDate>Fri, 21 Oct 2011 13:37:53 +0000</pubDate>
         <content:encoded><![CDATA[<p>매번 일본 여행을 다녀올 때 마다 심하게 책을 지르고 오는 듯하여 이번엔 고심하고 또 고심하여 싼 책이지만 가치가 있는 게 뭘까 한참을 서점에서 뒤적거리며 샀습니다. 사실은 바케모노가따리의 애니메이션 컴플릿북을 사왔어야 하는데 시간도 없고 마침 간 서점엔 품절이었습니다.</p>
<p>암튼 하나씩 소개해보겠습니다.</p>
<h4>PhoneGap 입문 가이드</h4>
<p>사실 개인적으로 모바일 개발에서 플래시를 사용할 생각은 전혀 없습니다. GPU가 관여한다면 오픈지엘기반으로 제작할 뿐이고 그렇지 않다면 무조건 HTML과 자바스크립트로 개발하여 폰갭으로 포장하는 쪽만 생각하고 있습니다. 특히 네이티브 개발을 하는 것과 폰갭으로 개발된 것 사이의 차이를 인식할 만큼 고성능이 나와야하는 경우는 대부분 오픈지엘이 커버할 영역이 됩니다. 따지고 보면 유지보수나 기타 이유로 네이티브로 오픈지엘이 아닌 개발을 해야할 상황이란게 매우 미묘합니다. 그런 면에서 이런저런 국내서의 어떤 장에 찔끔찔끔 설명되어있는 것보단 체계적으로 설명된 한 권의 책이 있어야 교육할 수 있기 때문에 구입했습니다(그렇다고 직원들이 일본어가 가능해서 이걸 본다는 건 아니고, 제가 이걸 바탕으로 체계적인 교육을 해야한다는 뜻 =.=)</p>
<h4>OpenGL로 만드는 안드로이드 SDK 게임 프로그래밍</h4>
<p>이 책은 너무 반가워서 덥썩 사버렸습니다. 전에 포스팅한 책 중에 <a rel="nofollow">OpenGL로 만드는 아이폰 SDK 게임 프로그래밍</a>라는 책이 있습니다. 재밌는 건 두 책이 완벽하게 동일한 데모와 설명 순서, 라이브러리 구축 예를 제공하고 있다는 점입니다. 책을 통해 진정한 크로스플랫폼을 보여주는군요 ^^; 쨌든 아이폰 책과 마찬가지로 초 간결하면서도 깔끔한 설명이 일품입니다.</p>
<h4>키넥트핵커스매뉴얼</h4>
<p>키넥트를 이용한 다양한 구현을 다루는 책입니다. 일본 내에 여러 구현 샘플도 다루고 있으며 여러 플랫폼에서 어떻게 키넥트를 활용하는지 코드까지 제공하고 있습니다. 사실 플래시11로 넘어오면서 모델링 자체야 맥스로 어떻게 한다고 해도 일반적인 웹에이전시가 키애니메이션을 잡을 인력을 갖고 있을리가 없습니다. 캐릭터 셋업까지야 어떻게 한다고 하고 그 뒤엔 역시 싼 값에 모션캡쳐할 방법을 생각해봐야겠죠. 저도 그 일환으로 키넥트를 사용할까 생각하여 사왔습니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/mJqmLe0nS44" height="1" width="1"/>]]></content:encoded>
         <category>Books</category>
      <feedburner:origLink>http://book.diebuster.com/book/?p=288</feedburner:origLink></item>
      <item>
         <title>Alternativa3D 8.x의 구조와 bs11 #3</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/DHdhNUVTQPw/486</link>
         <description>처음부터 너무 설명만 지루하게 한 감이 없지 않습니다. 사실 3D라는 건 눈으로 보고 마우스로 만지기 위해 존재하는 거지 머리만 아프려고 공부하는 건 아니겠죠. 이 쯤에서 걍 심심풀이 구경이나 좀 하는 시간을 갖도록 하죠. 아래 공개된 작업물들은 개발과정에서 나온 일종의 부산물입니다. 그냥 버릴 수도 있지만 이게 다 역사 될지 누가 알겠습니까 ^^; 알파테스트1차 이 버전은 매우 [...]</description>
         <guid isPermaLink="false">http://www.diebuster.com/flash/?p=486</guid>
         <pubDate>Tue, 18 Oct 2011 15:32:43 +0000</pubDate>
         <content:encoded><![CDATA[<p>처음부터 너무 설명만 지루하게 한 감이 없지 않습니다. 사실 3D라는 건 눈으로 보고 마우스로 만지기 위해 존재하는 거지 머리만 아프려고 공부하는 건 아니겠죠. 이 쯤에서 걍 심심풀이 구경이나 좀 하는 시간을 갖도록 하죠. 아래 공개된 작업물들은 개발과정에서 나온 일종의 부산물입니다. 그냥 버릴 수도 있지만 이게 다 역사 될지 누가 알겠습니까 ^^;<br />
<span id="more-486"></span></p>
<h4>알파테스트1차</h4>
<p><a rel="nofollow" target="_blank" href="http://www.diebuster.com/lab/alpha0/"><img src="https://lh6.googleusercontent.com/-_gX3kGx1P7o/Tp2XfZAnInI/AAAAAAAAAPY/lQy0PRhefG4/s500/Screenshot_5.jpg" alt=""/></a></p>
<p>이 버전은 매우 초창기 프로토타입 입니다. 여러 얼터8의 내부 기능을 조사 중이었습니다. 최초 마우스를 누른 채 움직이면 카메라가 회전합니다만 그 이후 왼쪽 빨간 박스나 오른쪽의 로딩된 모델을 클릭하면 그 클릭한 대상을 회전하게 됩니다. 이런 저런 실험과 인터페이스 개선을 하고 있던 시기입니다.</p>
<h4>Geomerty의 공유 실험</h4>
<p>포스팅에 쓴 대로 정말 그런 일이 일어나는지 보기 위해 작은 실험을 했습니다. 위에 있는 것이 공유를 했을 때 메모리가 늘어나는 정도를 보여준다면 아래 있는 것은 공유하지 않고 Box를 생성할 때마다 Geometry를 upload하는 경우라 볼 수 있습니다. 물론 두 번째가 메모리를 훨씬 크게 잠식합니다.</p>
<p><strong>Geometry 한 개를 공유하는 경우</strong><a rel="nofollow" target="_blank" href="http://www.diebuster.com/lab/memory0/"><img src="https://lh6.googleusercontent.com/-mum22vTFhjo/Tp2XeiBmsJI/AAAAAAAAAO8/LeNMuigOnhs/s400/Screenshot_1.jpg" alt=""/></a></p>
<p><strong>매 번 새로운 Geometry를 upload 하는 경우</strong><a rel="nofollow" target="_blank" href="http://www.diebuster.com/lab/memory1/"><img src="https://lh3.googleusercontent.com/-aAbC4v2pbN0/Tp2Xeo3vZ3I/AAAAAAAAAPM/Wr2_Sr7zNlM/s400/Screenshot_2.jpg" alt=""/></a></p>
<h4>복합 Material 실험</h4>
<p>얼터8이 A3D로부터 복잡한 재질 설정이 넘어온 경우 StandardMaterial 에 의존하여 처리하게 되는데 보다 깊고 자세한 부분을 탐구하기 위해 맥스의 설정을 여러 가지로 바꿔보며 연동을 테스트하던 중간 결과물입니다. 아래 결과물은 diffuse, normal, specular 등의 복합적인 텍스쳐가 적용되어있는 상태로 마우스로 이리저리 회전시킬 수 있습니다.<br />
<a rel="nofollow" target="_blank" href="http://www.diebuster.com/lab/standard0/"><img src="https://lh6.googleusercontent.com/-TE9sCChLUMY/Tp2XfQRraPI/AAAAAAAAAPU/Z3EOh6qUbw0/s576/Screenshot_4.jpg" alt=""/></a></p>
<h4>행렬지원함수 테스트</h4>
<p>얼터8은 비참하리 만큼 지원되는 행렬변환 함수가 없습니다. 따라서 bs11이 직접 추가적인 기능을 제공합니다. 이 테스트에서는 다양한 행렬변환 기능이 제대로 작동하는가를 확인할 수 있습니다. 좌상단의 select a Box를 한 경우는 큐브에 대해 파라메터가 적용되고 체크를 풀면 구에 적용됩니다.<br />
<a rel="nofollow" target="_blank" href="http://www.diebuster.com/lab/matrix0/"><img src="https://lh3.googleusercontent.com/-kQbnJYeT0gI/Tp2Xe7XiZ0I/AAAAAAAAAPA/Bo3AtgP_G4g/s550/Screenshot_3.jpg" alt=""/></a></p>
<h4>결론</h4>
<p>걍 지루함을 달래기 위해 원래 공개하면 안되는 개발 중의 여러 샘플을 올려봤습니다. 현재 bs11을 제작하는 코어멤버는 저 혼자가 아닙니다. 진우와 용호가 물심양면으로 돕고 실제 실험과 코딩도 같이 하고 있습니다. 앞으로도 이론적인 설명은 이어지겠지만 지루하지 않게 중간중간 결과물을 발표하도록 노력하겠습니다 ^^</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/DHdhNUVTQPw" height="1" width="1"/>]]></content:encoded>
         <category>bs11</category>
      <feedburner:origLink>http://www.diebuster.com/flash/486</feedburner:origLink></item>
      <item>
         <title>Ocean Shader Demo | Resn Labs</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/ZSRtYu-VIl4/</link>
         <description>本格的に他のプラットホームの shader が移転される感じです(본격적으로 타 플랫폼의 shader 가 이전되는 느낌입니다)</description>
         <guid isPermaLink="false" />
         <pubDate>Mon, 17 Oct 2011 09:50:10 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://resnlabs.com/2011/10/ocean-shader-demo/" title="Ocean Shader Demo | Resn Labs"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fresnlabs.com%2F" alt=""/><a rel="nofollow" target="_blank" href="http://resnlabs.com/2011/10/ocean-shader-demo/">Ocean Shader Demo | Resn Labs</a></cite><p>Tue 11 Oct 2011 Matt Halford Discussion, Experiment, News – 3D, caustics, flash 3d, fp11, island, molehill, ocean, pb3d, pixel bender, reflection, refraction, shader, stage3d, terrain, water An advanc...</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://resnlabs.com/2011/10/ocean-shader-demo/"><img src="http://b.hatena.ne.jp/entry/image/http://resnlabs.com/2011/10/ocean-shader-demo/" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Ocean Shader Demo | Resn Labs" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Ocean Shader Demo | Resn Labs" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://resnlabs.com/2011/10/ocean-shader-demo/"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111017#bookmark-63461966">hika00</a>  本格的に他のプラットホームの shader が移転される感じです(본격적으로 타 플랫폼의 shader 가 이전되는 느낌입니다)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/ZSRtYu-VIl4" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://resnlabs.com/2011/10/ocean-shader-demo/</feedburner:origLink></item>
      <item>
         <title>Flint Particles: Version 4.0.0 released</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/trHE8sS8XW8/version-4-0-0-released</link>
         <description>いよいよ flash11を支援する flint 4.0が発売開始されました(드디어 flash11을 지원하는 flint 4.0이 출시되었습니다)</description>
         <guid isPermaLink="false" />
         <pubDate>Mon, 17 Oct 2011 01:26:54 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://flintparticles.org/blog/version-4-0-0-released" title="Flint Particles: Version 4.0.0 released"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fflintparticles.org%2F" alt=""/><a rel="nofollow" target="_blank" href="http://flintparticles.org/blog/version-4-0-0-released">Flint Particles: Version 4.0.0 released</a></cite><p>16th October 2011 Earlier this week I released version 4.0.0 of Flint. This release is to support the new crop of 3d engines that are using Stage3d for rendering. As part of this it was necessary to a...</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://flintparticles.org/blog/version-4-0-0-released"><img src="http://b.hatena.ne.jp/entry/image/http://flintparticles.org/blog/version-4-0-0-released" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Flint Particles: Version 4.0.0 released" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Flint Particles: Version 4.0.0 released" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://flintparticles.org/blog/version-4-0-0-released"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111017#bookmark-63446610">hika00</a>  いよいよ flash11を支援する flint 4.0が発売開始されました(드디어 flash11을 지원하는 flint 4.0이 출시되었습니다)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/trHE8sS8XW8" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://flintparticles.org/blog/version-4-0-0-released</feedburner:origLink></item>
      <item>
         <title>【東京】深夜から朝まで居られるカフェ - NAVER まとめ</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/RGTibXAAcdI/2126829617284434401</link>
         <description>もしかしたら今度出張で使わなければならないかも知れないです.</description>
         <guid isPermaLink="false" />
         <pubDate>Sun, 16 Oct 2011 06:10:36 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://matome.naver.jp/odai/2126829617284434401" title="&#x003010;&#x006771;&#x004eac;&#x003011;&#x006df1;&#x00591c;&#x00304b;&#x003089;&#x00671d;&#x00307e;&#x003067;&#x005c45;&#x003089;&#x00308c;&#x00308b;&#x0030ab;&#x0030d5;&#x0030a7; - NAVER &#x00307e;&#x003068;&#x003081;"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fmatome.naver.jp%2F" alt=""/><a rel="nofollow" target="_blank" href="http://matome.naver.jp/odai/2126829617284434401">【東京】深夜から朝まで居られるカフェ - NAVER まとめ</a></cite><p><a rel="nofollow" target="_blank" href="http://matome.naver.jp/odai/2126829617284434401"><img src="http://cdn-ak.b.st-hatena.com/entryimage/63194342-1318662045.jpg" alt="&#x003010;&#x006771;&#x004eac;&#x003011;&#x006df1;&#x00591c;&#x00304b;&#x003089;&#x00671d;&#x00307e;&#x003067;&#x005c45;&#x003089;&#x00308c;&#x00308b;&#x0030ab;&#x0030d5;&#x0030a7; - NAVER &#x00307e;&#x003068;&#x003081;" title="&#x003010;&#x006771;&#x004eac;&#x003011;&#x006df1;&#x00591c;&#x00304b;&#x003089;&#x00671d;&#x00307e;&#x003067;&#x005c45;&#x003089;&#x00308c;&#x00308b;&#x0030ab;&#x0030d5;&#x0030a7; - NAVER &#x00307e;&#x003068;&#x003081;" class="entry-image"/></a></p><p>カフェ(115)東京(133) シャッフル 【東京】深夜から朝まで居られるカフェ</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://matome.naver.jp/odai/2126829617284434401"><img src="http://b.hatena.ne.jp/entry/image/http://matome.naver.jp/odai/2126829617284434401" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - &#x003010;&#x006771;&#x004eac;&#x003011;&#x006df1;&#x00591c;&#x00304b;&#x003089;&#x00671d;&#x00307e;&#x003067;&#x005c45;&#x003089;&#x00308c;&#x00308b;&#x0030ab;&#x0030d5;&#x0030a7; - NAVER &#x00307e;&#x003068;&#x003081;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - &#x003010;&#x006771;&#x004eac;&#x003011;&#x006df1;&#x00591c;&#x00304b;&#x003089;&#x00671d;&#x00307e;&#x003067;&#x005c45;&#x003089;&#x00308c;&#x00308b;&#x0030ab;&#x0030d5;&#x0030a7; - NAVER &#x00307e;&#x003068;&#x003081;" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://matome.naver.jp/odai/2126829617284434401"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111016#bookmark-63194342">hika00</a>  もしかしたら今度出張で使わなければならないかも知れないです.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/RGTibXAAcdI" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://matome.naver.jp/odai/2126829617284434401</feedburner:origLink></item>
      <item>
         <title>波漆 捨戚希 砺什闘</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/ywEEx1zrPtY/molehill_fragshader_test.html</link>
         <description>AGALを利用してモーションブーラを作成したサンプルです(AGAL을 이용하여 모션 블러를 작성한 샘플입니다)</description>
         <guid isPermaLink="false" />
         <pubDate>Sun, 16 Oct 2011 06:08:53 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://clug.cau.ac.kr/~codeonwort/molehill_fragshader_test.html" title="&#x006ce2;&#x006f06; &#x006368;&#x00621a;&#x005e0c; &#x00783a;&#x004ec0;&#x0095d8;"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fclug.cau.ac.kr%2F~codeonwort%2F" alt=""/><a rel="nofollow" target="_blank" href="http://clug.cau.ac.kr/~codeonwort/molehill_fragshader_test.html">波漆 捨戚希 砺什闘</a></cite><p></p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://clug.cau.ac.kr/~codeonwort/molehill_fragshader_test.html"><img src="http://b.hatena.ne.jp/entry/image/http://clug.cau.ac.kr/~codeonwort/molehill_fragshader_test.html" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - &#x006ce2;&#x006f06; &#x006368;&#x00621a;&#x005e0c; &#x00783a;&#x004ec0;&#x0095d8;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - &#x006ce2;&#x006f06; &#x006368;&#x00621a;&#x005e0c; &#x00783a;&#x004ec0;&#x0095d8;" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://clug.cau.ac.kr/~codeonwort/molehill_fragshader_test.html"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111016#bookmark-63307522">hika00</a>  AGALを利用してモーションブーラを作成したサンプルです(AGAL을 이용하여 모션 블러를 작성한 샘플입니다)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/ywEEx1zrPtY" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://clug.cau.ac.kr/~codeonwort/molehill_fragshader_test.html</feedburner:origLink></item>
      <item>
         <title>Laboratory output n°76 FourSparklers « simppa.fi/blog</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/GtI8vi5PHNo/</link>
         <description>flash11を使った素敵なパーティクル效果!(flash11을 사용한 멋진 파티클 효과!)</description>
         <guid isPermaLink="false" />
         <pubDate>Sat, 15 Oct 2011 08:58:19 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://www.simppa.fi/blog/foursparklers/" title="Laboratory output n&#xb0;76 FourSparklers &#xab; simppa.fi/blog"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fwww.simppa.fi%2F" alt=""/><a rel="nofollow" target="_blank" href="http://www.simppa.fi/blog/foursparklers/">Laboratory output n°76 FourSparklers « simppa.fi/blog</a></cite><p><a rel="nofollow" target="_blank" href="http://www.simppa.fi/blog/foursparklers/"><img src="http://cdn-ak.b.st-hatena.com/entryimage/63206138-1318669119.jpg" alt="Laboratory output n&#xb0;76 FourSparklers &#xab; simppa.fi/blog" title="Laboratory output n&#xb0;76 FourSparklers &#xab; simppa.fi/blog" class="entry-image"/></a></p><p>I just checked and yeah… I had almost a year break from releasing experiments. The very core content of my blog. What ever. Here’s another particle experiment. There are 87 380 balls doing their thing...</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://www.simppa.fi/blog/foursparklers/"><img src="http://b.hatena.ne.jp/entry/image/http://www.simppa.fi/blog/foursparklers/" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Laboratory output n&#xb0;76 FourSparklers &#xab; simppa.fi/blog" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Laboratory output n&#xb0;76 FourSparklers &#xab; simppa.fi/blog" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://www.simppa.fi/blog/foursparklers/"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111015#bookmark-63206138">hika00</a>  flash11を使った素敵なパーティクル效果!(flash11을 사용한 멋진 파티클 효과!)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/GtI8vi5PHNo" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://www.simppa.fi/blog/foursparklers/</feedburner:origLink></item>
      <item>
         <title>cyclone-for-as3 - cyclone physics engine for as3 - Google Project Hosting</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/be_li20Zcxk/</link>
         <description>GAME PHYSICS ENGINE DEVELOPMENTという本は基本に as3用に製作されている物理エンジンプロジェク(GAME PHYSICS ENGINE DEVELOPMENT라는 책은 기본으로 as3용으로 제작되고 있는 물리엔진프로젝트)</description>
         <guid isPermaLink="false" />
         <pubDate>Fri, 14 Oct 2011 17:01:14 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://code.google.com/p/cyclone-for-as3/" title="cyclone-for-as3 - cyclone physics engine for as3 - Google Project Hosting"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fcode.google.com%2F" alt=""/><a rel="nofollow" target="_blank" href="http://code.google.com/p/cyclone-for-as3/">cyclone-for-as3 - cyclone physics engine for as3 - Google Project Hosting</a></cite><p>cyclone은 책 Game Physics Engine Developmet에 동반된 3D 게임 물리 엔진입니다. cyclone은 c++로 짜였으며 저는 이 책을 공부하면서 as3로 작성하고 있습니다. 원서에 대한 정보는 여기서 얻을 수 있습니다. http://procyclone.com/ 예제 링크</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://code.google.com/p/cyclone-for-as3/"><img src="http://b.hatena.ne.jp/entry/image/http://code.google.com/p/cyclone-for-as3/" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - cyclone-for-as3 - cyclone physics engine for as3 - Google Project Hosting" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - cyclone-for-as3 - cyclone physics engine for as3 - Google Project Hosting" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://code.google.com/p/cyclone-for-as3/"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111015#bookmark-63133938">hika00</a>  GAME PHYSICS ENGINE DEVELOPMENTという本は基本に as3用に製作されている物理エンジンプロジェク(GAME PHYSICS ENGINE DEVELOPMENT라는 책은 기본으로 as3용으로 제작되고 있는 물리엔진프로젝트)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/be_li20Zcxk" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://code.google.com/p/cyclone-for-as3/</feedburner:origLink></item>
      <item>
         <title>red2d-agal2d - AGAL 2D렌더링 - Google Project Hosting</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/WxHMWrfIQdo/</link>
         <description>flash11基盤の 2Dグラフィック framework Red2D 簡単で便利に使うことができます.(flash11기반의 2D그래픽 framework Red2D 간단하고 편리하게 사용할 수 있습니다.)</description>
         <guid isPermaLink="false" />
         <pubDate>Fri, 14 Oct 2011 16:51:56 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://code.google.com/p/red2d-agal2d/" title="red2d-agal2d - AGAL 2D&#x00b80c;&#x00b354;&#x00b9c1; - Google Project Hosting"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fcode.google.com%2F" alt=""/><a rel="nofollow" target="_blank" href="http://code.google.com/p/red2d-agal2d/">red2d-agal2d - AGAL 2D렌더링 - Google Project Hosting</a></cite><p>Red2D V0.4 공개 2011.07.26AGAL을 통한 2D렌더링 연구 및 라이브러리화보다 많은 정보는 http://redcamel-studio.tistory.com 에서 확인 하실 수 있습니다. Downloads 메뉴를 이용해주세요 (svn이 아직 익숙하지가않아서;; 제대로한건지...모르겠네요) V0.4 DemoPerformance Demo - htt...</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://code.google.com/p/red2d-agal2d/"><img src="http://b.hatena.ne.jp/entry/image/http://code.google.com/p/red2d-agal2d/" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - red2d-agal2d - AGAL 2D&#x00b80c;&#x00b354;&#x00b9c1; - Google Project Hosting" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - red2d-agal2d - AGAL 2D&#x00b80c;&#x00b354;&#x00b9c1; - Google Project Hosting" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://code.google.com/p/red2d-agal2d/"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111015#bookmark-52752522">hika00</a>  flash11基盤の 2Dグラフィック framework Red2D 簡単で便利に使うことができます.(flash11기반의 2D그래픽 framework Red2D 간단하고 편리하게 사용할 수 있습니다.)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/WxHMWrfIQdo" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://code.google.com/p/red2d-agal2d/</feedburner:origLink></item>
      <item>
         <title>blog.alumican.net » Blog Archive » FlashPlayer11のサウンド新機能を試してみる</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/jKEozBItIso/14_190342</link>
         <description>これ以上 mp3をURLLoaderで持って来て swfで作るなどの仕事が必要なくなりましたよね.Sound.LoadPCMFromByteArray最高!(더 이상 mp3를 URLLoader로 가져와 swf로 만드는 등의 일이 필요없어졌군요. flash11에 추가된 Sound.LoadPCMFromByteArray 최고!)</description>
         <guid isPermaLink="false" />
         <pubDate>Fri, 14 Oct 2011 12:25:49 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://blog.alumican.net/2011/10/14_190342" title="blog.alumican.net &#xbb; Blog Archive &#xbb; FlashPlayer11&#x00306e;&#x0030b5;&#x0030a6;&#x0030f3;&#x0030c9;&#x0065b0;&#x006a5f;&#x0080fd;&#x003092;&#x008a66;&#x003057;&#x003066;&#x00307f;&#x00308b;"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fblog.alumican.net%2F" alt=""/><a rel="nofollow" target="_blank" href="http://blog.alumican.net/2011/10/14_190342">blog.alumican.net » Blog Archive » FlashPlayer11のサウンド新機能を試してみる</a></cite><p>ブログを書くのが久しぶり過ぎて、世の中ではすでにFlashPlayer11の話題で持ちきりのようで。 アップデートの目玉であるStage3Dに関してはいろんな人が取り上げているので、ちょっと地味なSoundの新機能をちょちょいと試してます。Sound.LoadPCMFromByteArrayを使えば、ByteArrayに格納されたPCMデータからSoundインスタンスを生成できるようになります。ご...</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://blog.alumican.net/2011/10/14_190342"><img src="http://b.hatena.ne.jp/entry/image/http://blog.alumican.net/2011/10/14_190342" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - blog.alumican.net &#xbb; Blog Archive &#xbb; FlashPlayer11&#x00306e;&#x0030b5;&#x0030a6;&#x0030f3;&#x0030c9;&#x0065b0;&#x006a5f;&#x0080fd;&#x003092;&#x008a66;&#x003057;&#x003066;&#x00307f;&#x00308b;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - blog.alumican.net &#xbb; Blog Archive &#xbb; FlashPlayer11&#x00306e;&#x0030b5;&#x0030a6;&#x0030f3;&#x0030c9;&#x0065b0;&#x006a5f;&#x0080fd;&#x003092;&#x008a66;&#x003057;&#x003066;&#x00307f;&#x00308b;" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://blog.alumican.net/2011/10/14_190342"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111014#bookmark-63104246">hika00</a>  これ以上 mp3をURLLoaderで持って来て swfで作るなどの仕事が必要なくなりましたよね.Sound.LoadPCMFromByteArray最高!(더 이상 mp3를 URLLoader로 가져와 swf로 만드는 등의 일이 필요없어졌군요. flash11에 추가된 Sound.LoadPCMFromByteArray 최고!)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/jKEozBItIso" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://blog.alumican.net/2011/10/14_190342</feedburner:origLink></item>
      <item>
         <title>Whack! - an open source game by Byxb Interactive</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/kpKs_OgtRLQ/</link>
         <description>スタルリングに製作された 2Dゲームデモ. 実際ゲームだと見ることは大変だがソースが公開されている(스탈링으로 제작된 2D게임 데모. 실제 게임이라고 보기는 힘들지만 소스가 공개되어있다)</description>
         <guid isPermaLink="false" />
         <pubDate>Fri, 14 Oct 2011 08:47:01 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://www.whacksite.com/" title="Whack! - an open source game by Byxb Interactive"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fwww.whacksite.com%2F" alt=""/><a rel="nofollow" target="_blank" href="http://www.whacksite.com/">Whack! - an open source game by Byxb Interactive</a></cite><p>To view this page ensure that Adobe Flash Player version 11.0.0 or greater is installed. Don't just play the game, build it! If you'd like to learn how to use Starling to build a hardware accelerated ...</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://www.whacksite.com/"><img src="http://b.hatena.ne.jp/entry/image/http://www.whacksite.com/" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Whack! - an open source game by Byxb Interactive" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Whack! - an open source game by Byxb Interactive" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://www.whacksite.com/"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111014#bookmark-63092106">hika00</a>  スタルリングに製作された 2Dゲームデモ. 実際ゲームだと見ることは大変だがソースが公開されている(스탈링으로 제작된 2D게임 데모. 실제 게임이라고 보기는 힘들지만 소스가 공개되어있다)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/kpKs_OgtRLQ" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://www.whacksite.com/</feedburner:origLink></item>
      <item>
         <title>Powerfl</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/DmPDlRSutno/</link>
         <description>flashと係わる技術を定期的に寄稿するチームブログ (flash와 관련된 기술을 정기적으로 기고하는 팀블로그)</description>
         <guid isPermaLink="false" />
         <pubDate>Fri, 14 Oct 2011 08:05:20 +0000</pubDate>
         <content:encoded><![CDATA[<blockquote cite="http://powerfl.com/" title="Powerfl"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fpowerfl.com%2F" alt=""/><a rel="nofollow" target="_blank" href="http://powerfl.com/">Powerfl</a></cite><p>Posted by oxizen | Published on Sunday, January 30th, 2011 | 7 Comments 개인 블로그는 귀차니즘때문에 몇차례 실패한바있는데. 이렇게 팀블로그를 시작하고 보니 강제로라도 하게 되서 너무 행복(?) 하군요. 사실 다른 분들이 워낙 쟁쟁한 분들이라 비슷한 주제를 선택한다 하더라도 좀 더 심도있게 다루기 힘들...</p><p><a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/entry/http://powerfl.com/"><img src="http://b.hatena.ne.jp/entry/image/http://powerfl.com/" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Powerfl" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af; - Powerfl" border="0" style="border:none;"/></a> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/append?http://powerfl.com/"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;" title="&#x00306f;&#x003066;&#x00306a;&#x0030d6;&#x0030c3;&#x0030af;&#x0030de;&#x0030fc;&#x0030af;&#x00306b;&#x008ffd;&#x0052a0;"/></a></p></blockquote><p><img src="http://cdn4.www.st-hatena.com/users/hi/hika00/profile_s.gif" class="profile-image" alt="hika00" title="hika00" width="16" height="16"/> <a rel="nofollow" target="_blank" href="http://b.hatena.ne.jp/hika00/20111014#bookmark-28684899">hika00</a>  flashと係わる技術を定期的に寄稿するチームブログ (flash와 관련된 기술을 정기적으로 기고하는 팀블로그)</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/DmPDlRSutno" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://powerfl.com/</feedburner:origLink></item>
      <item>
         <title>Alternativa3D 8.x의 구조와 bs11 #2</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/Deby9GfWU2M/474</link>
         <description>저 번 글에 이어 이번에도 보다 깊은 곳까지 얼터8의 구조를 분석하고 bs11이 어떻게 대응하는지 설명하겠습니다. 과연 Context3D를 어떻게 이용하고 있을까? 저번 시간에 이어 아주 약간만 더 들어가보겠습니다. gpu파이프라인은 하드웨어적으로 정점버퍼와 상수버퍼, 쉐이더 버퍼로 추상화 되어있습니다. 원래 더 많은 것들이 있지만 플래시11이 추상화시킨 게 현재로서는 이 정도 입니다. 정점버퍼에 열심히 데이터를 밀어 넣는 경우 쉐이더는 정점버퍼를 [...]</description>
         <guid isPermaLink="false">http://www.diebuster.com/flash/?p=474</guid>
         <pubDate>Thu, 13 Oct 2011 14:25:59 +0000</pubDate>
         <content:encoded><![CDATA[<p>저 번 글에 이어 이번에도 보다 깊은 곳까지 얼터8의 구조를 분석하고 bs11이 어떻게 대응하는지 설명하겠습니다.</p>
<h4>과연 Context3D를 어떻게 이용하고 있을까?</h4>
<p>저번 시간에 이어 아주 약간만 더 들어가보겠습니다.</p>
<p>gpu파이프라인은 하드웨어적으로 정점버퍼와 상수버퍼, 쉐이더 버퍼로 추상화 되어있습니다. 원래 더 많은 것들이 있지만 플래시11이 추상화시킨 게 현재로서는 이 정도 입니다.</p>
<p>정점버퍼에 열심히 데이터를 밀어 넣는 경우 쉐이더는 정점버퍼를 차례로 읽어 필요한 처리를 하게 됩니다. 예를 들어 큐브 10개가 있는 경우 각 큐브에 적당한 위치와 회전을 주고 변화를 반영시킨 큐브의 정점리스트 10개를 전부 정점버퍼에 넣으면 화면을 그릴 수 있습니다. 즉 원하는 화면은 정점버퍼에 삼각형 정보로 밀어 넣으면 된다는 거죠. 문제점은 다른 곳에 있습니다.</p>
<p>원래 3D의 정석적인 방법은 두 개의 렌더링 버퍼를 이용하는 더블 버퍼링입니다. 더블 버퍼링 자체는 플래시11도 지원하지만 DX나 OpenGL에서는 gpu를 사용하는 행렬변환 함수가 제공되므로 정점변환을 직접 호스트코드에서 처리한 뒤 후면 정점버퍼에 변환이 완료된 정점을 업로드 하여 전면 버퍼와 교체하는 게 일반적입니다. 하지만 플래시11의 context3D는 as3가 사용할 별도의 gpu함수를 제공하지도 않고 쉐이더의 결과를 반환하지도 않습니다. 따라서 정점리스트의 행렬변환을 as3내장객체인 Matrix3D 등으로 수행하게 되므로 매우 느려지게 됩니다(어도비에서 아예 Matrix3D를 아예 gpu를 타게 바꾸던가..어쩌라고=.=)<br />
<span id="more-474"></span><br />
그래서 꽁수가 등장하기 시작하는데 as3코드에서 행렬 변환하는 것이 손해이기 때문에 상수버퍼를 사용하게 됩니다. 물론 상수버퍼는 쓸모가 많지만 as3입장에선 절실한 거죠. 상수버퍼란 쉐이더가 실행 중에 얻을 수 있는 이미 공급된 데이터입니다. 원래 쉐이더는 정점버퍼의 정점데이터만 한 번에 하나씩 받을 수 있습니다. 하지만 상수버퍼의 내용은 쉐이더가 전부 알고 있습니다. 이런 점을 이용하면 기본적인 행렬변환도 전부 쉐이더에게 넘길 수 있습니다. 즉 상수버퍼에 원하는 행렬 변환 데이터를 넘겨주고 이를 바탕으로 정점에 대한 행렬 변환을 쉐이더가 하게 시켜 결과적으로 gpu가 변환을 하게 하는 거죠.</p>
<p>위와 같은 방식에서는 상수버퍼에 정점에 대한 행렬변환 정보를 기술해 줍니다. x, y, z, rotation, scale 등의 정보입니다. 헌데 이 데이터도 생각해보면 만만치 않습니다. 정점 하나에 행렬변환 정보 하나가 매칭될 수준이라면 상수버퍼의 데이터는 굉장히 방대해집니다. 따라서 기하구조가 변하지 않는 일종의 강체라면, 강체 당 하나의 행렬 변환 데이터를 보내는 식으로 데이터를 줄일 수 있습니다. 또한 이런 방법을 쓰면 draw콜에서도 이득이 생기는데 기하구조가 같은 경우 정점버퍼에는 기하구조를 하나만 넣어두고 상수버퍼에서 여러 개의 인스턴스 행렬변환 정보만 보내는 방식으로 처리하여 gpu메모리를 크게 절약할 수 있습니다.</p>
<p>플래시11의 3D는 as3처럼 꽁수와 편법이 난무하는 세계인거죠.</p>
<h4>얼터8은?</h4>
<p>얼터8은 플래시11 초창기부터 개발해 온 framework답게 플래시11의 편법을 모두 반영하고 있습니다. 예를 들어 큐브를 여러 개 생성한다고 하면 큐브 당 모든 기하정보를 전부 정점 버퍼에 올리지 않고 오직 하나의 기하구조만 올린 채 공유할 수 있습니다. 이게 가능한 이유는 앞 서 말씀 드린 대로 행렬변환 정보를 상수버퍼에 쓰기 때문이죠. 이를 코드로 표현하면 아래와 같습니다.</p>
<pre>
var box1:Box, box2:Mesh, i:int, j:int, surface:Surface;

// box1을 먼저 만든다.
box1 = new Box;

// 1. box2를 빈 메쉬로 만든다.
box2 = new Mesh;

// 2. box1의 기하정보를 그대로 참조하자!
box2.geometry = box.geometry;

// 3.box1의 서페이스 정보를 복사하자!
for( i = 0, j = box1.numSurface ; i &amp;lt; j ; ++i ){
	surface = box1.getSurface( i );
	box2.addSurface( null, surface.indexStart, surface.numTriangle );
}
</pre>
<p>다른 메쉬의 기하정보를 가져오려면 귀찮게도 항상 저 3단계를 밟아야 합니다. 이렇게 되면 내부적으로 box1과 box2는 같은 기하정보(geometry)를 공유하게 됩니다. 따라서 다음과 같이 box1의 geometry만 업로드하면 box1, box2를 모두 화면에 표시할 수 있게 됩니다.</p>
<pre>
box1.geometry.upload( stage3Ds[0].context3D );
</pre>
<p>저번 글에서 살짝 언급했습니다만 더 정확하게 얼터8에서 메시의 의미를 짚어보면 다음의 세 가지로 요약됩니다.</p>
<ol>
<li>Geometry 객체를 참조로 잡는 컨테이너</li>
<li>Geometry내의 정점에 적용될 행렬 변환 데이터를 저장해두는 저장소</li>
<li>텍스쳐매핑과 연결해주는 추상 인터페이스 인 서페이스(Surface)의 저장소</li>
</ol>
<p>(음 더 쉽게 설명을 못하겠네요 ^^; 걍 여러 번 읽으시면 알게 되실 듯)</p>
<p>실제 무심하게 Box인스턴스를 양산하지 말고 위와 같은 방법으로 생성하면 화면에 동일한 수의 큐브를 표현해도 gpu메모리 사용은 크게 줄어듭니다.</p>
<h4>bs11은?</h4>
<p>일단 정점으로부터가 아니라 Geometry가 만들어진 객체를 생성하는 경우를 생각해보면 간단히 두 가지 경우 밖에 없습니다. 하나는 기본 모델(Primitive)로 부터 생성했거나 아니면 외부 모델을 로딩한 거죠. 먼저 기본 모델을 생성하는 경우 bs11은 내부에 각 기본 모델의 유일한 Geometry를 키와 함께 저장해두고 이를 이용해 위와 같은 비슷한 형태로 공유하는 메시를 생성해 줍니다.</p>
<p>하지만 더욱 강력한 기능은 외부모델 로딩 시에 일어납니다. 맥스 등에서 각 객체의 이름을 기술할 때 미리 bs11과 약속한 이름으로 기술하면 지오메트리를 그룹화 지어 내부적으로 복제를 해주는 방식입니다. 예를 들어 맥스에서 동일한 큐브를 5개 만들어 각각 scale과 rotation, position 등을 바꿔 장면에 배치한 경우를 생각해보죠. 그럼 그 5개 큐브에 이름을 맥스에서 다음과 같이 부여합니다.</p>
<p><b>cube1@geo=box1<br />
cube2@geo=box1<br />
cube3@geo=box1<br />
cube4@geo=box1<br />
cube5@geo=box1</b></p>
<p>그럼 bs11은 A3D등으로 모델을 로딩한 뒤 각 매쉬의 이름을 다음과 같은 규칙으로 분리해냅니다.</p>
<p><b>이름@속성1=값1@속성2=값2@속성3=값3&#8230;..</b></p>
<p>위에 등장한 속성 명은 geo라는 것인데 이것은 해당 메쉬가 특정 기하구조를 공유할 때 사용하는 속성입니다(더 많은 속성은 나중에 ^^) 따라서 메쉬의 이름으로부터 cube1~5가 동일한 box1 기하구조를 사용한다는 사실을 알아냅니다.</p>
<p>그 이후 과정은 앞 서 설명했던 기하구조 공유 형태로 처리하게 됩니다. 따라서 맥스에서 로딩한 모델도 단일 기하구조에 대한 참조를 실현하게 되는 거죠.</p>
<p>이 혜택은 매우 큰 데 제법 정교한 비행기 모델을 여러 개 장면에 배치해도 기하구조를 하나만 gpu에 업로드해주는 강력한 bs11의 기능입니다.</p>
<h4>upload와 dispose관리</h4>
<p>내부적으로 독립적인 기하구조 1개만 잡아 두고 참조를 공유하도록 bs11이 디자인되어있기 때문에 upload와 dispose를 자동으로 할 수 있는 기반이 됩니다.</p>
<p>기하구조를 어떤 메쉬가 인출해갈 때마다 인출카운터를 하나 올리고 반대로 반납할 때마다 하나를 줄이면 흔히 알려진 retain, release를 실현할 수 있습니다. 최초 0에서 1이 되는 순간 upload하고 다시 0으로 돌아오는 순간 dispose하는 것으로 화면에 있는 것만 upload하도록 관리할 수 있게 됩니다.<br />
호스트코드를 작성할 때 전혀 신경쓰지 않아도 장면에 관련된 기하구조만 업로드되고 완전히 제거되면 다시 메모리에서 자동으로 제거됩니다.</p>
<h4>결론</h4>
<p>일단 위에 글을 적으면서 설명이 생략된 내용이 바로 텍스쳐 매핑과 서페이스에 대한 내용입니다. 제가 아직 글에 적은 적이 없어 원래 아시는 분이 아니면 현재 저 부분이 뻥하고 이빨빠져있어 난감하실거라 생각합니다. 일단 지오메트리를 얼터가 어떻게 쓰는지를 전부 다룬 뒤 텍스쳐를 다룰 생각이라 그렇습니다. 서페이스와 텍스쳐는 이해가 잘 안가도 좀 기다려주세요 ^^;</p>
<p>bs11의 기본적인 기하시스템은 이 정도로 정리하고 다음에는 텍스쳐관리를 알아보겠습니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/Deby9GfWU2M" height="1" width="1"/>]]></content:encoded>
         <category>bs11</category>
      <feedburner:origLink>http://www.diebuster.com/flash/474</feedburner:origLink></item>
      <item>
         <title>Alternativa3D 8.x의 구조와 bs11 #1</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/FQsNXE-y2gE/471</link>
         <description>bs11의 기저에는 얼터8이 깔려있습니다. 따라서 얼터8의 기초적인 구성이 어떻게 되어있는지 살펴보는 것은 반대로 bs11이 왜 그렇게 작동하는지를 이해할 수 있는 토대가 됩니다. 이번 포스트에서는 Geometry 시스템이 어떻게 얼터8에 구현되어있는지를 심층적으로 파악해보겠습니다. 3D를 구성하는 기하구조(Geometry) 다른 3Dframework처럼 얼터8도 GPU파이프라인에 기반한 기하클래스 군을 갖고 있습니다. 하지만 문제는 기존과는 완전히 다른  형태로 되어있다는 점입니다(얼터7과 비교해도 완전히 다릅니다) 현대 [...]</description>
         <guid isPermaLink="false">http://www.diebuster.com/flash/?p=471</guid>
         <pubDate>Wed, 12 Oct 2011 04:15:14 +0000</pubDate>
         <content:encoded><![CDATA[<p>bs11의 기저에는 얼터8이 깔려있습니다. 따라서 얼터8의 기초적인 구성이 어떻게 되어있는지 살펴보는 것은 반대로 bs11이 왜 그렇게 작동하는지를 이해할 수 있는 토대가 됩니다. 이번 포스트에서는 Geometry 시스템이 어떻게 얼터8에 구현되어있는지를 심층적으로 파악해보겠습니다.</p>
<h4>3D를 구성하는 기하구조(Geometry)</h4>
<p>다른 3Dframework처럼 얼터8도 GPU파이프라인에 기반한 기하클래스 군을 갖고 있습니다. 하지만 문제는 기존과는 완전히 다른  형태로 되어있다는 점입니다(얼터7과 비교해도 완전히 다릅니다) 현대 서양 철학은 상대주의와 합리주의에 입각하기 때문에 OOP형태로 설계할 때 부속을 분해하여 설계합니다. 따라서 일반적인 기하구조를 포장한 클래스 구조는 대략 다음과 같은 형태가 됩니다.</p>
<ol>
<li>점을 Vertex를 통해 만든다.</li>
<li>면을 Face로 만들 때 위에 만든 Vertex을 이용한다.</li>
<li>매쉬를 Mesh로 만들 때 위에 만든 Face를 이용한다.</li>
</ol>
<p>이 얼마나 알기 쉬운 구조입니까 ^^;</p>
<p>점을 세 개 만들어서 면을 생성하고 그 면을 메쉬에 넣으면 끝난다 이거죠. 하지만 얼터8은 미묘한 구조로 되어있습니다. 일단 코드를 보겠습니다.</p>
<p><span id="more-471"></span></p>
<pre>
//지오메트리를 만들기 위해 먼저 명령배열을 만든다.
//점 세 개랑 이어서 UV좌표가 들어간다는 뜻
var  attributes:Array = [];
attributes[0] = VertexAttributes.POSITION;
attributes[1] = VertexAttributes.POSITION;
attributes[2] = VertexAttributes.POSITION;
attributes[3] = VertexAttributes.TEXCOORDS[0];
attributes[4] = VertexAttributes.TEXCOORDS[0];

//지오메트리를 생성하고 정점과 UV좌표, 삼각면 인덱스를 차례로 설정한다.
var geometry = new Geometry();
geometry.addVertexStream(attributes);
geometry.numVertices = 3;
geometry.setAttributeValues(
	VertexAttributes.POSITION,
	Vector.&amp;lt;Number&amp;gt;( [x1,y1,z1,x2,y2,z2,x3,y3,z3])
);
geometry.setAttributeValues(
	VertexAttributes.TEXCOORDS[0],
	Vector.&amp;lt;Number&amp;gt;( [u1,v1,u2,v2,u3,v3] )
);
geometry.indices =  Vector.&amp;lt;uint&amp;gt;( [0,1,2] );

//메쉬를 생성하여 위의 지오메트리를 할당하고 특정 인덱스로부터 지정된
//삼각면의 갯수로 서페이스를 생성한다. 재질은 서페이스 단위로 할당!
var mesh = new Mesh;
mesh.geometry = geometry;
mesh.addSurface( new FillMaterial( 0xff0000 ), 0, 1 );
</pre>
<p>이 구조를 보면 걍 지오메트리에 점이니 면이니 구분없이 다 때려박고 서페이스라는 건 재질만 구분해서 적용하려고 지오메트리를 임의로 구분짓는 구분자 같은 역할만 합니다. 뭐랄까 오히려 강연사의 하나는 전체, 전체는 하나 같은 느낌의 구조입니다. 다음의 코드를 통해 Surface를 얻어내도 Surface안에는 아무런 지오메트리가 포함되어있지 않습니다.</p>
<pre>
surface = mesh.getSurface( 0 );
//surface.....indexBegin, numTriangles 따위만 있고 지오메트리는 없음.
</pre>
<p>따라서 surface란 한마디로 Mesh내에 여러 개의 재질을 적용하기 위한 구분자 이상도 이하도 아닙니다. 따라서 mesh는 geometry를 설정하면 성립은 하지만 surface를 설정하지 않으면 재질을 적용할 수 없어 화면엔 표시할 수 없는 것이죠. 이것 참 적응하기 어려운 구조랍니다.</p>
<p>사실 Mesh자체도 따지고 보면 Geometry 컨테이너에 불과하므로 하나의 메쉬에서 지오메트리와 서페이스를 빼내서 보관하고 있으면 메쉬를 양산하거나 병합하는 건 큰 일이 아닙니다.</p>
<p>사실 이런 구조를 만든 건 러시아식 사고방식에서 나온 게 아니라 context3D에 업로드하기 편한 구조를 만들기 위해서였겠죠(얼터7은 이렇게 되어있지 않고 맨 처음 소개한 구조로 되어있습니다)</p>
<h4>Geometry간의 병합</h4>
<p>수동으로 Geometry 두 개를 병합한다고 해보죠. 모든 정점이 완전히 분리된 두 개의 Geometry라면 그저 VertexStream과 AttributeValues를 적당히 버무려주면 됩니다. 하지만 절대로 용이하지 않습니다.</p>
<ol>
<li>numVertexStreams로 명령의 갯수를 일일이 파악해서 for로 배열을 재생성 해야 하고,</li>
<li>getAttributeValues()를 통해 하나하나 정점과 UV좌표수치를 뽑아서</li>
<li>각각의 배열로 만들어냅니다.</li>
<li>그걸 두 개의 Geomerty마다 한 뒤 생성된 배열 두 쌍을 병합하여 새로운 Geometry에 적용합니다.</li>
</ol>
<p>아, 도저히 귀찮아서 샘플코드를 작성할 수가 없습니다(나중에 용호 시켜서 지오메트리 병합 메서드 하나 짜라고 해야지..) 게다가 저렇게 병합하면 겹쳐지는 정점을 자동으로 정렬하고 삼각형 인덱스를 재처리하는 작업도 안됩니다. 참고로 away의 경우는 여기까지를 한 방에 처리하는 메서드를 제공하고 있습니다. 여튼 얼터8에서 기하구조 두 개를 병합하는 건 귀찮은 작업입니다.</p>
<h4>Geometry의 upload</h4>
<p>실제 기저에 있는 context3D에 기하정보를 업로드하기 위한 추상인터페이스가 바로 얼터8에서 제공하는 upload라는 메서드입니다. 이 메서드는 Resource를 상속한 클래스는 전부 갖고 있는데 지오매트리와 재질 계열의 클래스가 이에 해당됩니다. 따라서 특정 지오메트리를 직접 context3D에 업로드하고 싶다면 다음과 같이 하면 됩니다.</p>
<pre>
mesh.geometry.upload( context3D );
</pre>
<p>하지만 mesh는 Object3D를 상속받았고 Object3D는 내부에 mesh를 비롯한 다양한 객체를 자식으로 갖고 있습니다. 이 중 geometry속성이 있는 모든 자식들을 순회하여 컴포지트 패턴형태로 지오메트리를 수집해 벡터로 반환하는 형태는 다음과 같습니다.</p>
<pre>
var result:Vector.&amp;lt;Resource&amp;gt; = container.getResource( true, Geometry );
</pre>
<p>저렇게 하면 container안에 있는 모든 지오메트리를 수집하여 벡터로 반환하므로 다음과 같은 루프를 통해 업로드 되었는지 먼저 체크한 뒤 업로드를 하면 됩니다.</p>
<pre>
for each( var resource in container.getResource( true, Geometry ) ){
	resource.isUploaded ? null : resource.upload( context3D );
}
</pre>
<p>사실 mesh의 경우 자식을 갖지 않기 때문에 구지 getResource를 해서 벡터를 넘겨 받은 뒤 벡터의 요소를 꺼내 upload하는 건 뻘 짓입니다. 즉 아래의 예에서 두 번째 방식이 정답인거죠.</p>
<pre>
var mesh:Mesh = new Mesh;
...

//뭐하러 괜시리 벡터만들고 루프도냐..
for each( var resource in mesh.getResource( false, Geometry ) ){
	resource.isUploaded ? null : resource.upload( context3D );
}

//그냥 upload해버려
var resource = mesh.geometry;
resource.isUploaded ? null : resource.upload( context3D );
</pre>
<h4>결론</h4>
<p>context3D에 최적화 되어있는 얼터8의 Geometry를 살펴봤습니다. 참 유틸메서드 하나 지원안해주는 귀찮아쟁이 라이브러리입니다.</p>
<p>다음 글에서는 bs11이 여기에 어떻게 대처하는지를 적어보겠습니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/FQsNXE-y2gE" height="1" width="1"/>]]></content:encoded>
         <category>bs11</category>
      <feedburner:origLink>http://www.diebuster.com/flash/471</feedburner:origLink></item>
      <item>
         <title>2011.10.10 밀린 북리뷰 정리 2/2</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/AZC_4eeY1vs/</link>
         <description>워매 끝이 안남. 이제 미루지 말고 잘 써야지라고 저번 6월에도 결심했던 거 같은데.. 기껏 한 권씩 정성스레 리뷰할라고 만든 이 스킨은 무용지물이었던 것인가.. 플래시 게임 마스터 와 이 책은요 무려 역자인 유윤선님께 직접 선물 받았습니다. 감사합니다. 이 책은 플래시 게임 책이긴 하지만 동시에 그냥 게임 책입니다. 즉 이 책의 소스를 타 언어로 바꿔도 될 만큼 [...]</description>
         <guid isPermaLink="false">http://book.diebuster.com/book/?p=263</guid>
         <pubDate>Mon, 10 Oct 2011 07:19:15 +0000</pubDate>
         <content:encoded><![CDATA[<p>워매 끝이 안남. 이제 미루지 말고 잘 써야지라고 저번 6월에도 결심했던 거 같은데.. 기껏 한 권씩 정성스레 리뷰할라고 만든 이 스킨은 무용지물이었던 것인가..</p>
<h4><img src="https://lh3.googleusercontent.com/-1k8Au288CaU/TpJ4QJJMHZI/AAAAAAAAAN8/PBcWvxPGZYc/s566/1.jpg"/></h4>
<h4>플래시 게임 마스터</h4>
<p>와 이 책은요 무려 역자인 유윤선님께 직접 선물 받았습니다. 감사합니다. 이 책은 플래시 게임 책이긴 하지만 동시에 그냥 게임 책입니다. 즉 이 책의 소스를 타 언어로 바꿔도 될 만큼 게임의 정석을 다루고 있습니다. <strong>게임프로그래밍의 핵심 테크닉과 알고리즘</strong> 이란 책에 비견될 만큼 광범위한 게임 개발 이론을 다루고 있습니다. 저자는 플래시 플랫폼이 게임에 적합 부분과 약한 부분이 어딘지 정확하게 이해하고 약한 부분을 보완하기 위해 8비트 게임기 시절부터 사용하는 성능 향상 꽁수를 총 동원합니다. 하지만 이 책에도 단점이 있습니다. 일단 설명은 각 알고리즘에나 개념에 대해 상당히 추상적이고 관념적으로 설명하는데 비해 주어진 소스코드는 당장 실무에 사용해도 될 정도 입니다. 이 사이의 간극이 상당하여 설명을 듣고 코드를 봐도 쉽게 이해되지 않는 부분이 꽤나 있습니다. 뭐랄까 천자문을 천 번 읽어서 깨쳐라라는 식의 분위기가 있습니다. 좀 더 친절했으면 좋았을 것 같다는 생각이 많이 듭니다(책 내용이 좋기 때문에 더욱)</p>
<h4>플래시 멀티플레이 게임 개발</h4>
<p>이 책은 원서가 나온 지 꽤나 시간이 지난 책입니다. 원서를 볼 때도 느꼈던 거지만 게임 서버 이론을 알기 쉽게 가르쳐주는 친절한 서버 알고리즘 책 정도의 의미입니다. 실제로 대부분의 코드는 자사의 서버 솔루션용 자바코드라 그다지 쓸모가 없을 뿐더러 as3개발자에겐 알아먹기도 까다롭습니다. 본인만의 소켓서버를 어떤 언어로 구현하든 게임 서버가 갖춰야 할 기능과 아키텍쳐의 기초를 공부하기엔 매우 좋은 입문서입니다.</p>
<h4>플렉스 프로그래밍</h4>
<p>보통 러닝 시리즈는 기본에 충실한 내용이 맘에 들었는데 이 책에서는 약간 속 빈 강정 같은 느낌이 있습니다. 아마도 4.5가 워낙 변경 사항이 많은 것에 비해 책의 분량은 얇아 중요 부분만 넣다 보니 그런 게 아닌가 싶습니다. 쨌든 현재로서는 4.5의 유일한 역서군요.</p>
<h4>마스터링 언리얼</h4>
<p>제가 UDK가 처음이라 너무 재밌게 보고 있습니다. 플래시11용 IDE는 과연 이런 기능의 얼마나 지원할까..프로시니엄 프로젝트와 클라우드를 보면 포토샵의 3D기능 정도가 이사올 걸로 예상이 됩니다만, 사실 프로시니엄을 플레이어 수준으로 내장하지도 않을 거면서 속도도 고만고만하고.. 잠시 삼천포로 빠졌습니다. 암튼 UDK 물건이네요. 유니티3D를 갖고 놀 때보다 몇 배나 즐겁습니다.</p>
<h4>안드로이드 게임 프로그래밍</h4>
<p>이 책은 참 친절한 안드로이드용 게임 제작 책입니다. 모바일 게임을 만들기 위한 기본 조건은 오픈지엘ES입니다. 이 책은 책을 팔아먹기 위해 대략 게임이란 타이틀을 붙인 책이 아니라 오픈지엘ES를 안드로이드에서 어떻게 사용하는지 매우 기초에서 게임을 만들 수 있는 수준까지 꼼꼼하게 가르쳐줍니다. 사실 이 책에서 사용하는 코드는 조금만 변형하면 플래시로 옮길 수도 있습니다. 오픈지엘ES의 구조의 부분 집합 형태로 플래시11이 제작되었기 때문입니다(물론 아직 갈 길이 멀지만..) 뭔가 시장에서 게임을 만들 수 있는 책이 많이 출간되고 있습니다. 내용도 그 전보다 훨씬 실무에 가까워지고.. 하지만 그렇다고 게임을 만드는 난이도가 달라지는 것도 아니라서 게임개발이 가능한 인구가 갑자기 늘어날 거란 기대는 안하고 있습니다. 그래도 의지 있는 자에게 빛이 되는 책이군요.</p>
<h4>안드로이드 프로그래밍</h4>
<p>안드로이드 OS의 기본적인 아키텍쳐와 이를 사용하기 위한 개념들은 적지 않습니다. 사실 적지 않을 뿐 아니라 다른 OS환경과 비교하면 매우 독특하기도 합니다. 이 부분이 기존 개발자가 안드로이드로 투입되는데 일종의 장벽이 되는데 반대로 처음 프로그래밍을 안드로이드로 배운 개발자에게 안드로이드의 다양한 기능은 쉽게 인식됩니다. 기존 개발자로 가득 차 있는 제 회사에서 안드로이드 개발을 시키기 위해서는 안드로이드 OS의 기초 개념부터 차근차근 가르칠 필요가 있고 그런 점에서 매우 훌륭한 설명을 해주는 책입니다. 국내 저자 진인데도 이렇게 책을 잘 써주시다니 감사할 따름입니다.</p>
<h4>게임 프로그래머를 위한 물리 모델링</h4>
<p>현재 as3로 발표된 3D용 물리엔진은 맘에 드는 것이 없습니다. 하지만 그렇다고 좋은 c나 c++엔진은 대부분 gpu기반으로 이사가 버렸습니다. 어쩔 수 없이 하나 만들까 생각 중인데 제가 만들기는 너무 귀찮고 남을 시키자니 안 될 것 같고 마땅한 레퍼런스 하나를 번역해서 만들려고 합니다. 그에 적합한 책이 바로 이 책입니다. 그래서 번역해서 as3용 물리엔진을 만들고 있냐면 그건 또 밀려있습니다 =.= 쨌든 책은 좋습니다. 어떤 점이 다른 물리책과 다른가 하면 차근차근 구축해서 하나의 엔진이 될 수 있게 해준다는 점이 좋습니다. 뭐랄까 물리학보다 물리를 이용한 게임엔진에 확실히 중심이 있다는 점이 맘에 쏙 듭니다.</p>
<h4>게임 프로그래밍을 위한 3차원 그래픽스</h4>
<p>전부터 느낀 건데 홍릉과학출판사는 기획력이 좋은 출판사입니다. 딱 필요한 책을 낼 줄 안다고 할까요. 아쉬운 점은 책 디자인 슈퍼 구려서 선뜻 사게 안된다는 점이죠 ^^ 이 책은 어려운 3D그래픽스를 매우 쉽게 풀고 있습니다. 얼렁 3D에 입문하고 싶다면 유명서적 보시지 말고 이 책으로 시작하실 권장합니다. 교육용으로 샀지만 직원들에게 과연 이걸 가르치면 따라올지는 미지수입니다. 다들 수학을 왜케 싫어하는 건지.</p>
<h4>Mastering Autodesk 3ds Max Design 2011</h4>
<p>전통있는 맥스 매뉴얼인 마스터링 시리즈의 2011버전용입니다. 국내엔 요상하게도 3D 저작툴 관련되어서는 역서가 절대로 출간되지 않고 있습니다. 뭔가 허접 저자들의 생존 현장인가요? 허접한 국내서로 공부해야 하는 현실이 참 안타깝습니다. 여튼 이번 스터디에서 공식적으로 사용하고 있는 툴이라 간만에 새 버전의 책을 샀습니다. 맥스라면 역시 마스터링이죠!</p>
<h4>3ds Max 2011 모델링 기법</h4>
<p>이 책은 일단 2011버전과 무관한 책입니다. 낚시성 제목인거죠. 그냥 불친절하고 실무적인 모델링 기법 책입니다. 그렇다고 내용이 나쁜 건 아니고 여러 예제를 이용해 모델링의 중급 기법을 가르칩니다. 그럭저럭 쓸만한가..싶은..정도</p>
<h4>캐릭터 셋업 테크닉</h4>
<p>맥스에서 키애니메이션을 잡기 위한 여러 가지 단계와 방법을 소상이 다루는 책입니다. 영진에서 출판되었던 여러 낚시성 책보다는 훨씬 실무적이면서 게임에 적용하기 좋게 되어있습니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/AZC_4eeY1vs" height="1" width="1"/>]]></content:encoded>
         <category>Books</category>
      <feedburner:origLink>http://book.diebuster.com/book/?p=263</feedburner:origLink></item>
      <item>
         <title>2011.10.10 밀린 북리뷰 정리 1/2</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/mLcHjkSpj3A/</link>
         <description>이건 머 저번 포스팅 보다 더 많이 쌓여서 심지어 두 번에 나눠서 올려야 할 지경이군요 ^^; 일단 1차로 갑니다. THE DESIGN OF SITES 이 굉장한 책이 번역되다니 너무 기쁩니다. 웹 기획서의 종결자라고 불러도 될 정도의 풍부한 예와 개론으로 구성 되어있어 웹 종사자 전원에게 강력히 추천할 수 있는 책입니다. 이 책의 중요한 특징은 웹을 서비스 유형에 [...]</description>
         <guid isPermaLink="false">http://book.diebuster.com/book/?p=262</guid>
         <pubDate>Mon, 10 Oct 2011 05:43:41 +0000</pubDate>
         <content:encoded><![CDATA[<p>이건 머 저번 포스팅 보다 더 많이 쌓여서 심지어 두 번에 나눠서 올려야 할 지경이군요 ^^; 일단 1차로 갑니다.</p>
<h4><img src="https://lh3.googleusercontent.com/-iaFqCJ0jQM4/TpJ4P5SR2pI/AAAAAAAAANk/ZNFi09qhHGM/s566/2.jpg" alt="" width="566" height="422"/></h4>
<h4>THE DESIGN OF SITES</h4>
<p>이 굉장한 책이 번역되다니 너무 기쁩니다. 웹 기획서의 종결자라고 불러도 될 정도의 풍부한 예와 개론으로 구성 되어있어 웹 종사자 전원에게 강력히 추천할 수 있는 책입니다. 이 책의 중요한 특징은 웹을 서비스 유형에 따라 패턴화 시키고 시각적인 특징 뿐만 아니라 분야별 서비스의 개론과 중요한 포인트를 알려주고 그러한 시점에서 예가 되는 웹사이트를 일일이 설명해주고 있습니다. 이런 교과서적이면서 동시에 실무적인 책은 정말이지&#8230;</p>
<h4>WebMatrix와 ASP.NET WebPages로 시작하는 웹 개발</h4>
<p>아직도 전 MS의 여러 가지 솔루션이 서로 침범하는 정책을 어%E에서 사용될 가능성이 있을까 싶습니다. 여튼 어느 날 갑자기 할지도 모르는 ASP.NET의 사내 교육용으로 구매했습니다.</p>
<h4>자바 병렬 프로그래밍, 멀티프로세서 프로그래밍, 인텔 스레딩 빌딩 블록</h4>
<p>최근에 병렬 프로그래밍이 너무 좋아서 계속 공부하고 복습하고 책도 사 모으고 있습니다. 이 세 권은 전부 그런 맥락입니다. 역시 최강의 책은 멀티프로세서 프로그래밍..명성 그대로의 책입니다. 인텔 스레딩 빌딩 블록은 사실 인텔 라이브러리 설명보다 개론적인 설명도 너무 좋고 오히려 머랄까..호스트 코드 입장에서의 인터페이스를 어떻게 제공하는 게 좋겠다는 힌트를 많이 줍니다. 자바 병렬 프로그래밍은 기본적인 내용입니다만 기본적이라 좋습니다.</p>
<h4>jQueryAPI</h4>
<p>음 사진을 찍고 보니 옛날 책을 찍었네요. 책도 비슷하게 생겼습니다. 사진과 달리 jQeuryAPI란 책은 1.6을 기반으로 API를 일목요연하게 정리한 책입니다. 예제들은 별로지만 기능에 대한 설명이 한글로 충실하게 적혀있으므로 평소 치트시트만 쓰시던 분들이 한 권씩 소장하시면 더 자세한 기능도 알 수 있어 좋습니다. 또한 입문자에게는 최신 버전을 번역한 거라 defer라던가 진보된 1.6의 기능을 포함해서 한걸음씩 배울 수 있는 교재가 될 수 있습니다.</p>
<h4>스마트폰 앱 개발을 위한 HTML5, 모바일 웹 개발, jQeury Mobile</h4>
<p>뭐 한참 유행처럼 번지는 모바일용 사이트 제작에 관련된 책입니다. 다 고만고만 합니다. 아직은 다수의 동의를 얻을 수 있는 방법론이나 아키텍쳐가 정립되어가는 과도기라 대부분의 책들도 그저 기능별 설명에 그치고 예제나 설명도 단편적입니다. 좀 더 기다리면 좋은 책이 나올 것도 같은데 말이죠.</p>
<h4>도메인 주도 설계, 도메인 주도 설계란 무엇인가?</h4>
<p>사실 위키북스에서 도메인 주도 설계의 역서를 냈는데 잽싸게 인사이트에서 저 얇은 무엇인가? 라는 책을 낸 것에 대해 매우 더러운 인상을 받았습니다. 이건 좀 상도 상 아니다 싶은데.. 일단 책에 대해서 설명 드리면 이 책은 절대로 반드시 결코 읽어야 할 책입니다. 그것도 여러 번! 도메인이란 영역이란 단어입니다. 여기서 말하는 영역이란 특정 프로그램을 제작할 때 이 프로그램이 속한 곳으로 이 곳에는 그 분야의 특성, 이걸 사용하는 사람들, 이걸 개발할 사람들 등 다양한 주체들이 한데 섞여 있는 곳입니다. 이러한 도메인에서 프로그래밍이란 어떤 식으로 제작 되어야 하는가에 대한 일종의 가이드 라인입니다. 실무적으로 이 책이 제시하는 방법을 따르기는 매우 어렵습니다만 읽고 나면 꽤나 굉장한 통찰력과 사고의 전환을 일으킵니다. 쨌든 제가 여지껏 쓴 모든 북리뷰를 통 털어 켄트백의 구현패턴 다음에 반드시 이 책을 읽어야 합니다.</p>
<h4>SQL Anti Pattern</h4>
<p>SQL은 집합언어이기 때문에 상태를 기반으로 하는 제어형언어의 개발자가 좋은 쿼리를 짜기 어렵습니다. 뭐랄까 언어적인 센스가 매우 다르다고 해야 할 지. 게다가 고난스러운 과정을 거쳐 한 번 SQL이 익숙해지고 나면 그 이후는 매우 편리하고 심지어 당연하게 쿼리를 작성하기 시작하지만 이 때 조심할 점은 원하는 결과를 얻는데 자유롭게 쿼리를 짤 수 있다고 해서 좋은 쿼리는 아니라는 점입니다. 일단 쿼리가 자유로워 지면 그 만큼 더욱 세세한 부분까지도 돌봐야겠죠. 성능 상의 문제나 보안, 무결성, 하드웨어의 사용 등 다양한 이슈에 하나하나 눈뜨게 됩니다. 그 모든 걸 학습해가며 익숙해지고 나면 그런대로 쓰게 되는데 이 때 문제는 이미 익숙해져서 그걸 입문자에게 전달하려고 하면 참 애매하다는 거죠. 그런 점에서 이 책은 일단 원하는 결과를 얻는 쿼리를 짤 수 있는 수준에 이른 사람이 다음 단계로 가기 위해 인식해야 할 내용을 명확한 패턴으로 분리하여 설명하고 있습니다. 뭔가 교재로 딱 입니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/mLcHjkSpj3A" height="1" width="1"/>]]></content:encoded>
         <category>Books</category>
      <feedburner:origLink>http://book.diebuster.com/book/?p=262</feedburner:origLink></item>
      <item>
         <title>bs11소개(플래시11용 3D Framework)</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/uVkVfSRzfqY/453</link>
         <description>플래시11 3D Framework 2011년 10월에 발표된 플래시11은 GPU를 활용한 3D 디스플레이가 가장 큰 특징으로, 종전에 표현할 수 없던 화려한 그래픽 경험을 제공합니다. 하지만 이면에는 복잡한 프로그래밍적 문제가 산적해 있습니다. 보통의 개발자가 이런 벽을 뚫고 플래시11의 기능을 활용하기는 매우 어렵습니다. 또한 장벽을 넘어도 복잡성과 개발 분량이 기존에 비해 월등해 생산성이 크게 낮아집니다. 따라서 그 어느 때보다 [...]</description>
         <guid isPermaLink="false">http://www.diebuster.com/flash/?p=453</guid>
         <pubDate>Sun, 09 Oct 2011 09:37:11 +0000</pubDate>
         <content:encoded><![CDATA[<h4>플래시11 3D Framework</h4>
<p>2011년 10월에 발표된 플래시11은 GPU를 활용한 3D 디스플레이가 가장 큰 특징으로, 종전에 표현할 수 없던 화려한 그래픽 경험을 제공합니다. 하지만 이면에는 복잡한 프로그래밍적 문제가 산적해 있습니다. 보통의 개발자가 이런 벽을 뚫고 플래시11의 기능을 활용하기는 매우 어렵습니다. 또한 장벽을 넘어도 복잡성과 개발 분량이 기존에 비해 월등해 생산성이 크게 낮아집니다.</p>
<p>따라서 그 어느 때보다 효과적인 외부 툴 연동을 필요합니다. 많은 부분을 외부의 저작 툴로 해결하고 프로그래밍은 필요한 기능만 추가하는 편이 적정한 제약 범위에서 만들 수 있게 해줍니다.</p>
<p>현재 플래시11을 지원하는 3D framework은 많은 종류가 있습니다. 각 특장점을 비교하는 것은 무리라 간단히 제 나름대로의 생각을 적어 봅니다.</p>
<p>일단 유, 무료로 구분할 수 있습니다. Flare3D, Unreal, Unity3D 등은 유료입니다. 유료는 지속적인 업데이트와 전용 개발 환경을 제공해주는 경우가 많습니다. 단점은 돈 내야 한다는 것 외에도 특정 회사의 개발 툴과 환경에 종속적이므로 향후 다른 시도를 할 때 전환 비용이 크게 들어갑니다. 이에 비해 무료는 지원, 책임감, 안정성 등이 약하고 지원 툴도 없는 경우가 많습니다. 하지만 돈이 안 들고 마음대로 소스를 뜯어보며 연구할 수 있는 장점이 있습니다.</p>
<p><span id="more-453"></span></p>
<h4>Alternative3D 8</h4>
<p>중간 형태의 라이브러리도 등장하고 있습니다. 무료지만 기업의 지원을 받고 있던가, 기업이 출자하여 개발하던 솔루션이 무료로 커뮤니티에 이양되는 경우입니다. 얼터너티바 3D 8(Alternative3D 8.x &#8211; 이하 <strong>얼터8</strong>)는 매우 특이한 케이스로 유료 라이브러리로 출발했지만 후에 기업의 지원을 받고 무료로 전환된 경우입니다. 저는 이런 점에서 얼터8을 높게 평가하고 있습니다. 신속한 환경의 변화에 대한 대응할 자금력도 확보되어 안정성 있게 유지할 가능성이 높기 때문이죠.</p>
<h4></h4>
<p>헌데 얼터8은 framework으로써 장단점이 미묘합니다. 안 좋은 면을 보면 단점이 너무 많고 동시에 좋은 면을 들여다 보면 장점도 많습니다. 쨌든 제가 느낀 얼터8의 소감을 간단히 정리하면 away4.x의 3배쯤 불친절하고, 1/3정도의 기능만 제공하며 2배쯤 코딩할 게 많다는 것입니다. 나쁜 면만 말하면 그렇고, 분명 좀 더 away4보다 빠르고 무엇보다 맥스(3D Max)의 연동에서 10배쯤 좋았습니다. 어쩌면 얼터8에 별 기능이 없는 이유는 맥스에서 대부분의 작업을 처리하고 읽어드려 사용하라는 의미일지도 모릅니다.</p>
<p>결론적으로 away4는 프로그래밍 인터페이스를 풍부하게 제공하는 반면 얼터8는 맥스와 연동을 고도로 지원하고 있습니다. 따라서 코드를 이용해 많은걸 만들고 싶다면 분명 얼터8 보다 away4를 추천합니다. 하지만 본격적인 게임이나 애플리케이션에서 코딩으로 창조하는 결과물은 한계가 분명합니다. 난해하고 우연적인 감각의 산물이 대부분입니다. 기획의도가 명확한 창조의 세계를 정교하게 전달하기 위해서는 맥스와 같은 저작도구의 도움을 받아야 하고 그러한 면에서 오히려 얼터8이 더욱 상용 솔루션을 만들기에 최적화 되어있는 셈입니다.</p>
<p>여담이지만 이러한 점 때문에 얼터8의 경우 away4보다 사용인구가 적을 수 밖에 없습니다. away4는 기존 플래시 개발자가 손쉽게 접근할 수 있는 API를 제공하는데 비해 얼터8는 맥스를 공부하길 훨씬 강력하게 요구하기 때문입니다.</p>
<h4>맥스와의 연동</h4>
<p>away4는 맥스 작업물을 매우 호환성이 나쁜 dae를 이용해 읽어 들입니다. 현재 away4와 완벽하게 연동되는 최신 버전의 맥스나 마야의 dae 플러그인은 없다고 봐도 무방합니다. 또한 dae를 만들어냈다고 해도 기본적으로 텍스트에 xml이기 때문에 파일용량도 크고 파싱에도 시간이 엄청나게 들어갑니다(away4는 이러한 이유로 dae파서가 함수로 호출되지 않고 이벤트로 완료를 보고하고 있는 지경입니다)</p>
<p>하지만 얼터8는 이런 점에서 완전히 다릅니다.</p>
<p>맥스2010과 2011에 맞는 전용 플러그인을 제공하고 있으며, 이 전용 플러그인을 이용해 A3D라는 전용 형식을 출력합니다. A3D는 애니메이션이나 카메라, 조명, 다양한 재질 정보를 전부 포함할 뿐만 아니라 이를 완벽하게 얼터8 클래스와 매핑할 수 있도록 설계된 이진 형식입니다.</p>
<p>따라서 매우 작은 용량으로 만들어질 뿐 아니라 파싱도 ByteArray를 읽어 들여 할당하는 방식이라 dae와 비교할 바가 아닙니다. 작은 모델 몇 개라면 몰라도 장대한 화면의 경우 100배 이상의 차이가 쉽게 발생합니다.</p>
<h4>얼터8을 사용하는 데 문제점</h4>
<p>그럼에도 불구하고 여전히 얼터8을 쓰기는 쉽지 않습니다. 얼터8이 쓰기 어려운 건 어찌 보면 당연한데, 기본적인 세 가지 장벽이 있습니다.</p>
<ol>
<li>플래시11의 3D환경을 이해하고 초기화할 수 있어야 한다.</li>
<li>3D를 이루는 기본 요소에 대한 이해와 이를 활용하는 수학적인 지식이 필요하다.</li>
<li>얼터8 API와 기능, 제약, 작동 방식을 익혀야 한다.</li>
</ol>
<p>당연하게도 얼터8은 플래시11의 3D기능을 기반으로 제작 되어 있습니다. 따라서 일부는 플래시11의 기능을 이해해야 얼터8도 사용할 수 있습니다. 하지만 이 부분은 기존 플래시10까지 없던 부분이라 완전히 새로운 영역입니다. 일단 이 점이 최초에 가로막는 장벽이 됩니다.</p>
<p>또한 얼터8은 3D를 만들어냅니다. 얼터8, 플래시11과 별도로 3D를 이해해야 합니다. 우리가 기존 2D에서 벡터와 비트맵의 차이를 알고 xy좌표계나 베지어 곡선을 알고 있는 것처럼 3D도 3D를 구성하는 기본 요소가 있습니다. 점, 삼각면, 서페이스, 매쉬, 컨테이너의 개념을 익히고 재질이 적용되는 구조와 조명과의 관계도 이해해야 합니다. 이건 오히려 첫 번째보다 더 큰 개념적인 장벽입니다.</p>
<p>이를 다 통과하시면 마지막으로 이러한 플래시11의 3D기능과 여러 개념을 어떻게 얼터8의 클래스로 표현되는지, 메서드를 사용하는지 배워야 합니다. 얼터8은 러시아에서 만들어진 라이브러리로 제법 독창적인 아키텍쳐를 갖고 있습니다. 암튼 공부해야겠지만 이것도 쉽지 않은 게 많은 문서가 러시아어로 되어있고, 도움말은 영어이긴 하지만 설명이나 예제가 부족하며, 시중에 역서는 물론 원서조차 출시되어있지 않은 상황입니다(2011.10월 현재)</p>
<p>이 세 가지 장벽을 다 깨부수고 전진하면 그 다음에 다시 다음의 세 가지 장벽이 나타납니다^^;</p>
<ol>
<li>얼터8은 3D관련 연산 메서드가 거의 제공되지 않으므로 수동으로 구현해야 한다.</li>
<li>물리엔진이 제공되지 않아 직접 다른 물리엔진과 연동을 구현해야 한다.</li>
<li>메모리를 통제하는 기능이 없으므로 복잡한 리소스의 업로드 관리를 직접 해야 한다.</li>
</ol>
<p>얼터8은 매우 가벼운 라이브러리입니다. 헌데 너무 가벼워서 제공되는 수학적 함수가 너무 부족합니다. 지역 좌표계 기준으로 회전이나 이동을 처리할 수 없고 특정 대상을 바라보는 등의 흔히 쓰는 기능에 대해서도 메서드를 제공하지 않습니다. 이러한 문제는 직접 구현한다고 완전히 해결되는 것은 아닙니다. 만약 얼터8 내부에 이것을 구현했다면 GPU를 응용할 수 있게 개선될 여지가 있지만(동적으로 AGAL을 수정하는 방식으로) 외부에서 이를 통제하면 CPU를 통한 연산을 해야 합니다. 하지만 현재로서는 그나마도 직접 구현해야 할 상황입니다.</p>
<p>얼터7계열에서는 살짝 지원되던 물리기능이 완전히 빠져있습니다. 또 다른 물리엔진을 가져와 붙여야 하는데 CPU를 사용하게 되므로 이도 성능에 나쁜 영향을 끼치게 됩니다.</p>
<p>메모리관리에 대한 얘기는 GPU에 로드 되는 쪽을 말하는 것입니다. 복잡한 화면은 다양한 재질용 이미지와 방대한 기하구조를 GPU에 올리게 되는데 너무 많이 올리면 작동하지 않으므로 적절하게 조정해야 합니다. 이러한 조정도 전부 개발자에게 맡기고 있으므로 효과적인 관리를 직접 해야 합니다.</p>
<h4>bs11의 목표</h4>
<p>bs11은 다음과 같은 목표를 갖고 개발되고 있습니다.</p>
<ol>
<li>고도의 생산성 &#8211; 매우 짧은 코드만으로도 효과적으로 개발할 수 있게 하면서 동시에 기능을 제약하지 않는 유연성을 동시에 제공하려 합니다.</li>
<li>직관적인 함수구조 &#8211; bs11내의 함수를 접두어 기반으로 정리하여 필요한 기능을 체계적으로 찾을 수 있게 도와줍니다.</li>
<li>효율적인 자원관리 &#8211; 그룹을 지원하여 3D리소스를 그룹별로 context3D에 올렸다, 내렸다 할 수 있는 기능을 지원합니다.</li>
<li>기타 기존의 DisplayObject, Event, Loader 등의 객체에 대한 추상층 제공 &#8211; 기존의 플래시 기능도 편리하게 사용할 수 있습니다.</li>
</ol>
<p>한 마디로 복잡하고 반복적인 일은 bs11에게 맡기자는 것입니다. 어떻게 그렇게 되는지는 수 차례에 걸친 포스팅으로 풀어가겠습니다.</p>
<p>현재 bs11은 구축단계로 기초 부분이 완성되었고 기능을 확장해가고 있습니다. 재밌는 개념을 도입하여 개발자의 실력과 무관하게 일정 수준의 품질이 유지되도록 노력하고 있습니다.</p>
<p>페이스북의 s49라는 스터디에서는 bs11을 활용한 다양한 3D 애플리케이션 제작도 10회에 걸쳐 진행 중입니다.</p>
<p>스터디나 bs11에 관심있는 분들은 제게 연락 주시면 답변해드리겠습니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/uVkVfSRzfqY" height="1" width="1"/>]]></content:encoded>
         <category>bs11</category>
      <feedburner:origLink>http://www.diebuster.com/flash/453</feedburner:origLink></item>
      <item>
         <title>지연평가 활용하기 #2</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/AAXZOV92CoA/441</link>
         <description>전 포스팅에서 지연실행의 기초를 다뤘습니다. 지연평가활용하기 #1 이번 포스트에서는 지연실행의 꽃이라 할 수 있는 함수를 통한 지연실행에 대해 써 볼까 합니다. 제어형 언어에서 지연실행은 크게 두 가지로 나눌 수 있습니다. 첫 번째는 저번에 다뤘던 평가 지연이고 다른 하나는 이 번에 다루는 호출 지연입니다. 제어형 언어의 3대 요소는 문(statement), 식 (expression), 할당 (assignment) 입니다. 이 중에서 [...]</description>
         <guid isPermaLink="false">http://www.diebuster.com/flash/?p=441</guid>
         <pubDate>Sat, 24 Sep 2011 04:33:35 +0000</pubDate>
         <content:encoded><![CDATA[<p>전 포스팅에서 지연실행의 기초를 다뤘습니다.</p>
<p><a rel="nofollow" target="_blank" href="http://www.diebuster.com/flash/177">지연평가활용하기 #1</a></p>
<p>이번 포스트에서는 지연실행의 꽃이라 할 수 있는 함수를 통한 지연실행에 대해 써 볼까 합니다.</p>
<p>제어형 언어에서 지연실행은 크게 두 가지로 나눌 수 있습니다. 첫 번째는 저번에 다뤘던 평가 지연이고 다른 하나는 이 번에 다루는 호출 지연입니다. 제어형 언어의 3대 요소는 문(statement), 식 (expression), 할당 (assignment) 입니다.</p>
<p>이 중에서 문과 식은 평가 지연을 일으킬 수 있습니다. 평가 지연이란 평가가 일어날 때까지 특정 명령을 실행하지 않고 대기 시켜 두는 것을 말합니다(구체적인 내용을 저 번에 다뤘습니다 ^^) 호출 지연이란 말 그대로 호출을 하는 시점까지 실행하지 않고 대기 시키는 기능입니다. 평가 지연은 평가 시점 자체를 조절할 수 없다는 점에서 일일 호프에 가는 길을 표시하기 위해 바닥에 붙여둔 화살표 판들이라 이해할 수 있습니다. 유도하여 그 일이 일어나게 미리 장치해두는 것이죠. 이건 마치 바둑이나 장기처럼 미리 일어날 일을 예측해서 포석을 깔아두는 방식이라 수가 깊어질 수록 통제가 제대로 되지 않습니다. 이 점이 평가 지연을 한 두 단계만 일어나게 끊어버리는 이유입니다. 가령 조건문을 두 번 이상 중첩하지 말라던가 하는 식입니다. 이에 비해 호출 지연은 피자가 먹고 싶을 때 전화를 걸어 주문하는 것과 마찬가지로 이해할 수 있습니다.<br />
모든 문제의 근원은 사람인데 사람에겐 평가 지연을 정교하게 배치하는 것보다 호출 지연을 사용하는 것이 훨씬 사고하기 편리합니다. 여담이지만. 평가 지연을 정교하게 깔아두는 방식의 프로그램이 바로 수학적 프로그램입니다. 수학이란 어쩔 때 보면 인간의 본성을 거스르고 있다는 생각도 가끔 합니다. 수학적 프로그래밍은 보통 순수한 함수형 언어에서 개발하는 방법입니다.</p>
<p><span id="more-441"></span></p>
<h4>호출 지연 사용하기</h4>
<p>호출 지연을 사용하려면 단순히 함수를 만들고 호출하는 것으로는 안됩니다. 그렇게 하면 함수의 호출이 실행흐름에 따라 자동으로 일어나기 때문에 원하는 시점에 호출할 수 없습니다. 따라서 호출할 함수 자체를 기억해뒀다가 원할 때 호출하는 방법을 사용해야 합니다.<br />
파워플의 제 포스트 내용 중에 함수가 어떻게 객체가 되는지를 개념적으로 다룬 글이 있습니다.</p>
<p><a rel="nofollow" target="_blank" href="http://powerfl.com/?p=2503">rest인자의 활용</a></p>
<p>이 글의 초반에 나오는 함수의 가상 객체 부분을 보시면 함수도 하나의 객체가 될 수 있다는 생각이 드실 겁니다. 요점은 as에서 함수는 일반적인 참조 객체로 변수에 저장할 수 있기 때문에 호출지연을 위해 그저 함수 자체를 변수에 저장해두면 된다는 점입니다.<br />
따라서 아래와 같이 함수를 변수에 담았다가 원할 때 호출할 수 있습니다.</p>
<pre>
function log():void{
	trace( 'test' );
}

var func:Function;
func = log;

func();
</pre>
<p>하지만 함수란 인자를 받을 수 있습니다. 인자를 받을 수 없는 함수는 기능이 제한되기 때문에 필요에 따라 너무 많은 함수를 만들어야 합니다. 하지만 인자는 함수를 호출할 때 전달되기 때문에 사실 함수에 넘겨질 인자는 함수를 저장하는 시점에 같이 저장해야만 나중에 원하는 결과를 얻을 수 있습니다. 이를 코드로 표현하면 아래와 같습니다.</p>
<pre>
function log( $msg:String ):void{
	trace( $msg );
}

var func:Function, msg:String;
func = log;
msg = 'test';

func( msg );
</pre>
<p>이러한 상황은 함수 한 개와 인자 한 개를 잡아둘 때는 괜찮지만 다양한 함수와 그 인자를 잡아두르면 처음부터 인자를 배열로 저장해두고 함수객체의 apply를 이용하는 편이 보다 일반화 할 수 있습니다.</p>
<pre>
var func:Function, arg:Array;
func = log;
arg = ['test'];

func.apply( null, arg );
</pre>
<h4>defer와 invoker</h4>
<p>그럼 이상의 내용을 요약하여 하나의 클래스로 정의하고 이 이름을 defer(지연)이라고 부르겠습니다.</p>
<pre>
class Defer{

	private var _func:Function;
	private var _arg:Array;

	public function Defer( $func:Function, $arg:Array = null ){
		_func = $func;
		_arg = $arg.concat();
	}

	public function run():*{
		if( _arg ){
			return _func();
		}else{
			return _func.apply( null, _arg );
		}
	}
}
</pre>
<p>내용은 워낙 쉽습니다만 run에서 인자가 있냐 없냐로 apply를 사용할지 말지를 결정해 성능 상의 이득을 보게 해뒀습니다.</p>
<p>이제 호스트 코드를 다음과 같이 작성할 수 있습니다.</p>
<pre>
function log( $msg:String ):void{
	trace( $msg );
}

var defer:Defer;
defer = new Defer( log, ['test'] );
defer.run();
</pre>
<p>일단 defer를 맘대로 쓸 수 있으면 이를 묶어 커맨드 셋을 만들 수 있습니다.</p>
<pre>
var greeting:Array;
greeting = [
	new Defer( log, ['안녕~'] ),
	new Defer( log, ['난 노노야.'] ),
	new Defer( log, ['바이바이'] )
];
</pre>
<p>그럼 커맨드 셋 단위로 실행시킬 인보커 함수를 하나 만들어야 합니다.</p>
<pre>
function invoker( $commans:Array ):void{
	var i:int, j:int;
	for( i = 0, j = $commands.length ; i &amp;lt; j ; ++i ){
		$commands.run();
	}
}
</pre>
<p>이젠 커맨드를 인보커 함수를 통해 언제라도 호출할 수 있게 됩니다.</p>
<pre>
invoke( greeting );
invoke( introduce );
</pre>
<p>추상화 단계를 거칠 수록 함수를 변수로 잡아두는 것은 자연스레 은닉되고 그러함 함수와 인자를 셋트로 묶어 다양한 의미를 부여할 수 있게 됩니다.</p>
<h4>이벤트 리스너로 사용하기</h4>
<p>이벤트에 등록되는 리스너는 조건이 단일한 하나의 인자인 Event를 받아들인다는 점입니다. 위에서 작성한 defer는 run이 호출될 때 어떠한 인자도 받지 않습니다. 그럼 defer의 run을 약간만 개조해서 일반적으로도 사용할 수 있고 이벤트 리스너로도 사용할 수 있게 개조해보죠.</p>
<pre>
class Defer{

	...

	public function run( ...arguments ):*{
		if( _arg ){
			return _func();
		}else{
			return _func.apply( null, _arg );
		}
	}

}
</pre>
<p>저렇게 하면 run이 인자를 자유롭게 받아들일 수 있으므로 이벤트 리스너로 사용할 수 있게 됩니다. 이제 여러 버튼에 클릭 이벤트를 걸 때 각각 다른 메세지를 출력하는 호스트코드를 간단히 작성할 수 있게 됩니다.</p>
<pre>
function log( $msg:String ):void{
	trace( $msg );
}

var defer0:Defer, defer1:Defer, defer2:Defer, defer3:Defer;
defer0 = new Defer( log, ['안녕'] );
defer1 = new Defer( log, ['잘자'] );
defer2 = new Defer( log, ['배고파'] );
defer3 = new Defer( log, ['밥먹자'] );

buttun0.addEventListener( 'click', defer0.run );
buttun1.addEventListener( 'click', defer1.run );
buttun2.addEventListener( 'click', defer2.run );
buttun3.addEventListener( 'click', defer3.run );
</pre>
<h4>인보커도 리스너로 사용하기</h4>
<p>위에서 인보커를 클래스로 정의하지 않고 함수로 정의했는데 이를 확장하여 클래스로 정의하면 인보커 자체도 이벤트의 리스너로 사용할 수 있게 됩니다.</p>
<pre>
class Invoker{

	private var _commands:Array;

	public function Invoker( $commands:Array ){
		_commands = $commands.concat();
	}

	public function run( ...arguments ):*{
		var i:int, j:int;
		for( i = 0, j = _commands.length ; i &amp;lt; j ; ++i ){
			_commands[i].run();
		}
	}
}
</pre>
<p>이제 defer 여러 개를 묶어 인보커에 전달하고 인보커를 리스너로 사용해 보죠.</p>
<pre>
function log( $msg:String ):void{
	trace( $msg );
}

var invoker:Invoker;
invoker = new Invoker( [
	new Defer( log, ['안녕'] ),
	new Defer( log, ['배고파'] ),
	new Defer( log, ['밥먹자'] ),
	new Defer( log, ['잘자'] )
] );

button.addEventListener( 'click', invoker.run );
</pre>
<h4>결론</h4>
<p>defer객체를 이용하면 손쉽게 커맨드패턴을 구현할 수 있을 뿐만 아니라 커스텀이벤트를 정의해야할 필요가 없어집니다. 함수 뿐 아니라 함수의 인자도 동시에 참조해둘 수 있는 구조를 이용해 인보커까지 확장하면 함수를 호출하는 행위 자체로 새로운 구조의 언어를 작성할 수 있습니다.</p>
<p>지연 호출은 매우 강력한 언어의 기능으로 이미 C의 함수포인터 등 전통적으로 내려오는 프로그래밍 기법입니다. 체계적이고 안전한 방법으로 응용하면 프로그램을 매우 유연하고 컴팩트하게 작성할 수 있습니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/AAXZOV92CoA" height="1" width="1"/>]]></content:encoded>
         <category>3 흐름제어</category>
      <feedburner:origLink>http://www.diebuster.com/flash/441</feedburner:origLink></item>
      <item>
         <title>2011.06.20 밀린 북리뷰 정리</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/ZnMC9PVx4tg/</link>
         <description>나중에 한 권씩 리뷰를 한다고는 해도 일단 너무 많은 책들이 밀리고 있어서 한 번쯤 정리해야겠다고 생각했습니다. 바쁘다는 핑계로 방치하다가는 더 이상 한 장의 사진으로 찍을 수 조차 없게 될 듯하네요. ActionScript Beautifl Code 이케다군의 새로운 책입니다. 동경&amp;#8230;방사능.. 이케다군은 건강한건가. 머 스카이프로 가끔씩 대화해보면 괜찮게 살고 있는 듯합니다만. 쨌든 다시 책으로 돌아와서, 원더플에서 괜찮은 샘플만 모아서 [...]</description>
         <guid isPermaLink="false">http://diebuster.com/book/?p=256</guid>
         <pubDate>Mon, 20 Jun 2011 07:42:27 +0000</pubDate>
         <content:encoded><![CDATA[<p>나중에 한 권씩 리뷰를 한다고는 해도 일단 너무 많은 책들이 밀리고 있어서 한 번쯤 정리해야겠다고 생각했습니다.<br />
바쁘다는 핑계로 방치하다가는 더 이상 한 장의 사진으로 찍을 수 조차 없게 될 듯하네요.</p>
<h4>ActionScript Beautifl Code</h4>
<p>이케다군의 새로운 책입니다. 동경&#8230;방사능.. 이케다군은 건강한건가. 머 스카이프로 가끔씩 대화해보면 괜찮게 살고 있는 듯합니다만. 쨌든 다시 책으로 돌아와서, 원더플에서 괜찮은 샘플만 모아서 정리한 뷰티플이라는 사이트를 이케다군 스스로가 운영하는데 그 사이트에서 다시 좋은걸 추려서 책으로 꾸렸습니다. 이것참 굉장한 자가 출판 시스템 아닌가요 ^^; 컨텐츠 홀딩 사이트를 만들어서 그 사이트로부터 다시 오프라인 책을 출간하다니 참 이케다군의 열정엔 이길 수 없을 듯합니다. 책 평을 하다가 자꾸 세는군요 ^^;<br />
여튼 이 책은 원더플의 여러 인기있는 소스였다 이겁니다. 그래서 다양한 라이브러리를 사용하는 예제가 한가득 들어있습니다. 말로만 들어봤던 라이브러리를 사용하는 호스트코드의 향연을 즐기세요.</p>
<h4>Papervision3D Essentials</h4>
<p>어웨이 에센셜과 마찬가지 구성으로 씌여진 교과서적인 책입니다. Papervision에서 각 기능을 바르고 정확하게 구현하기 위한 정석이랄까..</p>
<h4>네이버, 구글에도 없는 인터넷광고마케팅을 컨설팅하라</h4>
<p>그러니까 현재 가장 효과적이고 저렴한 홍보방안은 바로 인터넷 광고입니다. 근데 그걸 실제로 어떻게 하는지 아세요? 이 책은 당신이 직접 광고를 인터넷에 하고 싶다면 어떻게 해야하는가에 대한 책입니다. 입문자들에게 매우 재밌는 내용으로 가득합니다.</p>
<h4>웹개발자를 위한 웹을 지탱하는 기술</h4>
<p>일본책답게 매우 설명이 아기자기 잘되어있습니다. 이 책은 웹이라 불리는 환경을 구성하는 다양한 프로토콜 및 기반 기술을 설명하는 책으로 반드시 읽어야하는 책입니다. 원래 Web Protocols and Practice라는 교과서적인 책이 있는데 역서가 국내에 안나왔었죠. 이 책이라면 충분히 그 역할을 해낼 수 있을 듯합니다. 웹 프로그래밍을 배우기 전에 웹의 근간이 되는 기술을 먼저 배우세요!</p>
<h4>ExtJS 웹 애플리케이션 개발</h4>
<p>나중에 리뷰하겠습니다. 머 간단히 말해 유명한 자바스크립트 프레임웍 해설서랄까..</p>
<h4>테스트 주도 ASP.NET MVC 프로그래밍</h4>
<p>웹개발을 테스트주도로 구현하는 상세한 과정을 보여줍니다. 하지만 닷넷 MVC프레임웍의 이해가 없다면 좀 어렵습니다만..</p>
<h4>프로세싱, 날개를 달다</h4>
<p>프로세싱 역서가 두 권째 니왔군요. 훨씬 자세히 설명하고 있지만&#8230;이것도 나중에 자세한건&#8230;</p>
<h4>기업정보공장</h4>
<p>번역이 영 안좋다기보다 어려운 단어들로 구성된 책입니다. 사전 지식이 없으면 역서가 더 어려울지도 모르겠습니다.<br />
여튼 경영학과에서 배우는 전문가 시스템이나 의사결정 지원 시스템을 포괄하여 데이터마트나 웨어하우스가 어떤식으로 구성되고 어떻게 운영하는게 현시점에서 좋은가를 제안하고 있습니다. 좋군요. 이것도 나중에 더 자세히 리뷰를&#8230;ㅎㅎ 과연..</p>
<h4>okgosu의 플렉스 4.5 &#038; 플래시 빌더 정석</h4>
<p>전 왠만하면 국내 저자의 어도비 플랫폼 개발책을 빠짐없이 구매하고 있습니다.</p>
<h4>SQL Injection</h4>
<p>오호 이 주제로 책을 한 권 내다니 나름 요즘 이슈에 맞지 않나 싶습니다. 다양한 이슈를 포괄적으로 다루고 있습니다. 입문자용이라 그다지 리뷰할 내용이 많지는 않지만 기본이 중요한거죠!</p>
<p>이 외에도 더 있습니다만, 아아 이제 다시 밀리지 않고 잘쓰길 스스로에게 기대하며&#8230;=.=;</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/ZnMC9PVx4tg" height="1" width="1"/>]]></content:encoded>
         <category>Books</category>
      <feedburner:origLink>http://book.diebuster.com/book/?p=256</feedburner:origLink></item>
      <item>
         <title>Away3D 3.6 Essentials (11/04/28)</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/Q-uC8S8PMoA/</link>
         <description>Away3D 3.6 Essentials Matthew Casperson 지음/PACKT 기존에 책에 대한 리뷰를 여러권 합쳐서 할 때보다 한 권씩 하다보니 훨씬 심도있게 소개하고 싶은 욕심이 납니다. 이 책도 손에 넣어 이리저리 구경한지는 꽤나 오래 되었지만, 리뷰를 쓸 마음이 들 때까지 몇 번인가 다시 보았습니다. 몇몇 분은 아시다시피 전 현재 모든 플래시의 그래픽을 어웨이3D에 의존하여 처리하고 있습니다. 2D, 3D [...]</description>
         <guid isPermaLink="false">http://diebuster.com/book/?p=247</guid>
         <pubDate>Wed, 27 Apr 2011 12:13:40 +0000</pubDate>
         <content:encoded><![CDATA[<div style="text-align:center;margin-bottom:10px;"><img alt="" title="&#x00c27d;&#x00ace0; &#x00be60;&#x00b974;&#x00ac8c; &#x00c775;&#x00d788;&#x00b294; CSS3" style="border:1px solid #666;margin-bottom:5px;"/><br />
Away3D 3.6 Essentials<br />
Matthew Casperson 지음/PACKT</div>
<p>기존에 책에 대한 리뷰를 여러권 합쳐서 할 때보다 한 권씩 하다보니 훨씬 심도있게 소개하고 싶은 욕심이 납니다.<br />
이 책도 손에 넣어 이리저리 구경한지는 꽤나 오래 되었지만, 리뷰를 쓸 마음이 들 때까지 몇 번인가 다시 보았습니다.</p>
<p>몇몇 분은 아시다시피 전 현재 모든 플래시의 그래픽을 어웨이3D에 의존하여 처리하고 있습니다. 2D, 3D 모두 말이죠.<br />
이유는 여러가지가 있습니다만 결국 앞으로 모힐등의 완전한 GPU기반의 그래픽 시대는 온다고 이미 재작년 정도에 생각했기 때문에 거기에 대응하여 일반적인 dx나 gl기반의 게임이 그러하듯 3D를 2D그래픽에도 응용하도록 회사의 전반적인 디스플레이 프레임웍을 정리한거죠.</p>
<p>이 중 수 많은 3D프레임웍중에 어웨이3D를 고른 이유는 정지화면에서 렌더링된 품질이 DisplayObject와 완전히 동등했기 때문입니다. 다른 3D프레임웍들은 여전히 정지 화면을 보면 텍스쳐가 입혀진 그래픽이 매우 거칠게 표현되고 왜곡없는 정면의 1:1 사각형안의 텍스쳐된 이미지가 동일한 사이즈의 Bitmap객체처럼 이쁘게 보이지 않았습니다.</p>
<p>해서 이미 개인적으로는 현재 플래시의 모든 그래픽을 어웨이3D로 처리하고 있었다는 것이죠. 제게 어웨이3D가 갖는 의미는 단순히 가끔 써야하는 3D프레임웍이 아니라 매우 근본적으로 의존하고 있는 중요 모듈인 셈입니다.</p>
<p>항상 제가 촉각을 세우고 어웨이3D관련 책자와 개발자들의 블로그를 디깅하는게 아닌거죠.</p>
<p>이러한 노력은 결국 플래시가 모힐로 전환되는 시점에서 자연스레 그 위력을 발휘하고 있는데 큰 변화없이 사내 프레임웍은 플11기반으로 이사할 수 있는 여건이 갖춰진 셈입니다. 심지어 기저의 프레임웍swc만 바꾸면 기존 프로젝트의 호스트코드는 변경없이 모힐기반으로 이사갈 수 있게 되었습니다.</p>
<p>여튼 어웨이3D에센셜 이 책 말인데요&#8230;<br />
다 읽고 나서 든 생각은 여태 제가 알고 있던 어웨이3D가 2.x대의 구닥다리였다는 것이었습니다.</p>
<p>이는 마치 제가 요즘 많이 강조하고 떠들고 다니는 플9시절의 기술로 플10이후의 개발을 하지말아라 와 비슷한 맥락인데 플10의 기능을 완전히 흡수한 어웨이3D 3.x대는 2.x대와는 전혀 다른 강력한 기능으로 무장되어있었습니다.</p>
<p>여태 나름대로 잘 알고 있다고 생각했던 어웨이3D의 지오메트리, 프리머티브, 재질, 기하유틸 등 모든 분야의 기능에 대해 어웨이3D 3.6의 기능을 절반도 활용 못하고 있던 제 자신이 어이없고 오만했다는 생각에 한심해졌습니다.</p>
<p>이 책은 어웨이3D 3.6에 대해 지면의 한계 이내에서 뭐하나 대충 넘어가는 법 없이 정말 꽉꽉 채워서 극도로 정리된 표와 예를 이용해 집요하리 만큼 철저하게 가르칩니다. 개인적인 책에 대한 느낌을 표현하자면 &#8220;이 책이 있다는 이유만으로도 다른 라이브러리를 사용할 수 없다.&#8221;  정도 입니다.</p>
<p>기존에 플래시3D를 써오셨던 분들이나 앞으로 사용하시게 될 분들께 전부 추천드리고 모힐시대에 구지 저수준 쉐이더랑 뒹구실 분들은 몰라도 고수준 프레임웍을 사용하실 분들은 이 책으로 충분히 어웨이4에 대비하실 수 있다고 말씀드릴 수 있습니다.</p>
<p>사담인데 어느샌가 포토샵잘하는 것만으로 플래시를 잘 쓸 수 없게 되었던걸 기억하시죠? 모션이 크게 플래시에 들어오면서 프리미어와 애팩을 포샵처럼 자유롭게 쓰는 사람이 훨씬 고품질의 플래시를 만들어낼 수 있는 세상이 되어있습니다.</p>
<p>마찬가지로 여러분들이 직접 모델링을 하는 사람이 안되더라도, 맥스를 포샵처럼 편하게 사용하여 남이준 모델을 이리저리 갖고 놀고 편집하는게 마치 디자이너가 준 PSD를 이리저리 굴려 쓰는 것만큼이 편하게 되도록 훈련해야하는 건 앞으로의 많은 분들에겐 꼭 필요한 일이 될 것입니다.</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/Q-uC8S8PMoA" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://book.diebuster.com/book/?p=247</feedburner:origLink></item>
      <item>
         <title>Bitmapdata를 관리하기</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/7UZcMWRsWQU/181</link>
         <description>플래시로 컨텐츠를 제작한 결과는 swf파일이 됩니다. swf파일은 간단한 형식의 바이너리 파일로 일명 abc포멧이라 불리는 규격으로 만들어집니다. 이 규격은 매우 간단하기 때문에 간단한 컨텐츠의 경우는 hex에디터에서 손으로 만들 수 있는 수준입니다(php의 ming이라던가 다른 여러가지 프로젝트들이 있습니다^^) 이 abc포멧을 분석하다보면 mp3나 jpg등이 거의 날로 swf에 포함되어 있다는 사실을 알 수 있습니다. 반대로 말하자면 mp3나 jpg만 최적화 해도 [...]</description>
         <guid isPermaLink="false" />
         <pubDate>Wed, 16 Feb 2011 18:04:38 +0000</pubDate>
         <content:encoded><![CDATA[<p>플래시로 컨텐츠를 제작한 결과는 swf파일이 됩니다. swf파일은 간단한 형식의 바이너리 파일로 일명 abc포멧이라 불리는 규격으로 만들어집니다. 이 규격은 매우 간단하기 때문에 간단한 컨텐츠의 경우는 hex에디터에서 손으로 만들 수 있는 수준입니다(php의 ming이라던가 다른 여러가지 프로젝트들이 있습니다^^)</p>
<p>이 abc포멧을 분석하다보면 mp3나 jpg등이 거의 날로 swf에 포함되어 있다는 사실을 알 수 있습니다. 반대로 말하자면 mp3나 jpg만 최적화 해도 swf의 용량을 크게 줄일 수 있다는 결론이 나옵니다.</p>
<p>하지만 현대의 컨텐츠는 무지막지한 이미지와 사운드를 요구하기 때문에 사실 자원에 대한 최적화가 그다지 의미없는 경우가 많습니다.</p>
<p>따라서 이미지 자체도 최적화하고 런타임에 필요한 자원을 로드하여 적시에 사용하는 방법을 병행하여 제한된 네트웍 속도 내에서 원할하게 작동하도록 설계하는 방식이 도입되고 있습니다. 최근 오픈된 많은 플래시 컨텐츠들은 프리로더가 없거나 최소로 작동하게 되어 있는데 바로 이러한 점층적 로딩을 반영한 것이라 할 수 있습니다.</p>
<p>진짜 문제는 여기서 부터인데 분산하여 로딩하는 기술은 더욱 대규모의 이미지 자원을 로딩하게 하는 결과를 만들어낸다는 것입니다.</p>
<p>따라서 이전까지는 gc가 작동하는 타이밍 정도에 이미지리소스가 메모리에서 해제되어도 괜찮았던 것이 현재는 더욱 빨리 메모리에서 효율적으로 제거하지 않으면 gc가 작동하시기 전에 avm2자체가 세상에서 하직하고 맙니다. 이는 브라우저 등에서 플로그인모드로 작동하는 경우 더욱 심각해집니다. 브라우저들은 플러그인에 대해 제한된 메모리와 cpu사용권을 주고 있기 때문이죠.</p>
<p><span id="more-181"></span></p>
<p>근데 이 이슈가 하필 이미지냐..<br />
이미지 한 장이 잡아먹는 메모리가 여타 다른 언어 요소가 사용하는 메모리양과 비교가 되지않을 정도로 크기 때문입니다. 이미지만 적시에 내려도 그럭저럭 위기는 없고 충분히 gc타이밍에 처리될 수준으로 내려갑니다. 업무용 플렉스어플이야 워낙 데이터로드가 많으니 별도라 쳐도 그외의 어플들은 제법 살만해지는 거죠</p>
<h4>애매한 dispose와 참조의 관계</h4>
<p>일단 아래와 같이 어떤 bitmapData를 로더로부터 얻었다고 합시다.</p>
<pre>
var b:bitmapdata = $e.target.content.bitmapData;
</pre>
<p>그럼 먼저 clone을 뜨고 원본을 dispose()시켜야 합니다. 이유는 그래야 loader객체와 그 자식인 content가 안전하게 gc대상이 되면서 향후 어플에서는 얻어온 비트맵을 자유롭게 사용할 수 있기 때문입니다. gc는 편리하지만 참조가 꼬리를 물지 않게 하려면 매우 주의깊게 객체를 관리해야 합니다. 코드로 보죠.</p>
<pre>
var _bitmap:BitmapData:

function load( $url:String, $complete:Function ):void{

	var loader:Loader = new Loader:

	loader.loadInfo.addEventListener( Event.COMPLETE, function( $e:Event ):void{

		//사본을 얻고
		_bitmap = $e.target.content.bitmapData.clone();

		//원본은 제거하고
		$e.target.content.bitmapData.dispose();

		//완료보고
		$complete( this );
	} );

	loader.load( new URLRequest( $url ) );
}
</pre>
<p>위의 코드에서 loader와 리스너가 모두 지역변수이고 bitmap을 얻은 후 참조를 유지하는 대상이 없기 때문에 안전하게 gc대상이 됩니다. 하지만 gc가 일어나기 전에 미리 dispose()를 통해 필요없는 비트맵을 제거합니다. 만약 위에서 clone()을 하여 _bitmap에 할당하지 않고 직접 할당하게 되면 참조관계가 꼬리를 물어 결국 loader까지도 전부 gc되지 않게 됩니다.</p>
<h4>dispose()</h4>
<p>하지만 위의 코드는 동적으로 로딩한 이미지를 얻는 과정에서 부산물인 loader를 성공적으로 객체참조 해지 했을 뿐 보다 근본적인 _bitmap의 강제 해지 시점을 해결한 건 아닙니다.</p>
<p>간단히 _bitmap.dispose() 할 시점을 생각해보면</p>
<p>1. 아무도 이 비트맵을 사용하지 않고<br />
2. 앞으로도 사용하지 않을 때</p>
<p>라고 할 수 있습니다.</p>
<p>근데 그게 언제인가요? ^^;</p>
<p>이 질문은 거의 gc를 제작하는 것만큼이나 어려운 질문입니다. 하지만 특수한 상황이니 범위를 한정지어 질문을 반대로 생각해봅시다.</p>
<h4>현재 사용 중인가를 판단하는 근거</h4>
<p>간단하게는 비트맵 사용 현황을 카운트해보면 알 수 있겠죠. 아이폰 덕분에 매우 유명해진 retain, release 개념은 사실 풀링의 기본 알고리즘입니다. 중앙에서 자원을 줄 때 retain을 통해 참조카운트를 하나 올리면 증가는 간단히 해결됩니다.</p>
<pre>
class BitmapSRC{

	var _count:int;
	var _bitmap:BitmapData:

	public function BitmapSRC(){}

	public function load( $url:String, $complete:Function ):void{...}

	public function getBitmapData():BitmapData{
		//카운터를 증가시킴
		++_count;
		return _bitmap;
	}

}
</pre>
<p>그럼 카운트를 줄이는건 언제인가요?</p>
<p>물론 명시적으로 자원을 반환하는 경우가 있겠습니다. 이 경우는 release를 호출하면 됩니다.</p>
<pre>
class BitmapSRC{
	...
	public function release( $e:Event = null ):void{
		--count;
	}
}
</pre>
<p>하지만 자동으로 반환하는 경우도 생각해볼 수 있습니다. (귀찮기 때문에..^^)<br />
자동반환은 다양한 이슈가 있겠지만 디스플레이 오브젝트 기준이라면 가장 합리적인 것은 스테이지에서 내려갈 때라고 할 수 있죠(Event.REMOVE_FROM_STAGE)</p>
<pre>
//이거슨 호스트 코드!

var src:BitmapSRC = new BitmapSRC:

src.load( 'girl.jpg', complete );

function complete( $src:BitmapSRC ):void{
	var bitmap:Bitmap;

	//새비트맵에 데이터할당
	bitmap = new Bitmap( $src.getBitmapData() );

	//스테이지에서 제거될 때 자원참조 카운터도 줄인다.
	bitmap.addEventListener( Event.REMOVE_FROM_STAGE, $src.release );

	stage.addChild( bimap );

	//remove될 때 참조카운터 감소!
	stage.removeChild( bitmap );

}
</pre>
<p>위의 코드에서 remove가 된 후의 _count는 0이 됩니다.<br />
이 과정을 자동으로 처리하려면 역시 자원을 가져갈 때 인자로 자동인지 아닌지 선택할 수 있게 getBitmapData를 보완해주는 것이 좋겠습니다.</p>
<pre>
class BitmapSRC{
	...
	public function getBitmapData( $isAutoRelease:Boolean = false, $target:DisplayObject = null ):BitmapData{

		++_count;

		if( $isAutoRelease &amp;&amp; $target ){ //오토릴리즈에 타겟도 넘겨받았다면!

			//아까 호스트코드에서 하던 짓을 여기서 한다.
			$target.addEventListener( Event.REMOVE_FROM_STAGE, release );
		}

		return _bitmap;
	}
	public function release( $e:Event = null ):void{

		--count;

		if( $e ){ //이벤트에 의해 release가 온 경우에는

			//리스너를 해지해준다.
			$e.target.removeEvent( $e.type, arguments.callee );

		}
	}
}
</pre>
<p>제가 잘 쓰는 away의 경우는 컨테이너에서 제거될 때 다른 이벤트로 처리되므로 어떤 경우인가에 따라 자원을 자동해지 시키는 방법을 확장할 수 있도록 해야합니다.<br />
(이건 과제로 내기로 하고&#8230;^^)<br />
암튼 그래서 결국 카운트가 0인 자원은 사용 중이 아니라고 할 수 있겠죠.</p>
<h4>앞으로도 사용하지 않을 때는?</h4>
<p>그러니까 말이죠. 객체 참조 카운터야 어떻게든 관리를 하면 되는데 대체 앞으로도 사용하지 않을 것 같다라는 건 어떻게 아냐는거죠. </p>
<p>사실은 모릅니다 ^^; 갑자기 어떤 경우에 쓸지 모르는 가능성이야 항상 있는거 아니겠습니까.</p>
<p>하지만 무한히 낮은 가능성 때문에 메모리에서 해지하지 않고 있다면 그것 또한 웃기는 일입니다. 이러한 중간 타협점이 바로 GC라 할 수 있지만 GC알고리즘는 이미 일어난 일만 처리할 수 있도록 되어있지 미래를 예상하도록 되어있지는 않습니다.</p>
<p>본래 언어수준에서 바인딩된 GC알고리즘을 수행하는 쓰레드의 경우 메모리를 정적, 스택, 힙으로 나누고 정적영역과 스택에서 선언한 힙메모리 참조를 전부 뒤져서 실제 힙에 있는 메모리가 스택과 정적메모리에 매칭되는 참조가 없는 경우 해당 객체의 힙메모리를 해지하는 식으로 작동합니다(풀어쓰기 생략..=.=)</p>
<p>위의 비트맵자원의 경우 사실 _count가 0이 되면 어디에도 참조가 없다는 뜻이므로 사실 곧장 제거해도 무방합니다.<br />
단지 그 이후에 그것을 사용하려고할 때 없는 자원이 되어서 문제인거죠.</p>
<p>따라서 GC의 방식을 사용할 수는 없고 두가지 다른 대안을 마련할 수 있습니다.</p>
<p>1. 타이머를 통해 count가 0이 된 뒤 일정시간까지 계속 count가 0 이라면 해지한다.<br />
2. drain을 통해 일괄로 흡수한다.</p>
<p>drain도 아이폰 덕분에 많이 유명해졌습니다. pool을 정리하는 과정이라 보시면 되는데, 명시적으로 drain을 호출하면 자원을 무조건 초기화하면 됩니다. 즉 유저가 더 이상 이 자원은 사용하지 않겠다라고 선언한다는거죠. 그건 간단하니 구현도 쉽습니다.</p>
<pre>
class BitmapSRC{
	...
	public function drain():void{
		_count = 0;
		_bitmap.dispose();
	}
}
</pre>
<p>타이머 방식도 별거 아니니 쉽게 구현할 수 있습니다.</p>
<pre>
class BitmapSRC{
	...
	public function release( $e:Event = null ):void{

		--count;

		if( $e ){
			...
		}

		if( count === 0 ){ //count가 0이 되면

			//30초 후에 drain할지를 판단한다.
			setTimeout( isDrain, 30000 );

		}
	}

	public function isDrain():void{

		if( count === 0 ){ //30초가 지났는데도 여전히 count가 0이면 진짜로 drain하자!
			drain();
		}

	}
}
</pre>
<h4>결론</h4>
<p>견고한 이미지 자원 관리기는 이제 대용량 컨텐츠를 계속 올렸다 내렸다 하는 플래시 앱에게 필수적일 뿐만 아니라 반복적인 작업입니다.<br />
한번 쯤은 매우 신경써서 구현을 하셔야 한다고 생각합니다.<br />
이 포스트의 내용은 매우 기초적이므로 힌트를 얻어서 멋진 통합 관리자를 만드셨다면 꼭 댓글로 같이 공유해주시면 감사하겠습니다(그러면서 막상 제건 공개안하고 있다..ㅎㅎ)</p>
<h4>과제</h4>
<p>DisplayObject가 아닌 객체가 bitmapData를 가져가는 경우에도 autoRelease를 걸 수 있게 하려면 단순히 그 부분을 if로 분기해서는 다양한 상황에 적응할 수 없습니다. 어찌할까요?</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/7UZcMWRsWQU" height="1" width="1"/>]]></content:encoded>
         <category>2 픽셀데이터</category>
      <feedburner:origLink>http://www.diebuster.com/flash/181</feedburner:origLink></item>
      <item>
         <title>Non blocking loop</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/hbzDwWXDMsM/180</link>
         <description>Blocking 제어형 언어는 명령을 메모리에 적재하고 순차적으로 실행하기 때문에 사실 상 언제나 cpu를 blocking하고 있습니다. 일단 blocking이 뭔지 자세히 설명하자면 한 마디로 컴터가 그걸 실행하는 동안 먹통이 되는 상태를 말합니다. 비슷한 말로는 동기화(sync) 로직이라고도 합니다. 하지만 현대의 OS들은 시분할 방식으로 cpu 제어권을 강제 탈환할 수 있기 때문에 멀티태스킹환경에서는 blocking제어명령을 보내도 빠져나올 수 있습니다. 따라서 많은 [...]</description>
         <guid isPermaLink="false" />
         <pubDate>Tue, 08 Feb 2011 10:12:36 +0000</pubDate>
         <content:encoded><![CDATA[<h4>Blocking</h4>
<p>제어형 언어는 명령을 메모리에 적재하고 순차적으로 실행하기 때문에 사실 상 언제나 cpu를 blocking하고 있습니다.</p>
<p>일단 blocking이 뭔지 자세히 설명하자면 한 마디로 컴터가 그걸 실행하는 동안 먹통이 되는 상태를 말합니다. 비슷한 말로는 동기화(sync) 로직이라고도 합니다.</p>
<p>하지만 현대의 OS들은 시분할 방식으로 cpu 제어권을 강제 탈환할 수 있기 때문에 멀티태스킹환경에서는 blocking제어명령을 보내도 빠져나올 수 있습니다. 따라서 많은 프로그래밍기법에서 thread를 활용하여 blocking명령을 다수 처리하거나 관리하는 기법을 사용합니다.</p>
<p>싱글쓰레드 기반으로 구성된 avm2의 경우 강제적인 시분할 타이밍을 만들어뒀는데 그게 바로 enterFrame으로 대표되는 frame시스템입니다. frame은 마치 쓰레드처럼 주기적으로 반복되는 실행타이밍인데 os가 제어권을 갖고 있지 않고 avm2가 제어권을 갖고 있기 때문에 한계가 명확합니다.</p>
<p>즉 한 프레임에서 긴 시간을 점유하는 blocking명령을 내리면 다음 프레임으로 강제로 넘길 수 없고 blocking이 풀릴 때까지 기다려야 한다는 거죠.</p>
<p>따라서 avm2의 흐름대로 프로그래밍 효과를 최대한 내고 싶다면 한 프레임이 실행되는 주기에 최대한 blocking 시간을 짧게 만들 필요가 있습니다.</p>
<p><span id="more-180"></span></p>
<p>어려운 용어는 이쯤하고 실제 blocking코드를 간단히 보죠.</p>
<pre>
for( i = 0 ; i &amp;lt; 999999 ; ++i ){
	Math.random();
}
</pre>
<p>컴터 성능에 따라 다소간 차이는 있겠지만 이거 엄청나게 오랜 시간동안 컴터를 먹통으로 만듭니다.</p>
<p>이러한 명령이 실행되면 실행이 완료될 때까지 다음 프레임으로 넘어가지 못합니다. 플래시는 화면업데이트나 이벤트처리, 다른 로직의 처리 등을 전부 프레임주기로 갱신하기 때문에 다음 프레임으로 넘어가지 못하면 플래시 그 자체가 먹통이 됩니다.</p>
<p>게다가 script실행 환경 상 타임아웃제한이 있습니다. 위의 코드를 실행하여 30초가 넘어가면 더 이상 실행되지 못하고 다운됩니다. 따라서 blocking을 분산하는 기술은 대규모 프로그래밍의 필수적인 요소입니다.</p>
<p>제어형 언어에서 blocking을 일으키는 경우는 다양하게 있지만 이번 포스트에서는 loop만 다루도록 하겠습니다.</p>
<h4>enterFrame</h4>
<p>일단 위의 blocking로직을 non blocking으로 만들려면 잘게 쪼개 enterFrame에 태워야합니다. enterFrame을 사용하려면 최소한의 displayObject가 필요합니다. 가벼운 객체인 shape를 이용해 enterFrame을 준비하겠습니다.</p>
<pre>
var looper:Shape = new Shape;
</pre>
<p>다음은 전역 카운터가 필요합니다. 위의 for에서 999999에 해당되는 거라 할 수 있죠.</p>
<pre>
var counter:int;
</pre>
<p>또한 한 프레임에서 루프를 돌 제한도 알아야합니다. 즉 999999를 한프레임에 얼마나 쪼개서 돌릴 것인가라는거죠. 예를들어 300번씩만 돌린다면 999999/300 = 3334 프레임으로 돌아야 전체 루프가 완성될 것입니다. 초당 60프레임으로 돌린다면 프레임당 딜레이가 없다고 가정할 때 56초가 걸리게 됩니다.</p>
<pre>
var frameLimit:int;
</pre>
<p>다음은 루프의 몸체에 들어갈 함수와 그 함수에 전달한 인자입니다만, 보통 루프몸체의 로직은 루프 카운터를 활용하는 경우가 대부분 이므로 counter도 알 수 있게 해줘야 합니다.</p>
<pre>
var runner:Function;
var param:Array;
</pre>
<p>이제 조각이 다 모였으니 간단한 클래스로 일반화 시킬 수 있습니다.</p>
<pre>
class nonBlockingLoop{

	var looper:Shape = new Shape;

	public function nonBlockingLoop(){}

	public function loop( $counter:int, $limit:int, $runner:Function, ...$param ):void{
		var counter:int;
		looper.addEventListener( Event.ENTER_FRAME, function( $e:Event ):void{
			var i:int;
			while( i++ &amp;lt; $limit ){
				if( counter &amp;lt; $counter ){
					//$param.unshift( counter ); 필요하면 counter도 넘...
					if( $param.length ){ //rest인자는 null인 경우가 없음
						$runner.apply( null, $param );
					}else{
						$runner();
					}
					++counter;
				}else{
					looper.removeEventListener( $e.type, arguments.callee );
				}
			}
		});
	}
}
</pre>
<p>counter를 클로저로 선언했기 때문에 loop라는 함수는 동시에 몇 번이라도 불러도 잘 작동합니다.</p>
<pre>
var looper:nonBlockingLoop = new nonBlockingLoop;

looper.loop( 999999, 300, Math.random );
looper.loop( 999999, 300, getDefinition, 'flash.display.Sprite' );

function test( $val1:String, $val2:int ):void{
	trace( $val1, $val2 );
}
looper.loop( 999, 20, test, '안녕', 37 );
</pre>
<h4>결론</h4>
<p>xml파싱을 비롯하여 무거운 blocking로직은 반드시 non blocking로직으로 고쳐써야 프로그램의 다운을 막을 수 있습니다.</p>
<p>또한 non blocking loop는 화면의 갱신과 다른 이벤트의 진행을 동시에 시켜주기 때문에 유저 입장에서 훨씬 좋은 응답성을 느끼게 되고 결과적으로 더 나은 이용 경험을 하게 됩니다.</p>
<p>최근 sng등에서 더욱 하드하게 플래시를 사용하는 이상 점점 더 필수적이 되어간다 할 수 있죠.</p>
<h4>과제</h4>
<ol>
<li>non blocking loop가 완료될 때 완료이벤트를 수신할 수 있도록 개선하시오.</li>
<li>아예 Shape를 상속하도록 개선하시오.</li>
<li>일반화시켜 클래스로 정리하는 포스팅을 한 건 처음이지만 non blocking에 대해서는 이미 두어 개의 포스트가 블로그 내에 존재하니 찾아보세요.</li>
</ol><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/hbzDwWXDMsM" height="1" width="1"/>]]></content:encoded>
         <category>3 흐름제어</category>
      <feedburner:origLink>http://www.diebuster.com/flash/180</feedburner:origLink></item>
      <item>
         <title>2011年 Coding Rule 1.0</title>
         <link>http://feedproxy.google.com/~r/DiebusterRss/~3/EiHchPq9YP8/179</link>
         <description>Class project package : root로 부터 시작한다. lib package : BS11의 하위로 시작한다. ? BS11.display, BS11.media class : BS 로 시작한다. ? BStest, BSrole static을 전면 금지하고, 유일한 싱글톤 인스턴스의 이름은 언제나 SELF &amp;#8211; BSdisplay.SELF.setData(); 추상 class : BSA 로 시작한다. ? BSAcontainer, BSAgraphics 인자 class를 사용하지 않는다. 인터페이스를 사용하지 않는다. Member [Embed : 금지 [...]</description>
         <guid isPermaLink="false" />
         <pubDate>Wed, 12 Jan 2011 12:50:13 +0000</pubDate>
         <content:encoded><![CDATA[<h4>Class</h4>
<ul>
<li>project package : root로 부터 시작한다.</li>
<li>lib package : BS11의 하위로 시작한다. ? BS11.display, BS11.media</li>
<li>class : BS 로 시작한다. ? BStest, BSrole</li>
<li>static을 전면 금지하고, 유일한 싱글톤 인스턴스의 이름은 언제나 SELF &#8211; BSdisplay.SELF.setData();</li>
<li>추상 class : BSA 로 시작한다. ? BSAcontainer, BSAgraphics</li>
<li>인자 class를 사용하지 않는다.</li>
<li>인터페이스를 사용하지 않는다.</li>
</ul>
<p><span id="more-179"></span></p>
<h4>Member</h4>
<ul>
<li>[Embed : 금지</li>
<li>public var : 금지</li>
<li>private var : _로 시작한다. ? private var _count:int;</li>
<li>override 되는 function : _로 시작한다 ? override private function _init():void{}</li>
<li>해당 함수가 이용하는 부가함수는 _가 끝에 붙는다. - function test() -&gt; function test_()</li>
<li>부가함수가 여러 개일 경우 명시적으로 이름을 붙일 수 있다. - function test_module1(), function test_module2()</li>
<li>인자함수는 $로 시작한다. - function $position( $x:int, $y:int )</li>
<li>추가되는 함수는 add로 시작한다. - addChild(</li>
<li>삭제되는 함수는 Remove로 끝난다. - childRemove(</li>
<li>획득되는 함수는 Get으로 끝난다. - childGet(</li>
<li>설정되는 함수는 Set으로 끝난다. - childSet(</li>
<li>사본을 얻는 함수는 Copy로 끝난다. - childCopy(</li>
<li>초기화 함수는 Init로 끝난다. - childInit(</li>
<li>자신의 초기화 함수는 init다. - function init(</li>
</ul>
<h4>Arguments</h4>
<ul>
<li>Argument : $로 시작한다. ? function test( $a:int, $b:int );</li>
<li>인자가 Function인 경우 : $인자형인자형_반환형 으로 이름 짓는다. ? function listener( $intString_Number:Function )</li>
<li>void인 경우 반환형을 생략할 수 있다. ? function listener( $intString:Function )</li>
<li>인자가 형식있는 Array인 경우 : $형형 형태로 이름 짓는다. ? function setData( $intintString:Array )</li>
<li>인자가 형식있는 Object인 경우 : $키키 형태로 이름 짓는다. ? function setData( $idNameRegdate:Object )</li>
<li>인자가 형식있는 Param인 경우 : $키키 또는 $형형을 이용할 수 있다 - function setData( ...$intString ), function setData( ...$idName )</li>
<li>모든 인자는 기본으로 불변하고 사본을 이용한다.</li>
<li>인자로 받은 BitmapData는 반드시 dispose()시킨다.</li>
<li>이벤트 리스너 인자가 null값을 기본으로 하면 다른 곳에서도 사용된다는 의미가 된다. - function clearScreen( $e:MouseEvent = null ) &lt;- 마우스이벤트 외에도 사용됨</li>
<li>포괄적 인자의 이름은 언제나 $param</li>
<li>식별자 계열의 인자의 이름은 언제나 $key</li>
<li>단순 값인 인자의 이름은 언제나 $val</li>
</ul>
<h4>Local Variables</h4>
<ul>
<li>결과값을 유도하는 지역변수명은 언제나 result</li>
<li>루프인자는 i, j, k, l, m ,n 까지 사용하며 그 이상의 루프인자는 허용하지 않는다 - 로직으로 분개</li>
<li>이터레이션용 인자는 언제나 key - for each( key in data )</li>
<li>key는 언제나 key:*로 선언함</li>
<li>key가 다중인 경우는 key1, key2...순으로 전개함 - for( key1 in data1 )for( key2 in data2 )</li>
<li>임시변수의 이름은 언제나 temp</li>
<li>temp가 여러 개인 경우는 실제 필요한 이름으로 대치</li>
<li>인자 덮어쓰기 또는 재활용을 금지함. - function test( $val ):void{ $val +=1; .... &lt;- 인자를 가공하거나 재활용하는 것을 금지</li>
</ul>
<h4>Pooling</h4>
<ul>
<li>pool에서 인자를 가져올 때는 언제나 pull 메서드를 통해 가져옴 - CbitmapPool.SELF.pull();</li>
<li>pool이 auto가 아니라 수동으로 반납하는 경우는 언제나 collect로 반납함 - CbitmapPool.SELF.collect();</li>
<li>pull한 객체를 초기화시키는 과정은 호스트가 갖고 있지 않고 인자를 넘겨 pull이 처리하는 게 기본임 - CbitmapPool.SELF.pull( initData );</li>
<li>pool을 구현한 경우 해당 인스턴스는 collect메서드를 구현하고 있어야 함.? - CbitmapPool.SELF.collect( instance1 ); -&gt; collect내부에서 instance1.collect() 를 호출하여 자원을 스스로에게 정리시킴</li>
<li>pull우선 pooling을 기본으로 사용함</li>
</ul>
<h4>Basic</h4>
<ul>
<li>function get, set을 기본적으로 금지한다.</li>
<li>문자열은 기본적으로 작은 따옴표로 묶는다.</li>
<li>클래스는 기본적으로 final이다.</li>
<li>클래스는 기본적으로 internal 이다.</li>
<li>메서드는 기본적으로 private, internal, public 순으로 권한을 풀어준다.</li>
<li>메서드가 private가 아닌 경우 반드시 final을 기본으로 선언한다.</li>
<li>this. 등의 강제적인 컨텍스트 할당을 금지한다.</li>
<li>외부라이브러리에 대해 래핑 없이 쓰는 것을 금지한다. - tweenMax.to( &lt;- 금지 -&gt; BStween.to(</li>
</ul>
<h4>Expression</h4>
<ul>
<li>내용있는 괄호는 반드시 공백을 둔다. ? ( 3 )</li>
<li>내용없는 괄호는 공백을 두지 않는다. ? test()</li>
<li>*와 /는 공백을 두지 않는다 ? 3*4,? 5/2</li>
<li>그 외의 모든 연산자는 공백을 둔다. ? 3 + 2, 5 + 2</li>
<li>괄호 및 위의 모든 규칙을 혼용한다. ? 3 + 2*3 + ( 1+ 3 )*5 &gt; 5</li>
<li>컴마는 뒤에 오는 요소가 공백을 둔다. ? 3, 5, 7</li>
<li>대괄호는 공백을 두지 않는다. ? [3, 4]</li>
<li>시작 중괄호는 옆에 붙인다. ? if( test &gt; 3 ){</li>
<li>중괄호 생략을 금지한다. ? if( test &gt; 3 ) a = 3; 금지</li>
<li>?:의 삼항연산자를 금지한다. ? return a ? a : 3; 금지</li>
<li><a rel="nofollow" target="_blank" href="mailto:&#x002018;@&#x002019;">‘@’</a>는 플랫폼에 예약되는 특수한 문자임</li>
<li>부정식을 금지함 &#8211; if( !a ) -&gt; if( a ){}else{</li>
<li>성능부분에는 bool식을 음수평가로 대체한다. &#8211; if( a ) -&gt; if( a&lt;0 )</li>
<li>성능 상의 이유로 &#038;&#038;를 다중 if로 사용하는 경우 이어쓰기를 허용한다. ? if( test )if( check )if( isObject ){</li>
<li>루프는 언제나 (? j = container.length ; i &lt; j ; ++i ) 를 기반으로 사용한다.</li>
<li>비교연산자는 임의평가식, 항등비교, 일반비교 순으로 사용한다.</li>
<li>형비교는 toString, is, in, typeof 순으로 사용한다.</li>
</ul>
<p>*TAF는 별도 규격들이 있음</p><img src="http://feeds.feedburner.com/~r/DiebusterRss/~4/EiHchPq9YP8" height="1" width="1"/>]]></content:encoded>
         <category>2 개발원칙</category>
      <feedburner:origLink>http://www.diebuster.com/flash/179</feedburner:origLink></item>
   </channel>
</rss><!-- fe1.yql.bf1.yahoo.com compressed/chunked Fri Feb 24 09:38:18 UTC 2012 -->

