2009년 봄, 일본에서 ActionScript 개발자들간에 재미있는 실험이 있었다. 그것은 "Flash속도를 극대화하기" 실험중 하나로 수만개의 입자를 가지고 가상의 유체 시뮬레이션을 보여주는 예제를 만드는 것이였다.

수만개의 입자를 이용한 유체 시뮬레이션 실행


위 화면은 최초실험대상이 된 1만개 입자 유체 시뮬레이션 코드의 실행화면이다.

아래 소스는 위에서 소개된 소스를 10만개 입자로 수정하고 최대 frameRate를 110으로 조정한 것이다. 또한 마우스 클릭으로 초기화 하는 대신 500ms단위로 유체의 이동패턴과 전체색이 조금씩 변하도록 수정했다.

package {
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	import flash.utils.*;
	
	import net.hires.debug.Stats;
	
	[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="110")];
	/**
	 * BitmapData를 이용한 파티클 렌더링 속도 테스트 
	 * @see http://clockmaker.jp/blog/2009/04/particle/
	 */ 
	public class bitmap_liquid100000 extends Sprite {
		
		private const nums:uint=100000;
		private var bmpDat:BitmapData;
		private var vectorDat:BitmapData;
		private var randomSeed:uint;
		private var bmp:Bitmap;
		private var vectorList:Array;
		private var rect:Rectangle;
		private var cTra:ColorTransform;
		private var vR:Number;
		private var vG:Number;		
		private var timer:Timer;
		
		public function bitmap_liquid100000() {
			initialize();
		}
		
		private function initialize():void {
			//stage 관련의 설정
			stage.align=StageAlign.TOP_LEFT;
			stage.scaleMode=StageScaleMode.NO_SCALE;
			stage.frameRate=110;
			
			//파티클이 렌더링 되는 메인 Bitmap. 
			bmpDat=new BitmapData(465, 465, false, 0x000000);
			bmp=new Bitmap(bmpDat);
			addChild(bmp);
			
			//파티클의 가속도를 계산하기 위한 도움 BitmapData로서 perlinNoise가 적용된다. 
			vectorDat=new BitmapData(465, 465, false, 0x000000);
			randomSeed=Math.floor(Math.random() * 0xFFFF);
			vectorDat.perlinNoise(230, 230, 4, randomSeed, false, true, 1 | 2 | 0 | 0);
			//addChild(new Bitmap(vectorDat)); //만약 이 perlinNoise가 적용된 Bitmap을 보고 싶다면 주석을 풀자 
			
			//화면크기 
			rect=new Rectangle(0, 0, 465, 465);
			
			//파티클 궤적을 그리기 위함 
			cTra=new ColorTransform(.8, .8, .9, 1.0);
			vR = 0;
			vG = 0;
			
			//파티클을 넣기 위한 List
			vectorList=new Array();
			for (var i:uint=0; i < nums; i++) {
				//파티클 위치
				var px:Number=Math.random() * 465;
				var py:Number=Math.random() * 465;
				var pv:Point=new Point(px, py);
				//파티클 가속도
				var av:Point=new Point(0, 0);
				//파티클 속도 
				var vv:Point=new Point(0, 0);
				//파티클 위치,가속도,속도 정보를 List에 저장 
				var hoge:VectorDat=new VectorDat(av, vv, pv);
				vectorList.push(hoge);
			}
			
			//지속적인 파티클 렌더링을 위한 loop 함수 호출 
			addEventListener(Event.ENTER_FRAME, loop);
			
			//500ms마다 
			timer = new Timer(500, 0);
			timer.addEventListener(TimerEvent.TIMER, resetFunc);
			timer.start();
			
			//통계 
			addChild(new Stats);
		}
		
		private function loop(e:Event):void {
			//렌더링용 BitmapData를 colorTransform로 어둡게 하여 기존에 그려진 파티클의 궤적을 보이도록 함 
			bmpDat.colorTransform(rect, cTra);
			
			//파티클의 위치를 재계산하여 렌더링한다.
			var list:Array=vectorList;
			var len:uint=list.length;
			for (var i:uint=0; i < len; i++) {
				var dots:VectorDat=list[i];
				var col:Number=vectorDat.getPixel(dots.pv.x, dots.pv.y);
				var r:uint=col >> 16 & 0xff;
				var g:uint=col >> 8 & 0xff;
				dots.av.x+=(r - 128) * .0005; //적색을 x축 가속도로 사용
				dots.av.y+=(g - 128) * .0005; //녹색을 y축 가속도로 사용
				dots.vv.x+=dots.av.x;
				dots.vv.y+=dots.av.y;
				dots.pv.x+=dots.vv.x;
				dots.pv.y+=dots.vv.y;
				
				var _posX:Number=dots.pv.x;
				var _posY:Number=dots.pv.y;
				
				dots.av.x*=.96;
				dots.av.y*=.96;
				dots.vv.x*=.92;
				dots.vv.y*=.92;
				
				//stage 밖으로 이동했을 경우 처리. 3항 연산자 처리함 
				(_posX > 465) ? dots.pv.x=0 : (_posX < 0) ? dots.pv.x=465 : 0;
				(_posY > 465) ? dots.pv.y=0 : (_posY < 0) ? dots.pv.y=465 : 0;
				
				//1*1 pixel을 bitmapData에 렌더링 
				bmpDat.fillRect(new Rectangle(dots.pv.x, dots.pv.y, 1, 1), 0xFFFFFF);
			}
		}
		
		private var seed:Number = Math.floor( Math.random() * 0xFFFF );
		private var offset:Array = [new Point(), new Point()];
		private function resetFunc(e:Event) :void{
			//파티클의 가속도를 계산하기 위한 도움 BitmapData로서 perlinNoise를 변경 
			vectorDat.perlinNoise( 230, 230, 3, seed, false, true, 1|2|0|0, false, offset );
			offset[0].x += 20;
			offset[1].y += 20;
			
			//파티클 궤적을 표시하기 위한 부분을 변경  (조금씩 색변동이 일어난다)
			var dots:VectorDat = vectorList[0];
			vR += .001 * (dots.pv.x-232)/465;
			vG += .001 * (dots.pv.y-232)/465;
			( vR > .01 ) ? vR = .01:
				( vR < -.01 ) ? vR = -.01:0;
			( vG > .01 ) ? vG = .01:
				( vG < -.01 ) ? vG = -.01:0;
			
			cTra.redMultiplier += vR;
			cTra.blueMultiplier += vG;
			( cTra.redMultiplier > .9 ) ? cTra.redMultiplier = .9:
				( cTra.redMultiplier < .5 ) ? cTra.redMultiplier = .5:cTra.redMultiplier;
			( cTra.blueMultiplier > .9 ) ? cTra.blueMultiplier = .9:
				( cTra.blueMultiplier < .5 ) ? cTra.blueMultiplier = .5:cTra.blueMultiplier;         
		}
	}
}

import flash.geom.Point;

class VectorDat {
	public var vv:Point;
	public var av:Point;
	public var pv:Point;
	
	function VectorDat(_av:Point, _vv:Point, _pv:Point) {
		vv=_vv;
		av=_av;
		pv=_pv;
	}
}

처음 이 소스를 본다면 뭔가 굉장히 복잡할 것이라고 생각할지 모른다. 지금껏 이런 것을 구현하기 위해 ActionScript 3.0의 DisplayObject객체 기반으로 입자를 구현하는 것을 먼저 생각한 분이라면 위 소스가 더 어렵게 느껴질 것이다. 참고로 만약 10만개의 입자를 전부 DisplayObject 객체로 구현하면 Flash Player는 제대로 작동도 못하고 중지될 것이다. DisplayObject와 그것을 확장한 화면 표시 객체는 다소 무겁다. Flash Player가 이런 무거운 객체를 10만개나 frameRate가 24 수준으로 그리는 것은 일반 보급 컴퓨터에서는 불가능하다.

위 소스를 잘보면 알겠지만 입자를 표현하기 위해 BitmapData(bmpDat변수 참고)를 이용한다. BitmapData 하나에 모든 입자 정보가 표현되도록 하는 것이 첫번째 아이디어이다. 이렇게 함으로써 10만개 입자 렌더링이 가능해진다.

처음 실행하면 무작위로 지정된 위치에 입자들이 배치되었다가 무작위 궤적을 따라 이동하는 것을 볼 수 있다. 이러한 이동이 뭔가 엄청나게 고난이도 물리엔진  알고리즘이 들어간 것 같지만 실상은 전혀 아니다. 입자의 위치를 이용해 가속도와 속도를 계산하는데 사용된 것은 다름 아닌 BitmapData(vectorDat변수 참고)이다. 이 BitmapData는 실제화면에는 눈에 보이지 않는다.  대신 가속도와 속도를 계산하기 위해 BitmapData에 PerlinNoise를 주어 입자의 위치정보에 해당하는 색정보를 얻어 색의 RGB값중 R값은 x축 가속도값으로 G값은 y축 가속도 값으로 참조하도록 구현되어 있다. PerlinNoise가 적용된 BitmapData는 아래와 같다. 실제로 이 화면을 보고 싶다면 위 코드의  "//addChild(new Bitmap(vectorDat))" 부분을 찾아 주석처리를 삭제하고 실행해 보면 된다.  

필자는 개인적으로 PerlinNoise 대신이 뭔가 물리학적 정보가 들어간다면 훨씬더 실용성 있는 재미난 교육용 자재로 만들 수 있지 않을까 생각했다.

입자의 가속도 계산을 위한 PerlinNoise가 적용된 BitmapData의 모습. 500ms단위로 계속 변한다.


BitmapData에 입자들의 위치를 갱신하는 것까지는 알겠는데... 입자들이 특정한 궤적을 남기도록 하는 효과는 도데체 어떻게 하는 것일가? 따로 궤적을 다루는 Array나 List가 있는 것일까? 아니다. ColorTransform 클래스에 비밀이 숨겨져 있다. loop() 함수를 보면 bmpDat.colorTransform(rect, cTra); 부분이 있다 .rect은 colorTransform을 적용할 범위이고 cTra가 적용할 ColorTransform객체이다. 이 객체에는 cTra.redMultiplier, cTra.greenMultiplier, cTra.blueMultiplier 속성등이 있다. 이 값은 기존 BitmapData에 RGB값을 해당값을 정해진 값으로 곱해주는 역할을 하는데 가령 cTra.redMultiplier가 0.8이면 loop를 돌때마가 Red값이 0.8배로 감소하게 된다. 결국 입자의 흰색(0xffffff)로 BitmapData에 찍히면 cTra.redMultiplier에 의해 계속 어두워지다가 결국 검은색이 된다. 이러한 원리로 궤적이 남게 되는거다.

하지만 위 코드는 문제가 있다. 실제로 실행해보면 필자의 컴퓨터에서는 frameRate가 10도 안나왔다. 최대치 110을 주었음에도 이 정도 밖에 안나왔다는 것에 대해 개발자로서 계산 및 렌더링 최적화에 관심을 자연스럽게 가지게 된다.

일본 개발자들은 Wonderfl의 "Fork"기능을 이용해 서로 소스를 공유하며 위 코드의 문제를 계속 개선해 나갔다. 

아래 압축파일은 필자가 여러 단계를 거쳐서 실험했던 코드를 압축한 것이다.



개선사항 1. BitmapData의 lock()과 unlock() 함수 추가 (bitmap_liquid100000_01.as)
BitmapData가 Bitmap을 통해 화면에 이미 렌더링 자원으로 활용되고 있다면 BitmapData가 수정될 때 마다 Bitmap에도 갱신한다.(즉, addChild(new Bitmap(bitmapData))일때를 의미한다.)  구체적으로 설명하자면 입자가 10만개 이므로 입자의 위치가 바뀔때마다 10만번의 BitmapData를 수정하면 그때마다 Bitmap에도 영향을 준다. 만약 BitmapData을 수정하고 난 다음에 마지막에 Bitmap에 적용될 수 있도록 하면 속도개선에 도움을 줄 것이다. 이것을 가능하게 하는 함수가 BitmapData의 lock(), unlock()함수이다. 위 코드에서 loop()함수에 맨처음과 맨끝부분에 각각 bmpDat.lock(), bmpDat.unlock()을 추가하자. 이 작업으로 전체적으로 2~3 frameRate 개선을 볼 수 있었다. frameRate가 이 실험에서는 크게 개선되지 않았지만 만약 BitmapData에 이보다 더욱 복잡한 수정이 있거나 더 크기가 크면 클수록 그 차이가 더 할 것이다.
private function loop(e:Event):void {
	bmpDat.lock();
	(생략)
	bmpDat.unlock();
}



개선사항 2. fillRect을 setPixel로 변경 (bitmap_liquid100000_02.as)
위 코드에서 가장 잘못된 부분중에 하나가 1px짜리 입자를 렌더링하기 위해 fillRect()을 이용했다는 것이다. 이 함수 대신 setPixel()로 수정한다. 이 작업으로 25~30 frameRate 개선을 했다. 여기까지만 하더라도 상당한 진전이다.

개선사항 3. point 대신 number로 (bitmap_liquid100000_03.as)
위 코드에서 비효율적인 코드부분이 있다. 바로 입자의 정보를 담은 VectorDat부분이다.

import flash.geom.Point;

class VectorDat {
	public var vv:Point; //속도
	public var av:Point; //가속도
	public var pv:Point; //위치 
	
	function VectorDat(_av:Point, _vv:Point, _pv:Point) {
		vv=_vv;
		av=_av;
		pv=_pv;
	}
}

위 클래스는 입자의 위치,속도,가속도 정보를 Point를 이용해 만들었다. 이렇게 하게 되면 10만개나 되는 입자의 위치를 vectorDat.pv.x, vectorDat.pv.y 형태로 접근해야 한다. 이것 대신 vectorDat.px, vectorDat.py로 하면 훨씬 빠른 접근이 가능해질 것이다. 반복되는 로직에 깊은 DOM을 접근을 사용하면 그만큼 느려진다는 것을 항상 염두할 필요가 있다. 다음 코드는 위 클래스를 개선한 것인다.

class VectorDat {
	public var vx:Number = 0; //x축 속도
	public var vy:Number = 0; //y축 속도
	public var ax:Number = 0; //x축 가속도
	public var ay:Number = 0; //y축 가속도
	public var px:Number; //x축 위치 
	public var py:Number; //y축 위치 
	
	function VectorDat( px:Number, py:Number ) {
		this.px = px;
		this.py = py;
	}
}

위 클래스에 맞게 전체 소스를 수정한 뒤 실행하면 frameRate가 10이상 개선되는 것을 확인할 수 있었다. 꽤 큰 진전이다.


개선사항 4. 가속도 계산을 위한 bitmapData 크기 조정 (bitmap_liquid100000_06.as)

BitmapData의 getPixel은 BitmapData의 크기가 크면 클수록 그 효율이 떨어진다. 위 코드에서 입자의 가속도를 계산하기 위해 perlinNoise를 적용한 BitmapData(vectorDat)는 렌더링하기 위한 BitmapData(bmpDat)와 크기가 동일하다. 이 크기를 465x465 대신 28x28로 줄이고 loop()함수내에 col=vectorDat.getPixel(dots.px, dots.py)대신 col=vectorDat.getPixel(dots.px>>4, dots.py>>4)로 수정해서 테스트하면 frameRate가 위 개선사항을 모두 적용한 것보다 약 10이상 증가한다. 



지금까지 개선사항 4가지를 통해 최초 코드의 frameRate를 12에서 60~70까지 끌어올릴 수 있었다. 아래는 실행화면이다.

실행 화면


결과 보러 가기 : http://wonderfl.net/code/2e15897ec742a2e2c09255bcba35c2b20a026356


다른 실험들...

필자는 VectorDat를 담는 List의 형태를 Array에서 Vector로 바꿔서 실험을 해봤다. 이 부분에 있어서는 거의 frameRate변화가 없었다. (bitmap_liquid100000_04.as참고)

또한 List형태를 Linked List로 바꿔봤는데.. 오히려 frameRate가 감소했다.  (bitmap_liquid100000_05.as참고)

마지막으로 BitmapData의 setPixel()보다 setVector()가 더 빠르다기에 그것으로 실험해 보았다. 하지만 이 방법은 위 실험에 쓰기에 적합하지 않았다. 왜냐하면 단순히 setPixel()과 setVector()만 놓고 보았을때 setVector()가 더 빠르지만 setVector()를 사용하기 위해서는 getVector()와  같은 부가적인 코드가 더 들어가게 되었고 그 코드들로 인해 오히려 frameRate가 더 줄어들었다. 그러므로 뭔가 도입할때는 그 상황에 맞게 도입해야한다. (bitmap_liquid100000_07.as참고)


추가사항 



웹눈님께서 이글을 보고 위 프로그램을 만들었는데 mouseX, mouseY 엑세스 비용문제를 해결하지 못해 속도 저하가 일어났었다.

while(pt.next) {
   var dx:Number = pt.x - mouseX;
   var dy:Number = pt.y - mouseY;
   (중간생략)
   pt = pt.next;
}


위처럼 만드셨는데...이렇게 하면 입자(파티클)이 10만개면 10번 mouseX, mouseY를 참조하게 된다. 이 속성을 엑세스 하는 것은 꽤 비싼 자원이 소비되므로 아래처럼 하면 속도개선 된다.

var mx:Number, my:Number;
mx = mouseX;
my = mouseY;
while(pt.next) {
   var dx:Number = pt.x - mx;
   var dy:Number = pt.y - my;
   (중간생략)
   pt = pt.next;
}


테스트 결과, 저렇게 바꾸는 것만으로 FPS(frame per seconds)가 무려 40에서 90까지 개선되었다.
별거 없는데도 엄청난 속도 개선이다! 


정리하며

일본에서 진행된 이 입자 유체 시뮬레이션 실험은 꽤 인기를 얻었으며 Wonderfl 사이트의 favorite와 fork기능을 통해 계속 퍼져나갔다. 필자도 예전부터 봐왔던 실험이였으나 BitmapData 활용을  이미지 에디터 정도의 프로젝트 외에는 거의 사용을 하지 않아서 깊숙히 파고들지 않았다. 

이런 단순한 실험이 일본의 여러 Flash 개발자들 사이에 인기를 끌고 함께 코드를 수정하는 모습을 보면서 그들의 개발분위기가 무척 부러웠다. 한국에도 이런 분위기가 정착되길 바란다. 

필자는 지금도 Wonderfl을 하루에도 수십번 방문한다.


참고글
Wonderfl - build Flash online
빠른 flash 연구회를 wonderfl에서
Flash 10, Massive amounts of 3D particles with Alchemy (source included).
Massive amounts of 3D particles without Alchemy and PixelBender
Flash 10, Massive amounts of 3D Particles (with haXe)
Using BitmapData.setVector for better performance


글쓴이 : 지돌스타(http://blog.jidolstar.com/670
 


Flash Player 10.1을 설치하려고 기존 Flash Player를 전부 uninstaller로 삭제한다음 Flash Player 10.1을 다운로드 받아 설치하려는데 다음과 같은 에러를 발생시키며 설치할 수 없었습니다.

설치하려고 하는 Adobe Flash Player 버전은 최신 버전이 아닙니다.

Windows 7 환경에서 인터넷 익스플로러(IE8)에 Active-x debug(개발자용) 버전을 설치가 되지 않아 하루 종일 이것까지고 씨름했습죠. 

  1. Adobe 이와 관련된 기술노트가 있어서 따라해 봤지만 안되었습니다.(관리자 권한으로 실행해도 마찬가지였습니다.)
  2. 또한 무식하게 Windows까지 새로 깔았지만 안되더군요.

그래서 마지막으로 관련 레지스트리를 삭제했습니다. 됩니다 ㅡㅡ;;;

  1. 시작 > 실행 > regedit 입력
  2. HKEY_LOCAL_MACHINE\SOFTWARE\Macromedia\FlashPlayer\SafeVersions 를 찾아 전부삭제

흑.... 어제부터 이것때문에 완전 생쑈를 했습니다. 시간 아까워.....

글쓴이 : 지돌스타( http://blog.jidolstar.com/668 )

지난 2월 2일 AIR 2.0 beta 2가 배포된데 이어 오늘(한국날짜기준 2010.02.24) Adobe Flash Player 10.1 beta 3가 배포되었습니다. Adobe Labs에 가면 상세한 정보를 보실 수 있습니다. 


릴리즈 노트의 Fixed Issues에 별표(*) 표시된 것이 이번 배포의 수정사항들입니다. 보면 기존에 있었던 Fix된 버그와 개선사항을 확인할 수 있습니다.

주의사항은 이것은 말그대로 beta라는 점입니다. beta는 정식버전이 아니기 때문에 Flash Player 10.1 API를 이용해서 개발하셔도 실제로 서비스하는 것은 안된다는 것을 의미합니다. 테스트 용도로만 설치하셔서 사용하시기 바랍니다.

글쓴이 : 지돌스타(http:/blog.jidolstar.com

애플이 아이패드를 발표하면서 Flash Player 지원을 공식적으로 거부했습니다.
그 이후로 엄청난 논란이 있는 가운데...
Adobe CTO 케빈 린치는 다음 처럼 의견을 제시했습니다.

Adobe 케빈 린치의 '컨텐츠 및 애플리케이션에 대한 오픈 액세스

아무튼 이런 상황에서 아래와 같은 기사도 올라왔네요.
한번 읽어보시고 각자의 의견을 들어보는 것도 좋을 것 같아요. ^^

---------------------------------------------------------------------

[원문]
http://online.wsj.com/article/SB20001424052748703546004575055184080144688.html


[월 스트리트 저널(Wall Street Journal)]


애플(Apple)의 마이크로소프트(Microsoft)화?


2010.02.09 / 홀먼 W. 제킨스 주니어(Holman W. Jenkins, Jr.)


애플은 증오적 라이벌 관계로 인해 제로섬 전략에 집착하는 회사로 전락할 위험에 놓여있습니다.

현재를 언급하는 것이 아니라 애플의 시가총액이 상상할 수 없는 규모에 달하여 마이크로소프트의 시가총액을 뛰어넘는 해의 이야기가 될 수 있습니다. 당연히 축하 인사가 따르겠지만 위로의 말도 함께 따를 것입니다. 제품 개발에만 전념하는 회사의 경우 전략에 집착하는 회사가 될 위험의 소지가 있기 때문입니다. 그리고 여기서 “전략”이란 증오적 라이벌 관계로 인한 제로섬 전략을 의미합니다.

안타깝게도 현재 우리는 신뢰를 찾기 힘든 타락한 세상에 살고 있습니다.

아이패드(iPad)의 예를 들어보겠습니다. 아이패드는 세상에 공개되자마자 “구세주 태블릿”이라는 별명을 얻었습니다. 아이패드는 상상하지 못할 만큼 탁월한 제품이 아닌 단지 애플이 넷북 경쟁에 뛰어들기 위해 출시한 제품으로, 아이팟 터치(iPod Touch)를 확대해 놓은 버전에 불과합니다. 아이패드는 최상의 웹 브라우징 시스템으로 부각될 수 없을 수도 있습니다. 왜냐하면 애플이 웹 상에서 비디오를 전달하는 데 75% 가량 사용되고 있는 플래시(Flash) 지원을 거부했기 때문입니다. 그러나 아이패드(iPad)(‘지불’이라는 영어 PAID의 철자 순서를 바꾸어 만든 말)는 애플의 온라인 서비스를 통해 판매되고 있는 e북, 음악 및 비디오를 사용하기에는 적합한 디바이스로 보입니다. 단도직입적으로 말하자면 아이패드는 마치 아이튠즈(iTunes) 스토어를 후원하기 위해 최적화된 디바이스로 보입니다.


그렇다면 왜 애플은 플래시를 제외시키기로 결정했는지 궁금하지 않을 수 없습니다. 애플과 애플의 후원업체들은 플래시가 짜증나는 웹 광고를 만드는데 사용되는 제품이라는 미학적이고 철학적인 이유를 내세우고 있습니다.


애플이 플래시를 거부하는 이유는 바로 여기에 있습니다. 플래시를 사용하면 아이폰(iPhone) 및 아이패드 사용자는 아이튠즈를 통하지 않고 비디오 및 기타 엔터테인먼트를 사용할 수 있을 것이고 애플 앱 스토어(Apple App Store)에서만 현재 구입할 수 있는 다양한 기능을 무료로 얻을 수 있게 됩니다.


네트 중립성 옹호자들이나 독점 금지법 집행자들이 스티브 잡스(Steve Jobs)를 연행해가는 오류를 범하지 않도록, 한 가지 덧붙이자면 애플은 플래시를 거부할 수 있는 적법한 권리를 가지고 있습니다. 그러나 한 가지 짚고 넘어가야 할 것은 애플은 엄청난 양의 웹 컨텐츠와 사용자를 분리시키려는 전략적 선택을 내세우고 있다는 점입니다. 플래시가 버그를 부른다는 주장 등에 대해 플래시 옹호자의 시점에서 잠시 벗어나 설명해 보겠습니다. 플래시는 다른 비디오 플레이어와의 시장 경쟁에서 우위를 점하고 있으며 10억 명에 달하는 PC 사용자가 정기적인 업데이트를 다운로드하고 있다는 사실은 엄청난 성공이라고 해도 과언이 아닐 것입니다. Hulu.com에서 TV 프로그램을 시청하거나 MLB.com에서 야구 경기를 보거나 Facebook을 통해 친구와 커뮤니케이션할 때에도 플래시가 필요합니다.


현재로선 플래시를 소유하고 있는 어도비는 최소한 플래시 프로그래머가 애플의 앱 스토어를 통해 자신이 개발한 컨텐츠나 애플리케이션을 제공할 수 있도록 몇 가지 툴을 출시하고 있다고 말하고 있습니다. 이것도 애플의 축복이 있어야 가능할 것입니다. 그러나 애플은 미래의 웹 표준은 독점적인 플래시를 대체하게 될 것이라고 주장하고 있습니다. 이것은 지켜봐야 할 일입니다. 플래시는 현재 전세계 95%의 PC에 설치되어 있어 하루 아침에 웹 표준이 바뀔 가능성은 극히 희박합니다. 또한 파이어폭스(Firefox) 같은 브라우저 제작업체 모두가 애플이 말한 새로운 표준과 생각을 함께 하고 있는 것도 아닙니다.


더 크게 우려되는 바는 여기에 있습니다. 애플이 이러한 무모한 목표로 인해 자사의 모바일 디바이스 사용자층을 확대하여 단지 더 많은 사용자가 아이튠즈만 이용하도록 사용자를 가두는 “네트워크 효과”의 매혹적인 유혹에 무릎을 꿇을 수 있다는 점입니다. 애플은 최근까지 제휴 관계를 유지했던 구글(Google)과 전면전에 돌입했습니다.


지난달 말  애플 직원과의 미팅에서 스티브 잡스가  “지금까지 애플은 검색 시장에서 구글과의  경쟁을 피하기 위해 노력했지만 ‘아이폰  타도’ 를 위해 자사의 모바일 디바이스르  출시했다.” 면서 “사악해지지 말자(Don't be evil) " 라는 구글의 모토를 폄하한 발언이 일파 만파 퍼졌습니다.


구글폰으로 인해 아이폰이 없어지지는 않을 것입니다. 시장은 수많은 모바일 디바이스를 수용할 수 있는 여건을 충분히 갖추고 있습니다. 그러나 실제 위협이 되는 것은 수천만 명의 소비자를 앱 스토어인 아이튠즈만 이용할 것을 주입시킬 수 있는 애플의 능력입니다. 구글이 아이패드가 공개되기 며칠 전 자사의 슬레이트 모양의 디바이스 모델을 발표한 것은 의미 있는 행보였습니다. 구글의 모바일 디바이스는 플래시를 지원하고 있습니다. 애플 사용자가 사용할 수 없는 비디오 및 기타 웹 기능을 사용자가 구매하거나 사용할 수 있도록 했습니다.


애플이 아이폰에서 구글을 대체하기 위해 마이크로소프트의 검색 엔진인 빙(Bing)과 거래를 고려하고 있다는 소문이 돌고 있습니다. 또한 애플이 광고 사업에도 뛰어들어 구글의 서비스와 경쟁하기 위해 클라우드 서비스를 확대할 것이라는 소문도 들리고 있습니다. 어디서 많이 들어본 스토리 아닌가요?


네트워크 효과는 권력과 부를 가져오는 방법이 될 수는 있지만 마이크로소프트의 사례에서 볼 수 있듯이 너무 많은 성과는 특권의 지위를 유지하기 위한 방어적이고 망상적 시도로 인해 물거품이 될 수 있습니다. 회사의 최고 심미가이자 완벽주의자가 더 이상 정상적인 의사 결정을 내리지 못하게 되면 과연 애플은 어떤 회사가 될 것인지 많은 전문가들은 의문을 가지고 바라보고 있습니다. 애플이 점점 더 많은 사용자들에게 아이튠즈 앱 스토어만 사용할 수 있는 질이 나쁜 디바이스를 출시하는 회사로 전락되지 않을까 우려되는 바입니다.
 

최근에 AIR 애플리케이션을 개발하면서 publisher ID이 누락되는 문제에 대한 글을 적은 적이 있었다.

Adobe AIR 애플리케이션 배포후 publisher ID 파일이 누락되는 문제

나는 이 문제를 단순히 설정이 틀어진다던가 버그라고만 생각했다. AIR 1.5 라이브 문서를 보면 다음과 같이 명백하게 밝히고 있다.

As of AIR 1.5.3, publisher IDs are deprecated. New applications (originally published with AIR 1.5.3 or later) do not need and should not specify a publisher ID.


AIR 1.5.3 릴리즈 노트를 살펴보면 PublisherID문제를 해결하기 위해 기존 버전의 AIR에서 어떻게 AIR 1.5.3으로 마이그레이션을 할 수 있을까 적어두었다.

Changes in AIR 1.5.3 

정리하자면 이렇다. AIR 1.5.3으로 처음 애플리케이션을 개발하는 사람은 그대로 개발하면 된다. 어짜피 AIR 애플리케이션이 배포되고 그 상태에서 업데이트 하는데는 문제가 없기 때문이다. 하지만 PublisherID가 필요한 경우가 있거나(그런 경우는 없는게 좋다) 기존 버전을 AIR 1.5.3으로 갈아타고 싶을 때는 AIR의 디스크립터 파일에 <publisherID></publisherID>를 삽입하여 컴파일 해줘서 기존버전과의 호환을 유지할 수 있게 된다. 이는 AIR 1.5.3 뿐 아니라 앞으로 배포될 AIR 2.0에도 해당하는 것으로 보인다.

아마도 이렇게 된데에는 중간에 인증서(certificate) 관련 파일이 변경되더라도 애플리케이션 배포에 문제가 없도록 한다는 취지가 있는 것이 아닐까 판단한다. 가령, 자기발급인증서 사용하다가 공인인증서로 바꿔도 배포에 문제가 없게 된 것이다. 그 반대의 경우도 마찬가지이고. 그렇다면 오히려 더 좋은거 아닌가?

이 AIR 애플리케이션이 고유하다는 것을 명시적으로 알려주는 것은 Publisher ID와 Application ID 였는데... 이제부터 그 고유성은 Publisher ID는 선택사항이고 Application ID가 증명해주게 되었다. 이렇게 되면 다른 사람이 제작한 Application ID가 중복되는 경우도 있는데... 그런 경우에는 com.jidolstar.air.myapp 형태로 해주면 어느정도 중복을 방지할 수 있다. 하지만 완벽히 피해갈 수는 없게 되었다.

앞으로 AIR 애플리케이션을 개발할 때 꼭 참고하자.

문제를 발견해주시고 알려주신 leigh님께 감사한다.

참고글
AIR: Migrating Expired Certificates using AIR 1.5.3
Changes in AIR 1.5.3
Packaging an AIR installation file using the AIR Developer Tool (ADT)

글쓴이 : 지돌스타(http://blog.jidolstar.com/655)

근래 스티브 잡스의 Adobe Flash에 대한 자극적인 발언으로 시끄러운 가운데 Adobe CTO인 케린 빈치가 의견을 게시했습니다. 아래는 그 내용의 번역본입니다.


원본글 : http://blogs.adobe.com/conversations/2010/02/open_access_to_content_and_app.html
게시자: Kevin Lynch, CTO

최근 출시되고 있는 우수한 디바이스에 Flash Player가 탑재되어 있지 않다는 사실에 적잖이 놀랐을 것입니다.


본래 Flash는 시장이 형성되지 않았던 약 15년 전에 펜(Pen) 컴퓨팅 태블릿을 위해 고안되었습니다. 초창기에는 낮은 대역폭의 벡터 그래픽을 지원했지만 지난 십여 년간 새로운 기능을 빠르게 추가해 나가면서, 웹의 틈새 시장을 공략했습니다. 현재는 새로운 활용 방안을 찾는 데 노력을 기울이고 있습니다. 일례로 웹상에서의 애니메이션, 스트리밍 오디오, 풍부한 인터랙션, 임의의 폰트, 양자간 오디오/비디오 커뮤니케이션, 로컬 저장소, 혁신적인 비디오 전달 등이 있습니다.
 

HTML 기능이 추가된 Flash는 상당히 높은 채택율을 기록하고 있는 가운데, 상위 웹 사이트의 85% 이상에서 Flash 컨텐츠를 사용하고 있으며, 인터넷이 연결된 컴퓨터의 98% 이상에서 Flash가 실행되고 있습니다. Flash는 웹상의 대부분의 캐주얼 게임, 비디오 및 애니메이션에 사용되고 있으며 Nike, Hulu, BBC, Major League Baseball 등 유명 브랜드에서 Flash를 사용하여 10억 이상에 달하는 전세계 사용자에게 매력적인 경험을 전달하고 있습니다.


Flash의 미래에 있어서 지금이 가장 중요한 시기입니다. 현재 PC 외에도 다양한 디바이스들이 하루가 다르게 출시되고 있으며, 많은 수의 디바이스가 인터넷 검색에 사용될 것입니다. 따라서 컨텐츠 및 애플리케이션 제작자와 사용자는 PC에서 Flash를 통해 얻어질 것으로 기대되는 경험, 즉 원활하고 일관되며 풍부한 경험을 디바이스에도 동일하게 전달하기 위해 많은 과제들을 해결해야 할 것입니다. Flash 엔지니어링 팀은 이를 실현하기 위해 다양한 디바이스에서 Flash Player를 철저히 분석해 왔습니다.


이러한 노력의 결과로 Adobe는 시장 선도적인 제조업체를 대상으로 한 스마트폰용 Flash Player 10.1을 선보이려고 합니다. 이러한 제조업체에는 스마트폰 뿐만 아니라 태블릿, 넷북, 인터넷 TV 등 시장을 형성하고 있는 Google의 Android, RIM의 Blackberry, Nokia, Palm Pre, 기타 업체들이 있습니다. Flash를 통해 고객은 전체 웹을 검색할 수 있으므로 브라우저에서 Flash를 사용하고 있는 이러한 디바이스는 경쟁력을 갖추게 됩니다. 이는 사실상 오픈 스크린 프로젝트(Open Screen Project)를 통해 이루어지고 있으며, Adobe는 50여 이상의 파트너와 협력하면서 다양한 디바이스에서 이를 실현하기 위해 노력하고 있습니다. 예를 들어, 최근 선보인 구글 넥서스원(Nexus One)은 Flash Player 10.1을 통해 탁월한 브라우저 경험을 선사할 것입니다.


그렇다면 Apple 디바이스에서 실행 중인 Flash는 어떨까요? Adobe는 Flash 기반으로 iPhone용 독립 실행형 애플리케이션을 구축할 수 있게 함으로써, Flash 기술은 이러한 디바이스에서의 사용을 넓혀 나가기 시작했습니다. 실제로 이러한 애플리케이션 중 일부는 FickleBlox, Chroma Circuit과 같은 Apple App Store(앱스토어)에서 이미 제공되고 있습니다. 이 동일한 솔루션은 iPad에서도 작동될 것입니다. Adobe는 이러한 디바이스의 브라우저에서 Flash를 지원하기 위한 준비를 마친 상태이며 이제 Apple에서 사용자를 위해 이를 허용하는 것만이 남아 있습니다. 그러나 Apple은 지금까지도 어도비의 이러한 협력 요청을 받아들이지 않고 있습니다.


장기적으로 볼 때, Flash에 대한 요구 사항을 대신하게 될 것으로 HTML이 꼽히고 있는 데, 특히 최근 개발된 HTML 5 버전이 출시되면 그 움직임은 본격화될 것으로 전망하는 사람들이 많아지고 있습니다. 그러나 오늘날은 물론이거니와 앞으로도 한 기술이 다른 한 기술을 대체하게 되지는 않을 것으로 예상됩니다.


Adobe는 HTML의 발전을 지원하고 있습니다. 앞으로 HTML이 진화를 거듭할수록 Adobe 소프트웨어에 더 많은 기능이 추가될 것으로 기대하고 있습니다. HTML이 Flash의 기능을 안정적으로 수행할 수 있다면, Adobe는 많은 시간과 수고를 덜 수 있지만, 사실상 그렇게 될 가능성은 거의 없습니다. 비디오 부문의 경우 현재 웹상에 있는 비디오의 75% 이상에서 Flash가 사용되고 있는 데도 불구하고, 브라우저 간 포맷 통일이 이루어질 수 없으므로 사용자와 컨텐츠 제작자는 비호환성이라는 문제를 안게 되고 결국 HTML 비디오 구현은 어두운 뒤안길에 남겨질 것입니다.


HTML의 진보에도 불구하고 Flash의 생산성과 표현 기능은 웹 커뮤니티에서 가희 독보적이라고 할 수 있습니다. Flash 팀은 지난 십여 년간 불가능하다고 여겼던 경험을 구현해 왔던 것처럼 앞으로도 더욱 혁신에 박차를 가할 것입니다. 1년도 채 안 되는 짧은 시간 동안 대다수의 웹 클라이언트를 업데이트할 수 있었던 Flash는 다양한 브라우저 전반에 걸쳐 HTML이 수행하는 것보다 훨씬 빠른 시간 내에 고객에게 이러한 혁신 기술을 선보일 수 있을 것으로 기대를 모으고 있습니다.


Adobe는 시간, 장소, 매체에 구애 받지 않고 아이디어와 정보를 생성하고 전달할 수 있는 방식을 혁신하고 있으며 디자이너와 개발자가 자신의 독창적인 아이디어를 마음껏 펼칠 수 있는 방법을 고안해 내는 데 전력을 다하고 있습니다. 또한 가장 생산성이 우수한 툴과 컨텐츠 및 애플리케이션을 배포할 수 있는 광범위한 기능을 창의적인 관리 방법과 접목시키는 것 또한 Adobe의 미션이라고 할 수 있습니다. Adobe는 고객이 목표를 달성하고 기술 격차를 극복할 수 있는 기술 혁신을 이뤄내는 데 필요한 모든 기술과 포맷을 지원하고 있습니다. Flash와 HTML이 결합되면 최고의 기술이 탄생하게 될 것입니다. 그렇게 되면 누구나 웹상에서 이 기술을 사용하여 최상의 경험을 제공할 수 있게 될 것입니다.


아이디어와 정보를 활용하는 것은 사용자가 선택한 컨텐츠와 애플리케이션을 보고 서로 인터랙션할 수 있는 개방된 에코시스템과 자유가 존재한다는 것을 의미합니다. 이 오픈 액세스 모델은 가장 효율적인 모델로 그간의 여러 시행착오를 거쳐 그 효과가 입증되었습니다. 이와 반대로 폐쇄 모델에서는 사용자가 개별 컨텐츠와 애플리케이션을 보거나 승인 및 거부할 수 있는 사항을 제조업체에서 결정하려고 했습니다. 웹은 디바이스에 상관없이 컨텐츠와 애플리케이션을 일관되게 액세스할 수 있는 개방된 환경으로 존재해야 한다는 데는 이견이 없을 것입니다.


Adobe는 고객들이 최상의 업무 성과를 달성하고 운영 체제, 브라우저 및 다양한 디바이스 전반에 걸쳐 효과적이고 안정적으로 전세계 모든 사용자에게 다가갈 수 있도록 지속적으로 지원해 나갈 것입니다.

최근에 Flex 4.0 기반으로 Adobe AIR 애플리케이션을 개발하는 프로젝트를 맡았다. 현시점(2010.2.1) Flex 4.0 SDK에 함께 있는 AIR SDK 버전은 한단계 구버전인 1.5.2이기 때문에 가장 최신 버전인 1.5.3을 기존 Flex 4.0 SDK에 덮어씌운 상태에서 개발을 진행했었다. 문제없이 개발할 수 있다.

그런데 애플리케이션 배포시 문제가 발생했다. AIR 애플리케이션을 설치하면 설치 디렉토리 밑에 META-INF/AIR/publisherid 파일이 존재해야 한다. 그런데 이 파일이 없는 것이다. publisherid는 인증서의 고유 ID를 담고 있다. 이 파일이 없는 상태에서 배포, 업데이트 모두 잘되지만 badge에서 이미 설치된 AIR 애플리케이션이 있는지 여부를 판단할 수 없었다. 사실 배포,업데이트가 잘 되기 때문에 이 상태로 배포해도 문제는 없지만 너무 꺼름칙했다. (AIR의 장점중 하나가 쉽게 설치된 AIR 애플리케이션과 Flash의 연동이 큰 장점 아니던가....)

이 문제의 원인을 찾고자 별짓을 다하다가 SDK 문제라는 것에 귀결을 내리게 되었다. 문제는 Flex 4.0 SDK에 AIR 1.5.3 SDK를 덮은것에서 비롯되었다. 기존 Flex 4.0 SDK에서 AIR 1.5.2 기반으로 만들어 배포하면 Publisher ID 파일이 있지만 AIR 1.5.3으로 덮어씌우고 배포하면 이 파일이 없었던 것이다. 개발, 컴파일까지 모두 잘되는데 말이다. ㅎㅎ 

결국 나는 Flex 4.0 기반으로 애플리케이션을 거의 완성한 상태라서 AIR 1.5.2 기반으로 배포할 수 밖에 없게 되었다. 편리하고 빠른 개발을 위해 Flex 4.0를 선택했지만 AIR 버전이 구버전으로 인한 문제점은 정말 예상치 못한 일이었다.

개발하다 보면 별에 별일이 많은데... 정말 이렇게 크리티컬한 상황까지 보게 되니 정말 웃기기 까지 한다.

질문?
Flex 4.0에 AIR 1.5.3을 덮어씌워도 publisher id 파일이 누락되지 않도록 하는 방법은 뭘까요? 혹시 알게되면 댓글이나 트랙백 부탁합니다.

추가 1
Flex 3의 최신버전인 Flex 3.5의 경우에는 AIR 1.5.3 SDK가 함께 있는데... Flex 4는 왜???? ㅡㅡ;;

추가 2
Flex 4.0 SDK의 beta 2 버전은 4.0.0.10485 이다. 이 버전은 AIR 1.5.2 SDK이다. 하지만 최신 Nightly Builder 버전으로 다운로드 받으면 AIR 1.5.3이 기본이다. 그냥 이걸로 개발해야겠다.

추가 3
Adobe AIR 1.5.3 부터는 PublisherID가 기본적으로 제거됩니다. http://blog.jidolstar.com/655

글쓴이 : 지돌스타(http://blog.jidolstar.com/652)




지난 22일에 Adobe Labs에서 Adobe Stratus 2에 대한 소개가 있었습니다.

http://labs.adobe.com/technologies/stratus/

Stratus는 RTMFP(Real Time Message FlowProtocal)이라 불리우는 통신프로토콜을 이용해 Flash Player 10이 설치된 클라이언트 까지 P2P(Peer to Peer)가 가능하게한 기술입니다. TCP가 아닌 UDP기반으로 동작하고요.

이번 Stratus 2는 Adobe Flash Player 10.1 beta, Adobe AIR 2 Beta에서 동작하도록 만들어졌습니다. 재미있게도 이번 버전에서는 애플리케이션 수준에서 멀티케스트와 소스 공급자의 로드를 줄여주는 구조를 지원하게 되었습니다. 맨 위의 그림에서 좌측 그림은 기존 Flash Player끼리 통신하기 위해 서버를 항상 거쳐야만 했었습니다. 서버입장에서는 완전 부담이죠. 그런데 중간 그림에서 볼 수 있듯이 Stratus가 나오면서 서버와는 한번의 접속으로 하고 Flash Player끼리 통신이 되었습니다. 이것도 소스 공급자인 Flash Player 입장에서는 로드가 심할 수 있습니다. 이를 Flash Player 단위에서 분산시키도록 한 것이 이번 배포의 핵심인 것 같네요.

물론 Stratus 2는 아직 베타버전인 Flash Player 10.1과 AIR 2.0에서만 동작하므로 바로 실무에 사용할 수는 없습니다. 그러나 조만간 이 기술을 사용할 수 있게 되겠죠.

Stratus 1.0에 대한 많은 실험이 국내에도 있었습니다. 저도 조금 테스트 해봤었고요.
http://blog.jidolstar.com/498 

다른 분들의 글들입니다.
플래시 P2P RTMFP에 대해(예제 파일 첨부)
[Flex] Stratus를 이용한 P2P방식의 Flash간에 1:1 다이다이 오목게임-_-
Flash로 p2p를 만들어보자 - Stratus 라이브러리
Flash로 채팅을 구현해보자.


하지만 방화벽, 공유기를 통해 접근 문제가 해결되었는지는 미지수네요.(테스트 안해봤음)
이 문제만 해결되면 정말 멋진 애플리케이션이 많이 나올거라 생각됩니다. ^^

글쓴이: 지돌스타(http://blog.jidolstar.com/651)






제가 ACP(Adobe Community Professional)가 되었습니다.
이로써 Adobe 공인 전문가 그룹에 등록 되었습니다.

http://lizfrederick.blogspot.com/2010/01/new-acps-for-2010.html

국적과 상관없이 약 300명 정도가 등록되었습니다. 분류로는 Acrobat, AfterEffect, AIR, Authorware, Captivate, ColdFusion, Creative Suite, Dreamweaver, Fireworks, Flash Media Server, Flash Mobile, Flash Platform, Flash Platform(RIA), Flash Professional, Flex, FrameMaker, Illustrator, InDesign, InDesign Server, Lightroom, LiveCycle ES, Photoshop, PhotoShop Elements, Premiere Pro, Production Premium, RoboHelp, Spry, Visual Communicator등이 있고 저는 Flash Platform(RIA) 분야로 등록되었네요.

저는 모르고 있었는데 우야꼬가 전화로 축하해주더군요. ^^;
메일을 보니까 한국 어도비로부터 축하 메일이 왔더군요.
저 외에 한국에서 ACP로 선정된 분들입니다.

강성규(땡굴이)
이정웅(블루메탈)
이준하(열이아빠)
배준균

ACP 후보 추천시 저에 대해서 작성된 내용입니다. (물론 영어로 번역되었겠죠...)

Flash Platform 기술에 대해 큰 관심을 가지고 있으며 그 기술에 대해 한국어 블로그(http://blog.jidolstar.com)를 운영하고 있다. 한국 어도비 RIA 홈페이지에 분기별로 기술문서를 기고하고 있다. 또한 ACC로써 Flash Platform 기술 전도사로 활동하고 있다(http://adoberia.co.kr/acc/acc.html). 한국어 Flex문서가 없다. 그래서 그는 flexdocs.kr 이라는 사이트를 구축했다. 그는 회사에서 Flash 개발팀장으로 근무하고 있으며 한국 SNS인 Starpl에 Flash 기술을 적용하는데 일조했다(http://starpl.com).

여러가지로 부족한데 선정해준 Adobe사에 감사하며 이름에 걸맞게 열심히 활동하고 실력도 쌓아가도록 노력하겠습니다.

글쓴이 : 지돌스타(http://blog.jidolstar.com)


"Flash로 못할 것이 없다."라는 말을 들어보셨나요? 이번에 소개하는 것은 beautifl.net에 올라온 Flash 코드중 개인적으로 자극을 받은 것만 선정해본 것들입니다. wonderfl.net에 올라온 것들이기 때문에 코드도 공개되어 있어 언제든지 분석도 할 수 있습니다. Flash의 세계를 만끽해보세요.

보러가기 : http://opencast.naver.com/FL188/16

글쓴이 : 지돌스타(http://blog.jidolstar.com/646)

LCDS, BlazeDS, ZendAMF등을 이용해 AMF(ActionScript Message Format)으로 데이터를 주고받는 형태는 이미 많은 예제들과 문서들이 있다. AMF는 데이터 통신을 위한 일종의 약속된 규약이고 이 데이터를 주고 받고 하는 과정에서 서로의 언어에 맞게 직렬화(Serialization)하는 것은 각 언어에서 지원해주는 라이브러리를 사용하면 된다. ActionScript 3.0은 기본 API에서 지원해준다. 자바의 경우는 BlazeDS나 LCDS를 사용하면 된다. PHP의 경우에는 ZendAMF를 사용하면 된다. 이들을 이용하면 가령, 자바와 java.lang.Interger는 ActionScript의 int나 uint로... java.lang.Double은 ActionScript의 Number형과 직렬화된다. 이는 일종의 기본적으로 지원되는 직렬화이다.

다음은 BlazeDS에서 기본적으로 지원되는 직렬화이다.
Serializing between ActionScript and Java

하지만 이런 기본 직렬화과정을 사용하지 않고 직렬화 자체를 커스터마이징(customizing)할 수 있다. 가령 클라이언트(예,Flash 애플리케이션)에서는 아이디, 이름, 속성, 가격의 정보가 중요하지만 서버(예,자바)에서는 재고(inventory)가 중요한 경우가 있다. 이런 경우에는 Flex와 Java쪽의 직렬화하는 클래스를 다음과 같이 디자인 할 수 있겠다.

// Product.as
package samples.externalizable {

import flash.utils.IExternalizable;
import flash.utils.IDataInput;
import flash.utils.IDataOutput;

[RemoteClass(alias="samples.externalizable.Product")]
public class Product implements IExternalizable {
    public function Product(name:String=null) {
        this.name = name;
    }

    public var id:int;
    public var name:String;
    public var properties:Object;
    public var price:Number;

    public function readExternal(input:IDataInput):void {
        name = input.readObject() as String;
        properties = input.readObject();
        price = input.readFloat();
    }

    public function writeExternal(output:IDataOutput):void {
        output.writeObject(name);
        output.writeObject(properties);
        output.writeFloat(price);
    }
}
}


// Product.java
package samples.externalizable;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Map;

/**
* This Externalizable class requires that clients sending and 
* receiving instances of this type adhere to the data format
* required for serialization.
*/
public class Product implements Externalizable {
    private String inventoryId;
    public String name;
    public Map properties;
    public float price;

    public Product()
    {
    }

        /**
        * Local identity used to track third party inventory. This property is
        * not sent to the client because it is server-specific.
        * The identity must start with an 'X'.
        */
        public String getInventoryId() {
            return inventoryId;
        }

        public void setInventoryId(String inventoryId) {
            if (inventoryId != null && inventoryId.startsWith("X"))
            {
                this.inventoryId = inventoryId;
            }
            else
            {
                throw new IllegalArgumentException("3rd party product
                inventory identities must start with 'X'");
            }
        }

        /**
         * Deserializes the client state of an instance of ThirdPartyProxy
         * by reading in String for the name, a Map of properties
         * for the description, and 
         * a floating point integer (single precision) for the price. 
         */
        public void readExternal(ObjectInput in) throws IOException,
            ClassNotFoundException {
            // Read in the server properties from the client representation.
            name = (String)in.readObject();
            properties = (Map)in.readObject();
            price = in.readFloat();
            setInventoryId(lookupInventoryId(name, price));
        }
        /**
         * Serializes the server state of an instance of ThirdPartyProxy
         * by sending a String for the name, a Map of properties
         * String for the description, and a floating point
         * integer (single precision) for the price. Notice that the inventory 
         * identifier is not sent to external clients.
         */
        public void writeExternal(ObjectOutput out) throws IOException {
            // Write out the client properties from the server representation
            out.writeObject(name);
            out.writeObject(properties);
            out.writeFloat(price);
        }
        
        private static String lookupInventoryId(String name, float price) {
            String inventoryId = "X" + name + Math.rint(price);
            return inventoryId;
        }
}

위 코드는 ActionScript의 flash.utils.IExternalizable 인터페이스와 Java의 java.io.Externalizable 인터페이스를 이용해 기본직렬화를 무시하고 이들 인터페이스에 정의된 readExternal와 writeExternal 메소드를 호출하여 직렬화 자체를 커스터마이징 할 수 있다는 것을 의미한다. Externalizable 인터페이스를 구현한 클래스에 정의된 메소드가 기본 직렬화보다 우선순위가 높다는 것을 기억하면 되겠다.

Flex의 ArrayCollection을 다시 한번 보기 바란다. 이 클래스는 flash.utils.IExternalizable를 구현했다.
mx.collections.ArrayCollection

꼭 이런 경우만은 아니다. 쓸데없는 데이터의 크기를 줄이기 위한 방법도 해당한다. 예를들어 ActionScript 코드를 보면 다음과 같다.


class Example implements IExternalizable {
  
      public var one:Boolean;
      public var two:Boolean;
      public var three:Boolean;
      public var four:Boolean;
      public var five:Boolean;
      public var six:Boolean;
      public var seven:Boolean;
      public var eight:Boolean;
       public function writeExternal(output:IDataOutput) {
           var flag:int = 0;
           if (one) flag |= 1;
          if (two) flag |= 2;
          if (three) flag |= 4;
          if (four) flag |= 8;
          if (five) flag |= 16;
          if (six) flag |= 32;
          if (seven) flag |= 64;
          if (eight) flag |= 128;
           output.writeByte(flag);
      }
       public function readExternal(input:IDataInput) {
           var flag:int = input.readByte();
           one = (flag & 1) != 0;
          two = (flag & 2) != 0;
          three = (flag & 4) != 0;
          four = (flag & 8) != 0;
          five = (flag & 16) != 0;
          six = (flag & 32) != 0;
          seven = (flag & 64) != 0;
          eight = (flag & 128) != 0;
      }
 }

데이터 통신을 위해 쓸데없이 Boolean객체를 주고 받을 필요없다. 위 코드처럼 직렬화를 커스터마이징한다면 송수신 데이터 자체의 크기도 줄일 수 있다. 이는 매우 유용하다.


참고글
flash.utils.IExternalizable
커스텀 직렬화의 사용
ActionScript 3.0 데이터 유형 및 직렬화(serialization)
Serializing between ActionScript and Java
AMF 3 스팩
AS3 BitmapData AMF solution using IExternalizable
Flex and PHP: remoting with Zend AMF

글쓴이 : 지돌스타(http://blog.jidolstar.com/644)


Flash 애플리케이션을 만들때  통합개발환경(IDE)인 Flash CS3, CS4 나 Flex Builder, Flash Builder, FDT와 같은 툴을 주로 사용할 것이다. 실무에서는 당연히 이런 툴을 선택할 수 밖에 없다. 그러나 이들은 사실 유료이고 무겁다.

Flash MiniBuilder라는 프로그램은 간단하게 ActionScript 3.0 기반으로 개발할 수 있도록 Adobe AIR로 만들어진 가벼운 개발툴이다. 이것은 Victor Drâmbă라는 사람이 만들었으며 그의 블로그(http://www.victordramba.com)를 가보면 MiniBuilder에 대한 소식을 볼 수 있다.

MiniBuilder는 Flex SDK 3와 Java JRE 설치를 먼저 해야 정상적으로 사용할 수 있으며 사용하는 방법은 다음 동영상에서 잘 나와있다. 약간 복잡해 보이지만 중간에 start.bat를 실행해야하는 번거로움은 AIR 2.0에서는 없어질 것이라 생각한다.
http://www.youtube.com/watch?v=bjEc2eT_rCE&feature=player_embedded


이 프로그램은 Flex SDK에서 제공하는 컴파일러를 이용해서 만들어진 ActionScript 3.0코드를 컴파일하게 된다. 워낙 가볍기 때문에 Flash Builder에서 느껴지는 묵직함은 찾아볼 수 없다. 일반적인 코딩도 별 어려움이 없고 또한 코드힌트기능 및 에러메시지 출력 기능도 있기 때문에 이 또한 유용하다. 아쉬운 점은 디버깅을 할 수 없고 한글 주석도 못단다는 점.

MiniBuilder는 공개소스이다. GPL 라이센스를 가지며 Google Code(http://code.google.com/p/minibuilder/)에서 전반적인 설명과 소스코드를 볼 수 있다. 원한다면 Flex Builder 3나 Flash Builder 4에서 SVN으로 다운로드 받아 직접 소스를 테스트해볼 수도 있다. (본인도 SVN으로 다운받아 해봤다. 자바소스까지 포함되어 있으므로 Eclipse+Flex Builder 3 Plug-in 환경에서 작업할 것을 권한다. MXML 사용 안하고 전부 ActionScript 3.0으로 만들었다.)



MiniBuilder는 AIR뿐 아니라 Flash버전으로도 제작되어 유명한 ActionScript 3.0 코드 공유사이트인 Wonderfl의 에디터로도 활용되었다. 다음 제작자의 글을 보면 그에 대한 소개가 나와있다.
http://www.victordramba.com/?p=71



벌써 이것이 만들어져 소개된지 몇개월 되었는데 이렇게 멋진 공개 프로그램이 한국에 소개된게 딱 하나밖에 못본 것 같아 간단하게 소개해본다.

참고 링크
Victor Drâmbă의 블로그 : http://www.victordramba.com
Flash MiniBuilder Google Code : http://code.google.com/p/minibuilder
설치 및 사용방법 : http://www.youtube.com/watch?v=bjEc2eT_rCE&feature=player_embedded


글쓴이 : 지돌스타(http://blog.jidolstar.com/642)


지난 2009년 12월 18일에 프로젝트 코드명 Squiggly(스퀴글리)가 Prerelease판으로 업데이트 되었다.
http://labs.adobe.com/technologies/squiggly/

Squiggly는 Flash Player 10, AIR 1.5이상에서 동작한다. 이 엔진은 ActionScript 3.0 기반이며 영어로 문장에서 사용된 단어를 영어사전의 그것과 비교하여 단어의 철자를 체크한다. 이번 업데이트는 TLF(Adobe Text Layout Framework)를 기반으로 하는 Flex 4 Spark 컴포넌트를 지원하도록 했다. Squiggly는 Flex Builder, Flash Builder, Flash CS4등 다양한 툴에서 사용할 수 있다. 단지 아쉬운 것은 영어단어만 체크한다는 점이다.


다음 페이지는 Squiggly 데모이다.
http://labs.adobe.com/technologies/squiggly/demo/

개발자는 언제든지 예제소스와 ASDoc을 아래 링크에서 받아볼 수 있다.


이것을 쓸지 모르겠지만 아무튼 알아두고 있어 나쁠 것도 없으니....

참고
http://adnaru.com/242

글쓴이 : 지돌스타(http://blog.jidolstar.com/640)

 


Flash, Flex, AIR, ActionScript 프로젝트를 진행하면서 모든 코드를 손수 만들어 사용하는 것은 그다지 추천할 만한 일은 아니다. 왜냐하면 아무리 실력있는 개발자라도 프로젝트에 필요한 코드모음을 전부 만드는 것은 너무 큰 노력이 들뿐만 아니라 코드의 유지보수에도 매우 많은 시간을 허비할 수 있기 때문이다.

Flash 기반 코드 라이브러리는 이미 수년간에 걸쳐 공개되어 있다. 조금만 노력을 기울이면 3D, 트윈, 물리엔진, 수학, 보안, 데이터관리, MVC,   as3corelib, Papervision3d, Away3d, Flex 컴포넌트, 각종 유틸등 ActionScript/Flex/AIR/Flash에 관련된 수십,수백가지 우량(?) 라이브러리들을 쉽게 사용할 수 있다.


위에 링크되어 있는 라이브러리만 해도 정말 현업에 바로 사용할 수 있는 것들이 정말 많다. 또한 단순히 공개차원을 넘어 지속적으로 업데이트가 되며 완성도가 높아지고 있다.

그럼 다시 생각해보자. 내가 3D 게임을 만들기 위해 3D 엔진을 만들어야할 것인가? 내가 트윈(tween)을 구현하기 위해 트윈엔진을 만들어야 할것인가? 각종유틸이 필요해서 그걸 다 내가 만들것인가? 만약 검증되지 않고 아직 별도로 공개되어 있지 않은 것이라면 당연히 만들어야할 것이다. 하지만 기본적으로 큰 노력없이 쉽게 사용할 수 있고 자동으로 업데이트 및 검증까지 해주는 사람들이 만든 훌륭한 라이브러리가 있는데... 왜!!! 그걸 다 만들 필요가 있는가이다.

재미있게도 위에서 소개한 라이브러리들은 대부분 Google 코드(http://code.google.com)에 공개되어 있다. 이는 무엇을 의미하는가? 업데이트할때마다 압축파일을 받아 라이브러리에 복사하는 수고가 필요없이 SVN으로 간단하게 업데이트 할 수 있다는 것을 말한다. 이것을 적극 활용하는 방법을 소개하는 것이 이 글을 쓰는 목적이다.

필자는 Flash 개발자라면 누구라도(?) 잘 알고 있는 Flash 3D 엔진인 Papervision3D과 Away3D를 SVN을 이용해 가져와 프로젝트에서 활용하는 방법을 언급하고자 한다. 개발환경은 Flash Builder 4를 기준으로 하겠다. (거의 모든 기능을 Flex Builder 3에서도 할 수 있다.)


1. Flex/Flash Builder에 SVN 플러그인 설치
이제부터 설명할 공개 라이브러리를 사용하기 위해 Flash builder에 SVN 플러그인을 설치해야한다. 방법은 어렵지 않다. 다음 링크를 참고한다.

Flex Builder 에서 Subversion(SVN) 사용하기


2. Google Code에서 Papervision3D SVN 주소 확인하기
Google 코드 사이트(http://code.google.com)로 들어가 papervision3d로 검색해서 Papervison3D 구글코드 페이지(http://code.google.com/p/papervision3d/)로 들어간다. Papervision3d의 라이센스와 각종 링크들을 보면 다른 정보들도 확인할 수 있다.

물론 화면 우측 Featured downloads에 있는 zip 및 swc 파일을 받아 직접 프로젝트에 복사해 사용할 수 있으나(많은 블로그에 이 방법을 소개하고 있다.) 앞서 말한데로 새로 업데이트되는 최신소스를 바로바로 사용해보려면 이 방법은 너무 불편하다. 게다가 공개 라이브러리를 사용하는게 4~5개 이상 넘어가면 지속적인 업데이트가 힘들다.

어떤 개발자는 너무 최신 버전이면 버그가 있을지도 모르지 않겠느냐? 라고 의심할 수 있을 것이다. 하지만 Papervision3D와 같이 이미 대중적(?)으로 인기를 모으고 있는 라이브러리라면 철저한 검증없이 함부로 최신화(commit) 하지 않는다.


위 Source 탭으로 들어가 Checkout 메뉴를 보면 아래처럼 SVN checkout 주소가 있다. 이 주소는 저장소의 주소라 불리운다. 여러분은 이 주소로 Papervision3D 소스 코드를 받아올 수 있겠다.




3. SVN을 이용해 Papervision3D 라이브러리 프로젝트 만들기
이제 본격적으로 Papervision3d를 SVN으로 받아와 라이브러리 프로젝트를 만들어보자.

Flash Builder를 실행한다. 실행되면 메뉴에서 File > Import 로 들어간다. 아래 처럼 창이 뜨면 SVN > Checkout Projects from SVN 을 선택한다음 Next 버튼을 누른다.



아래 처럼 보이면 새로운 저장소 위치를 만들기 위해 Create a new repository location을 선택후 Next 버튼을 누른다. 이는 새로운 저장소라는 것은 SVN을 접속할 주소를 의미한다고 보면 되겠다. 여기서는 Google 코드에서 봤던 주소 http://papervision3d.googlecode.com/svn/trunk 가 되겠다.

아래처럼 나오면 주소를 입력하고 Next 버튼을 누른다.



아래 화면처럼 나오면 http://papervision3d.googlecode.com/svn/trunk 저장소 내에 있는 Papervision3D 소스 경로를 볼 수 있다. 우리는 ActionScript 3.0 기반에서 제작하기 때문에 as3/trunk를 선택한다. 이때 선택하는 기준은 그 안에 src 폴더의 상위 폴더이어야 한다. 이 방식은 다른 라이브러리를 참조해서 하더라도 저장소내에 구조가 조금씩 다르지만 같은 방법을 사용하므로 기억하자.


위 창에서 Next 버튼을 누르면 다음 창으로 전환된다. 세부적으로 Check out 하는 방법을 설정할 수 있는데 우리는 최신 버전을 사용할 것이기 때문에 바로 Finish 버튼을 누른다.



이제 Papervison3D 라이브러리를 가져올 SVN 주소 설정을 끝냈으므로 이 라이브러리가 담길 프로젝트를 생성해야한다. 위 절차를 모두 끝내면 자동적으로 다음과 같이 New Project 창이 뜬다. 이때 Flex Library Project를 선택하면 되겠다.


다음 그림처럼 Project name을 Papervision3D(이름은 아무거나 써도 상관없다.)으로 설정하고 Flex SDK Version을 선택한 다음 Finish버튼을 누른다.


참고로 Flex SDK Version을 선택시에 라이브러리가 AIR 코드가 포함되어 있는 경우라면 Include Adobe AIR libraries를 선택해야한다.(예: as3corelib) 또한 라이브러리가 구동되기 위한 SDK가 무엇인지도 알아야한다. 가령 Flash Player 10부터 3D API를 사용한 라이브러리라면 그것을 지원하는 SDK를 사용해야한다는 것을 의미한다. SDK는 Adobe Labs에서 최신버전을 받아 사용하면 된다.(방법을 모르시면 댓글을 ^^)

아래처럼 Confirm Overwrite 메시지가 뜨면 그냥 OK 버튼을 누른다.



이제 구글 코드 저장소로부터 아래처럼 Papervision 3D 코드를 받아온다.


Package Explorer에 추가된 Papervion3D 라이브러리 프로젝트를 확인하자. 하지만 만약 에러메시지가 나온다면 다음과 같이 해보자. 해당 프로젝트를 선택하고 오른쪽 마우스 버튼을 눌러 컨텍스트 메뉴에서 Properties로 들어가보자. 아래와 같은 창이 나오면 왼쪽 메뉴에서 Flex Library Build Path를 누르고 우측 상단 탭에 Classes를 선택한다. 그리고 Select classes to include in the library를 선택한 다음 src 앞에 check박스를 체크한다. 그리고 OK 버튼을 누르면 다시 컴파일 되면서 컴파일 에러가 사라질 것이다.



여러분은 이제 최신버전의 Papervision3D를 사용할 수 있게 되었다. 아래처럼 해당 프로젝트를 선택하고 오른쪽 마우스 버튼을 눌러 컨텍스트 메뉴에서 Team > Update to Head를 선택하는 것만으로 최신버전으로 업데이트 할 수 있게 된다. 이러한 방법은 SVN으로 공유한 다른 라이브러리들을 항상 최신으로 유지하는데 쉬운 방법을 제공하게 된다.


한가지 언급하자면 위에서 소개하는 방법은 Papervision3D를 예로 들었기 때문에 다른 라이브러리의 공개 형태에 따라 수행하는 방법의 차이가 있을 수 있다는 점을 강조하고 싶다. 그러한 점은 개발자가 알아서 체크할 수 있어야 한다.


4. 조금만 더 가다듬어 보기 (관심있는 사람만 읽으면 됨)
3번까지 진행하는 것만으로도 개발하는데 전혀 문제없지만 아래 내용을 좀더 알고 가면 더욱 좋을 듯 싶다.

지금까지 구글 코드로부터 SVN 저장소를 통해 받아온 Papervison3d 라이브러리는 설정파일을 제외한 ActionScript 3.0 코드가 대부분이다. 그래서 실질적으로 프로젝트에 필요한 설정구성요소인 .actionScriptProperties나 .flexLibProperties등의 파일들은 Papervision3D 개발자가 처음부터 저장소에 공유하지 않는다. 왜냐하면 .actionScriptProperties, .flexLibProperties들은 Flex Builder나 Flash Builder와 같이 특정 개발툴에서 필요한 파일이기 때문에 다른 IDE에서는 무의미 할 수 있기 때문이다.

아래 처럼 Papervision3D의 프로젝트 이름에 SVN으로 공유되었으나 폴더그림에 * 표시가 되어 있다. 이 표시는 원래 SVN 저장소 내용과 프로젝트 내용이 다를때 나온다. 이 다른 내용이라는 것은 금방 언급했던 .actionScriptProperties, .flexLibProperties 등이다.


Flash Builder에서는 프로젝트내의 .actionScriptProperties, .flexLibProperties 파일을 직접 볼 수 없도록 되어 있다. 이는 Filter 처리가 되어 있기 때문이다. 아래 그림처럼 선택해 Filter 처리된 파일들을 전부 check out하자.



위 그림 처럼 Filter 처리된 파일을 check out하면 아래처럼 프로젝트 내에 .actionScriptProperties, .flexLibProperties 등을 볼 수 있게 된다. 이 파일의 아이콘에 ?로 표시된 것은 저장소에 이 파일이 존재하지 않음을 나타내는 것이다.

* 표시나 ? 표시를 없애기 위해서 이러한 파일들이 SVN 저장소와 공유되지 않도록 무시할 수 있도록 하면 된다. Flash Builder에 설치된 SVN 플러그인은 이러한 기능을 지원해준다. 메뉴에서 window > Preference로 들어가 창이 뜨면 Team > Ignored Resources로 들어가면 아래 처럼 나온다. 여기에 다음 내용을 Add Pattern하자.

.actionScriptProject
.actionScriptProperties
.flexProperties
.flexProject
.project
bin
.settings
참고 : http://labs.adobe.com/wiki/index.php/Flex_Builder:resources:plugins:subversion:filtering




이제 아래 그림처럼 * 표시나 ? 표시가 없어지고 저장소의 원본과 프로젝트의 소스가 일치함을 나타내는 표시로 바뀐다.




5. Away3D를 SVN으로 받아오기

Papervision3D 라이브러리를 이용해서 애플리케이션을 만드는 예제는 굳이 설명안해도 된다고 생각한다. 대신 Away3D를 활용하는 방법을 약간 언급하고자 한다.

Away3D도 Papervision3D처럼 구글코드(http://code.google.com/p/away3d/)를 통해 SVN으로 소스를 공개하고 있다. 하지만 Away3D는 Papervision3D와 다르게 Flash Player 9, Flash Player 10 버전을 함께 제공하면서 Flash Player 10 3D 라이브러리를 이용한 3D 엔진인 Away3DLite도 제공한다. 또한 몇가지 유용한 예제도 함께 제공하고 있다.


Away3D 저장소 주소(http://away3d.googlecode.com/svn/trunk)로 접속하면 아래처럼 나온다. fp9과 fp10은 각각 Flash Player 9, 10 버전을 의미한다. 아무래도 Flash Player 10 버전이 최신이면서 효율적으로 만들어졌으므로 fp10에 있는 공개 라이브러리와 예제소스를 참고할 것이다.

fp10에 보면 Away3D, Away3DLite 소스가 있음을 확인할 수 있다. 또한 그에 대한 예제는 Examples에 들어 있다.


아래는 해당 라이브러리와 예제의 저장소 주소이다.


여러분은 Papervision3D를 SVN으로 프로젝트를 만든 것처럼 Away3D에서도 그래도 하면 된다. 단. Examples의 경우 중간에 프로젝트 생성시 ActionScript 프로젝트를 선택하기 바란다. 물론 Flash Player 10 기준이라는 점도 명심하자.

예제 프로젝트에서는 해당 라이브러리 프로젝트의 경로를 포함시켜줘야한다. Away3D_Example은 Away3D 라이브러리를 Away3DLite_Examples는 Away3dLite 라이브러리를 포함해야한다. 방법은 간단하다. Away3D_Example와 Away3DLite_Examples내에 libs 폴더안에 각각의 라이브러리 프로젝트에서 만들어진 bin디렉토리에 있는 
swc를 복사하면 된다. 하지만 이는 애플리케이션을 전부 만들고 배포하고 난 다음에 백업을 위해 선택할 방법이고 실제로 개발할때는 다음과 같이 한다.

1. Away3D_Example 프로젝트를 선택한다.
2. 메뉴에서 Project > Properties를 선택한다.
3. 창이 뜨면 좌측 ActionScript Build Path(Flex의 경우 Flex Build Path)를 선택한다.
4. 상단 Library path 탭을 선택한다.
5. Add Project를 선택한 다음 Away3D 라이브러리를 선택한다.
6. OK 버튼을 누른다.
7. Away3D_Example의 .actionScriptProperties를 연다.
아래 그림처럼  default package에 있는 소스 들은 전부 애플리케이션들이다. 이 코드들이 진정한 애플리케이션으로서 동작하려면 .actionScriptProperties내에 application으로 등록해야한다. 수작업이긴 해도 전부 등록하자. 또는 해당 as 파일을 선택후 마우스 오른쪽 버튼을 눌러 Set as Default Application 항목을 선택해도 된다. 이는 애플리케이션으로 등록하는 동시에 Default 애플리케이션으로 잡아준다. Default 애플리케이션을 지칭하는 것은 .actionScriptProperties 파일 내에 actionScriptProperties 태그의 mainApplicationPath 속성이 그 역할을 한다.



위 처럼 설정하면 이제 예제 파일들을 아무 문제없이 동작시킬 수 있을 것이다.
8. Away3DLite_Example도 위와 비슷한 방법으로 하면 되겠다.

아래는 Away3DLite_Examples에 있는 Advanced_Mario1000.as 애플리케이션을 실행하는 화면이다.

아마 어떤 애플리케이션은 as3dmod 라이브러리가 필요하다는 에러가 나올것이다. 이것도 비슷한 방법으로 Google Code에서 가져올 수 있다. 단, 몇가지 다른 설정을 해야하는데 여기서 설명하지 않고 각자의 몫으로 돌리겠다.


정리하며

개발자라면 Google Code와 친해져야하지 않을까? 또한 기존 라이브러리가 있는가 검색을 해보는 성의가 있어야하지 않을까? 그리고 그 라이브러리를 잘 활용하는 방법을 스스로 깨달으려고 노력해야하지 않을까?

잘못된 사항이나 더 좋은 정보가 있다면 얼마든지 댓글이나 트랙백 부탁한다.


참고
bs-papervision : http://code.google.com/p/bs-papervision/ 
as3dmod : http://code.google.com/p/as3dmod/
sandy3d : http://www.flashsandy.org 
alternativa3D : http://alternativaplatform.com/en/alternativa3d/

글쓴이 : 지돌스타(http://blog.jidolstar.com/639)





예전에 wonderfl.net에 대해서 소개한바 있다. 여기서 소개하는 Beautifl.netWonderfl.net에서 올라온 엄선된 아름다운(?) ActionScript/Flex 컨텐츠를 목록화 해서 쉽게 볼 수 있도록 해주는 서비스이다.

Beautifl.net은 적절히 분류(3D, Effect, Physics, Game, Sound등)가 되어 있어 관심있는 영역의 Flash 컨텐츠도 감상할 수 있겠다. PV, Pick, New 순으로 정렬도 되기 때문에 이 또한 유용하다. 또한 좋은 컨텐츠가 있다면 누구든지 추천할 수 있으며 RSS feed로도 구독할 수 있다. 

Flash로 이런 것도 만들 수 있구나를 넘어 실제 코드도 볼 수 있기 때문에 Flash 개발자들의 스킬업을 위해 이보다 좋은 것도 없을 것 같다.

Wonderfl.netBeautifl.net을 통해 멋진 Flash 세계를 감상해보자.

참고로 이 둘 사이트는 모두 일본에서 만들어졌다.

글쓴이 : 지돌스타(http://blog.jidolstar.com/634)


Flash 엔터프라이즈 개발 업체를 제외하고는 플래시 개발자가 2~3명인 업체가 대부분입니다. 게다가 Flex/AIR등에 처음 접하는 경우도 다분하죠. 결국 Flash 프로젝트의 실무를 어찌 진행할 것인가 고민이 되는 것이 현실입니다. 그래서 도움이 될만한 글들을 모아봤습니다.

http://opencast.naver.com/FL188/15

이 캐스트는 베스트 No.로 12월 10일에 추천되었습니다. ^^
http://opencast.naver.com/home/bestNo.nhn?exposureDate=20091210 

글쓴이 : 지돌스타(http://blog.jidolstar.com/633)

어제 Adobe AIR에서 CPU 사용을 줄이는 방법에 대해서 소개했다. 이 글에 Hika님과 찬익님이 그에 대해 댓글을 달아주시며 다른 정보를 공유해주셨다. 정말 감사드린다. 이런 것이 블로그의 매력일 것이다. 블로그를 내 완벽한 지식을 전달하기 위해 쓴다는 것은 다소 어폐가 있다. 완벽한 것은 없다. 블로그는 지식 소통의 도구로 잘 활용하면 좋은 정보 공유를 통한 더욱 완전해지는 지식습득이 가능하게 한다. 난 지난 몇년간 블로그를 하면서 정말 몸소 체험했다. 지금 이글을 보고 있는 분들도 꼭 블로그를 하길 권장한다.

각설하고. 찬익님이 Flex 4 기반에서 AIR 애플리케이션을 만들때 FrameRate를 조절하는 방법으로 backgroundFrameRate를 소개해주었다. 이것은 Event.ACTIVATE와 Event.DEACTIVATE를 이용해서 이미 Flex 4의
WindowedApplication 클래스에 적용되어 있다. 아래 코드는 WindowedApplication 클래스의 일부이다.

/**
*  Constructor.
*  
*  @langversion 3.0
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
public function WindowedApplication()
{
	super();

	addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
	addEventListener(FlexEvent.PREINITIALIZE, preinitializeHandler);
	addEventListener(FlexEvent.UPDATE_COMPLETE, updateComplete_handler);
	addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);

	var nativeApplication:NativeApplication = NativeApplication.nativeApplication;
	nativeApplication.addEventListener(Event.ACTIVATE, nativeApplication_activateHandler);
	nativeApplication.addEventListener(Event.DEACTIVATE, nativeApplication_deactivateHandler);
	nativeApplication.addEventListener(Event.NETWORK_CHANGE, dispatchEvent);

	nativeApplication.addEventListener(InvokeEvent.INVOKE, nativeApplication_invokeHandler);
	initialInvokes = new Array();

	//Force DragManager to instantiate so that it can handle drags from
	//outside the app.
	DragManager.isDragging;
}

/**
*  @private
*  Storage for the backgroundFrameRate property.
*/
private var _backgroundFrameRate:Number = 1;

/**
*  Specifies the frame rate to use when the application is inactive.
*  When set to -1, no background frame rate throttling occurs.
*
*  @default 1
*  
*  @langversion 3.0
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
public function get backgroundFrameRate():Number
{
	return _backgroundFrameRate;
}

/**
*  @private
*/ 
public function set backgroundFrameRate(frameRate:Number):void
{
	_backgroundFrameRate = frameRate;
}

/**
*  @private
*/
private function nativeApplication_activateHandler(event:Event):void
{
	dispatchEvent(new AIREvent(AIREvent.APPLICATION_ACTIVATE));

	// Restore throttled framerate if appropriate when application is activated.
	if (prevActiveFrameRate >= 0 && stage)
	{
	    stage.frameRate = prevActiveFrameRate;  
	    prevActiveFrameRate = -1;
	}
}

/**
*  @private
*/
private function nativeApplication_deactivateHandler(event:Event):void
{
	dispatchEvent(new AIREvent(AIREvent.APPLICATION_DEACTIVATE));

	// Throttle framerate if appropriate when application is deactivated.
	// Ensure we've received an updateComplete on the chance our layout
	// manager is using phased instantiation (we don't wish to store a
	// maxed out (1000fps) framerate).
	if ((_backgroundFrameRate >= 0) && (ucCount > 0) && stage)
	{
	    prevActiveFrameRate = stage.frameRate;
	    stage.frameRate = _backgroundFrameRate; 
	}
}


이는 Flex 4를 이용해 AIR 애플리케이션을 만들때 별도의 조치없이 backgroundFrameRate 속성 설정만으로 frameRate를 조절할 수 있다. 이 값은 기본으로 1이다. 더 좋은 값은 0.01이라고 한다. 이는 거의 멈추게 하는 수준이다. 이 속성은 Flex 4에서 AIR를 위해 WindowedApplication 에만 적용되어 있다. Flash기반인 Application 클래스에는 이 속성이 없다.
참고글
Adobe AIR에서 CPU 사용을 줄이는 방법

글쓴이 : 지돌스타(http://blog.jidolstar.com/624)

오랜만에 네이버 오픈케스트에 케스팅했습니다. 이만저만 하는게 많다보니 여기에 신경을 전혀 못쓰고 있었네요. 요즘에는 AIR분야를 좀 해보려고 하고 있습니다. 항상 눈팅만하다가 본격적으로 결과물을 내어야할 것이 생겨서 이것저것 해보는 중입니다. 이런걸 정리하다 보면 저 자신도 너무 모르는게 많고 항상 부족함을 느낍니다. 아무튼 혼자 아는 것보다 함께 알아서 서로 공유해 서로 커나가는 것이 제 생각입니다. 좋은 정보가 되길 바랍니다.

http://opencast.naver.com/FL188/14

글쓴이 : 지돌스타(http://blog.jidolstar.com)
Adobe AIR는 다양한 OS(Windows, Mac, Linux)에 구동될 수 있는 애플리케이션을 만드는데 사용하는 일종의 Flash Platfom기술이다. Flash ActionScript 3.0이나 Ajax만으로도 AIR 애플리케이션을 만들 수 있기 때문에 기존에 웹개발자들이 다른 언어를 배우지 않고 일반 데스크탑용 애플리케이션을 만드는데 있어서 접근성이 좋다. 앞으로 AIR는 데스크탑뿐 아니라 모바일등과 같은 다양한 기기에도 적용될 예정이다.

하지만 AIR외에 다른 데스크탑용 애플리케이션과 비교해 그 적용범위가 아직까지 많은 부분 부족하고 복잡한 UI를 다루는데 있어서 성능문제가 걸릴 수 있다. 하지만 AIR 2.0 Beta 버전이 오픈된 것을 볼 수 있었듯이 계속 발전해나갈 것이다. 물론 성능면에서도 마찬가지 일 것이다. 그래도 약간은 부족하다. 기능은 그렇다 쳐도 지금의 성능을  개발자가 조금만 신경을 쓴다면  획기적으로 향상시킬 수 있다.

일전에 Reducing CPU usage in Adobe AIR라는 글을 보았다. 여기서는 매우 단순하고 쉬운 방법으로 framerate를 줄임으로서 CPU 사용율을 현격히 줄이는 방법을 소개하고 있다.

이 방법이 퍼포먼스를 올리기 위한 방법의 하나의 예시는 될 수 있지만 그 전부는 아니라는 점은 밝혀둔다.

(이 글을 완벽히 이해하기 위해서는 ActionScript 3.0과 AIR에 대한 전반적 이해가 요구됩니다.)

FrameRate를 줄임
Framerate를 줄임(Framerate throttling)은 애플리케이션의 휴면(idle)이 있을때 자원 사용을 줄여 퍼포먼스를 증가시키는 기술을 의미한다. 이를 구현하기 위해 ActionScript 3.0에서 매우 유용한 속성으로 Stage.frameRate가 있다. 이것을 이용하면 런타임시에 애플리케이션의 framerate를 변경시킬 수 있다. 

여기서 보여지는 예제는 Reducing CPU usage in Adobe AIR에서 소개한 글에 나온 예제를 조금더 실용적으로 만들었다.(실제로 실행해 볼 수 있도록) Flash Builder 4와 AIR 2.0 SDK를 설치한 사람들이라면 이 예제를 실제로 테스트 해볼 수 있다. 아래 순서대로 개발/테스트 환경을 구축하면 된다.

  • 만약 Flash Builder를 설치 안했다면 다음 링크를 통해 받으세요.
  • SDK와 Runtime을 다운로드 받습니다.
  • 다운받은 Runtime을 실행해 설치합니다.
  • (MS Windows의 경우)SDK는 압축을 풀고 그안에 있는 내용을 Flash builder가 설치된 sdks/4.0.0과 sdks/3.4.1 폴더에 각각 덮어씌웁니다. 제 경우는 C:\Program Files\Adobe\Adobe Flash Builder Plug-in Beta 2\sdks\4.0.0
  • Flash Builder를 실행합니다.
  • 메뉴에서 File > New > Flex Project를 선택합니다.
  • 프로젝트 이름을 적고 Application Type은 AIR를 선택합니다.
  • Next버튼을 두번 클릭후 Main Application file이름이 프로젝트명.mxml로 되어 있다면 Novice.as로 바꾸세요. 그리고 Finish 버튼을 누릅니다.
  • 아래 첫번째 초급 코드를 복사해서 Novice클래스를 열어 붙힙니다.
  • 디버그 모드로 테스트합니다.
  • 두번째, 세번째의 경우 만들어진 프로젝트의 소스폴더에 해당 클래스 이름으로 Class를 만듭니다. File > New > ActionScript Class를 선택한뒤 아래 소스를 복사해 붙여넣으면 되겠죠?
  • Package Explorer에 프로젝트명을 선택후 마우스 우클릭해서 컨텍스트 메뉴에서 Properties를 선택합니다.
  • 창이 뜨면 좌측 Flex Applications를 선택하고 오른쪽에 Add를 눌러 추가한 클래스(Intermediate.as, Expert.as)를 추가한뒤 OK를 합니다. Intermediate-app.xml과 Expert-app.xml이 자동 생성됩니다.
  • 이제 디버그 모드로 실행하면서 동작하는 형태를 학습하세요.
  • 아래 소스는 다음 링크에서 다운로드 받으셔도 됩니다.



  • 초급
    Framerate를 줄일때의 시점을 선택하는데 가장 쉽고 유용한 방법은 NativeApplication에서 Event.ACTIVATE 와 Event.DEACTIVATE 이벤트를 사용하는 것이다. AIR로 만들어진 빈윈도우를 선택해서 사용할때 CPU사용율이 1.8%라면 다른 윈도우를 선택해 그 윈도우의 CPU 사용율이 0.4%까지 떨여졌다고 한다. 또한 framerate를 0.01로 지정하면 0.2%까지 떨어진다고 한다. 이에 대한 예제는 다음과 같다. 예제가 이해하기 쉬우므로 따로 설명하지 않겠다.


    package {
    	import flash.desktop.NativeApplication;
    	import flash.display.NativeWindow;
    	import flash.display.NativeWindowInitOptions;
    	import flash.display.NativeWindowType;
    	import flash.display.Sprite;
    	import flash.display.StageAlign;
    	import flash.display.StageScaleMode;
    	import flash.events.Event;
    	import flash.text.TextField;
    	import flash.text.TextFieldAutoSize;
    	import flash.utils.getTimer;
    	
    	/**
    	 * CPU 사용 줄이기 예제 1 
    	 * @author Yongho, Ji
    	 * @since 2009.12.1
    	 * @see http://blog.jidolstar.com/622
    	 */ 
    	public class Novice extends Sprite {
    		private var __isActive:Boolean = false;
    		private var __window:NativeWindow;
    		private var __textField:TextField;
    		public function Novice() {
    			__init();
    			var options:NativeWindowInitOptions = new NativeWindowInitOptions();
    			options.type = NativeWindowType.UTILITY;
    			
    			__window = new NativeWindow(options);
    			__window.width = 200;
    			__window.height = 200;
    			__window.title = "Novice";
    			
    			__textField = new TextField();
    			__textField.autoSize = TextFieldAutoSize.LEFT;
    			__textField.text = "";
    			
    			__window.stage.scaleMode = StageScaleMode.NO_SCALE;
    			__window.stage.align = StageAlign.TOP_LEFT;
    			
    			__window.stage.addChild(__textField);
    			__window.activate();
    			__window.addEventListener(Event.CLOSING,__onClosing);
    		}
    		private function __init():void {
    			NativeApplication.nativeApplication.addEventListener(Event.ACTIVATE, __onActive );
    			NativeApplication.nativeApplication.addEventListener(Event.DEACTIVATE, __onDeactive );
    			stage.addEventListener(Event.ENTER_FRAME,__onEnterFrame);
    		}
    		private function __onActive($event:Event):void {
    			stage.frameRate = 50;
    			__isActive = true;
    		}
    		private function __onDeactive($event:Event):void {
    			stage.frameRate = 1;
    			__isActive = false;
    		}
    		private function __onEnterFrame($event:Event):void {
    			__textField.text =  "active:" + __isActive + " " + getTimer();
    		}
    		private function __onClosing($event:Event):void {
    			NativeApplication.nativeApplication.exit();
    		}
    	}
    }
    


    중급

    위의 예제보다 조금더 고급적으로 framerate를 조절할 필요가 있다. 가령, 마우스 휠 이벤트에 따라 스크롤이 되는 컨텐츠가 있는 경우가 그것인데 평소에는 작은 framerate를 유지하다가 스크롤시에 빠른 렌더링이 필요하므로 framerate를 올려주는 것이다. 구체적으로 MouseEvent.MOUSE_WHEEL이 발생시 framerate를 올려주고 Event.ENTER_FRAME 이벤트에서 스크롤링후 500ms이 지난 다음 다시 framerate를 줄이는 것이다. 이도 휴면(idle)상태에서 쓸데없이 렌더링되는 것을 방지하고 필요한 동작할 때만 빠른 렌더링을 요구하도록 함으로써 CPU 사용율을 줄여주는 것이다.

    package {
    	import flash.desktop.NativeApplication;
    	import flash.display.NativeWindow;
    	import flash.display.NativeWindowInitOptions;
    	import flash.display.NativeWindowType;
    	import flash.display.Sprite;
    	import flash.display.StageAlign;
    	import flash.display.StageScaleMode;
    	import flash.events.Event;
    	import flash.events.MouseEvent;
    	import flash.text.TextField;
    	import flash.text.TextFieldAutoSize;
    	import flash.utils.getTimer;
    	/**
    	 * CPU 사용 줄이기 예제 2 
    	 * @author Yongho, Ji
    	 * @since 2009.12.1
    	 * @see http://blog.jidolstar.com/622
    	 */ 
    	public class Intermediate extends Sprite {
    		private static const ACTIVE:int = 50;
    		private static const INACTIVE:int = 1;
    		private var __isActive:Boolean = false;
    		private var __isScrolling:Boolean = false;
    		private var __buffer:int;
    
    		private var __window:NativeWindow;
    		public function Intermediate() {
    			__init();
    			var options:NativeWindowInitOptions = new NativeWindowInitOptions();
    			options.type = NativeWindowType.UTILITY;
    			
    			__window = new NativeWindow(options);
    			__window.width = 200;
    			__window.height = 200;
    			__window.title = "Intermediate";
    			
    			var textField:TextField = new TextField();
    			textField.y = 20;
    			textField.width = 195;
    			textField.height = 175;
    			textField.multiline = true;
    			textField.wordWrap = true;
    			textField.border = true;
    			textField.borderColor = 0xff0000;
    			textField.text = "Adobe AIR는 다양한 OS(Windows, Mac, Linux)에 구동될 수 있는 애플리케이션을 만드는데 사용하는 일종의 Flash Platfom기술이다. Flash ActionScript 3.0이나 Ajax만으로도 AIR 애플리케이션을 만들 수 있기 때문에 기존에 웹개발자들이 다른 언어를 배우지 않고 일반 데스크탑용 애플리케이션을 만드는데 있어서 접근성이 좋다. 앞으로 AIR는 데스크탑뿐 아니라 모바일등과 같은 다양한 기기에도 적용될 예정이다.하지만 원천적으로 데스크탑용 애플리케이션과 비교해 그 적용범위가 아직까지 많은 부분 부족하고 복잡한 UI를 다루는데 있어서 성능문제가 걸릴 수 있다. 적용되는 범위는 AIR 2.0 Beta 버전이 오픈된 것을 볼 수 있었듯이 계속 발전해나갈 것이다. 또한 성능면에서도 마찬가지 일 것이다. 그래도 성능면에 있어서 개발자가 조금만 신경을 쓴다면 어떤 부분에 있어서 획기적으로 AIR 애플리케이션의 성능을 향상시킬 수 있다. 일전에 Reducing CPU usage in Adobe AIR라는 글을 보았다. 여기서는 매우 단순하고 쉬운 방법으로 framerate를 줄임으로서 CPU 사용율을 현격히 줄이는 방법을 소개하고 있다. ";
    
    			__window.stage.scaleMode = StageScaleMode.NO_SCALE;
    			__window.stage.align = StageAlign.TOP_LEFT;
    			
    			__window.stage.addChild(textField);
    			__window.activate();
    			__window.addEventListener(Event.CLOSING,__onClosing);
    		}
    		private function __init():void {
    			NativeApplication.nativeApplication.addEventListener(Event.ACTIVATE, __onActive );
    			NativeApplication.nativeApplication.addEventListener(Event.DEACTIVATE, __onDeactive );
    			stage.addEventListener(MouseEvent.MOUSE_WHEEL, __onMouseWheel, true);
    		}
    		private function __onActive($event:Event):void {
    			stage.frameRate = ACTIVE;
    			__isActive = true;
    			trace( "active" );
    		}
    		private function __onDeactive($event:Event):void {
    			stage.frameRate = INACTIVE;
    			__isActive = false;
    			trace( "deactive" );
    		}
    		private function __onMouseWheel($event:MouseEvent):void {
    			if( !__isActive ) {
    				if ( !__isScrolling ) {
    					stage.addEventListener(Event.ENTER_FRAME, __onEnterFrame, true);
    				}
    				stage.frameRate = ACTIVE;
    				__isScrolling = true;
    				__buffer = getTimer()+500;
    			}
    		}
    		private function __onEnterFrame($event:Event):void {
    			if( __buffer < getTimer() ) {
    				stage.frameRate = INACTIVE;
    				__isScrolling = false;
    			}
    		}
    		private function __onClosing($event:Event):void {
    			NativeApplication.nativeApplication.exit();
    		}
    	}
    }
    


    고급

    위에서 소개한 경우보다 약간더 어려운 주제로 넘어가보자. 먼저 창이 보이지 않을때와 보일때에 어떻게 처리할 것인가이다. 보이는 경우라면 일단 최소한의 framerate를 5로 주고 안보인다면 1로 준다. 이 경우는 MS Windows에서는 Tray Icon으로 바뀌며 창이 안보여질 때나 Mac에서 Dock으로만 표시될 필요가 있을때 사용될 수 있을 것이다. 굳이 보여지지 않는데 지나친 framerate를 줄 필요가 없기 때문이다. 평상시 Active한 상태에서는 24 framerate를 유지하지면 때에 따라서 부드럽게 운동하는 모습을 렌더링할 필요가 있을 때가 있다. 상태변화에 따라 Tweener 기능을 사용하는 경우가 그것인데 이때는 평소보다 framerate를 올려줄 필요가 있을 수 있다.

    아래 AIR 애플리케이션 소스코드는 두개의 버튼이 있다. 한개는 창의 visible을 false로 지정했다가 1초후 다시 true로 해주는 것이고 또 하나는 가상의 애니메이션이 있다고 가정하고 1초정도 여분을 둔다. 각 상태가 변할때마다 framerate를 Dubugging 시에 콘솔창에서 상태변화를 확인할 수 있도록 짜여있다.

    package {
    	import flash.desktop.NativeApplication;
    	import flash.display.NativeWindow;
    	import flash.display.NativeWindowInitOptions;
    	import flash.display.NativeWindowType;
    	import flash.display.Shape;
    	import flash.display.SimpleButton;
    	import flash.display.Sprite;
    	import flash.display.StageAlign;
    	import flash.display.StageScaleMode;
    	import flash.events.Event;
    	import flash.events.MouseEvent;
    	import flash.filters.BevelFilter;
    	import flash.text.TextField;
    	import flash.text.TextFormat;
    	import flash.utils.getTimer;
    	import flash.utils.setTimeout;
    	/**
    	 * CPU 사용 줄이기 예제 3 
    	 * @author Yongho, Ji
    	 * @since 2009.12.1
    	 * @see http://blog.jidolstar.com/622
    	 */ 
    	public class Expert extends Sprite {
    		public static const ANIMATING:int = 50;
    		public static const ACTIVE:int = 24;
    		public static const INACTIVE_VISIBLE:int = 5;
    		public static const INACTIVE_INVISIBLE:int = 1;
    		
    		private var __isActive:Boolean = false;
    		private var __isAnimating:Boolean = false;
    		private var __window:NativeWindow;
    		private var __buffer:int;
    		
    		public function Expert() {
    			__init();
    			var options:NativeWindowInitOptions = new NativeWindowInitOptions();
    			options.type = NativeWindowType.UTILITY;
    			
    			__window = new NativeWindow(options);
    			__window.width = 200;
    			__window.height = 200;
    			__window.title = "Expert";
    			
    			__window.stage.scaleMode = StageScaleMode.NO_SCALE;
    			__window.stage.align = StageAlign.TOP_LEFT;
    			
    			//창을 감추기 버튼 
    			var buttonSkin:Sprite = new Sprite;
    			buttonSkin.graphics.beginFill( 0xff0000, 1.0 );
    			buttonSkin.graphics.drawRect(0,0,100,50);
    			buttonSkin.graphics.endFill();
    			buttonSkin.filters = [new BevelFilter()];
    			var textFormat:TextFormat = new TextFormat();
    			textFormat.color = 0xffffff;
    			textFormat.align = "center";
    			var textField:TextField = new TextField();
    			textField.defaultTextFormat = textFormat;
    			textField.text = "창을 감추기(1초후에 나타남)";
    			textField.width = 100;
    			textField.multiline = true;
    			textField.wordWrap = true;
    			textField.y = buttonSkin.height/2 - textField.textHeight/2; 
    			buttonSkin.addChild( textField );
    			var button:SimpleButton = new SimpleButton(buttonSkin,buttonSkin,buttonSkin,buttonSkin);
    			button.addEventListener(MouseEvent.CLICK, __onHide );
    			__window.stage.addChild( button );
    			
    			//Animation 동작 시키기 버튼 
    			buttonSkin = new Sprite;
    			buttonSkin.graphics.beginFill( 0x0000ff, 1.0 );
    			buttonSkin.graphics.drawRect(0,0,100,50);
    			buttonSkin.graphics.endFill();
    			buttonSkin.filters = [new BevelFilter()];
    			textFormat = new TextFormat();
    			textFormat.color = 0xffffff;
    			textFormat.align = "center";
    			textField = new TextField();
    			textField.defaultTextFormat = textFormat;
    			textField.text = "동작시키기(1 second)";
    			textField.width = 100;
    			textField.multiline = true;
    			textField.wordWrap = true;
    			textField.y = buttonSkin.height/2 - textField.textHeight/2; 
    			buttonSkin.addChild( textField );
    			button= new SimpleButton(buttonSkin,buttonSkin,buttonSkin,buttonSkin);
    			button.y = 52;
    			button.addEventListener(MouseEvent.CLICK, __onAnimate );
    			__window.stage.addChild( button );			
    						
    			__window.activate();
    			__window.addEventListener(Event.CLOSING,__onClosing);
    		}
    		private function __init():void {
    			NativeApplication.nativeApplication.addEventListener(Event.ACTIVATE, __onActive );
    			NativeApplication.nativeApplication.addEventListener(Event.DEACTIVATE, __onDeactive );
    		}
    		private function setFrameRate( frameRate:Number ):void {
    			stage.frameRate = frameRate;
    			trace( frameRate );
    		}
    		private function animate($duration:int = 1000):void {
    			trace( "동작시작");
    			setFrameRate( 50 );
    			__buffer = getTimer() + $duration;
    			if(!__isAnimating) {
    				stage.addEventListener(Event.ENTER_FRAME,__onEnterFrame);
    			}
    		}
    		private function active():void {
    			if(!__isAnimating) {
    				setFrameRate( ACTIVE );	
    			} 
    			trace( "active " );
    		}
    		private function deactive():void {
    			if (!__isAnimating) {
    				setFrameRate( (__window.visible) ? INACTIVE_VISIBLE : INACTIVE_INVISIBLE );
    			}
    			trace( "deactive " );
    		}
    		private function show():void {
    			__window.visible = true;
    			active();
    		}
    		private function hide():void {
    			__window.visible = false;	
    			deactive();
    		}
    		private function __onActive($event:Event):void {
    			__isActive = true;
    			active();
    		}
    		private function __onDeactive($event:Event):void {
    			__isActive = false;
    			deactive();
    		}
    		private function __onEnterFrame($event:Event):void {
    			if( __buffer < getTimer() ) {
    				trace( "동작끝");
    				stage.removeEventListener(Event.ENTER_FRAME,__onEnterFrame);
    				__isAnimating = false;
    				if( __isActive ) {
    					active();
    				} else {
    					deactive();
    				}
    			}
    		}
    		private function __onHide($event:MouseEvent):void {
    			hide();
    			setTimeout(show,1000);
    		}
    		private function __onAnimate($event:MouseEvent):void {
    			animate( 1000 );
    		}
    		private function __onClosing($event:Event):void {
    			NativeApplication.nativeApplication.exit();
    		}
    	}
    }
    


    참고글
    Reducing CPU usage in Adobe AIR 
    [머드초보]시스템트레이아이콘(system tray icon) 예제


    글쓴이 : 지돌스타(http://blog.jidolstar.com/622)
    찬익님의 블로그(http://blog.chanik.com/25)로 부터 매우 재미있는 내용을 봤다. 바로 커스텀 메타데이터 태그(custom metadata tag)에 대한 내용인데 커스텀 컴포넌트, 커스텀 이벤트등의 용어는 들어봤어도 커스텀 메타데이터 태그는 생소하다. 말그대로 Flex에서 사용하는 메타데이터 태그인 [Event], [Bindable] 이런 것 들은 사실 예전부터 mxmlc로 컴파일될 때에 ActionScript 3.0으로 변환된다는 것은 알고 있었지만 메타데이터 태그가 이렇게 사용되는지에 대한 내막은 전혀 알지 못했던 것이 사실이다. 아무튼 너무 좋은 정보라 공유하고자 한다.

    사실 Flex 2시절부터 커스텀 메타데이타에 대한 이야기가 있었다고 한다. 하지만 Flex 3서부터 컴파일 옵션에 "-keep-as3-metadata MyTag"와 같은 형태로 사용할 수 있게 되었다. 이는 다음과 같이 ActionScript 3.0 코드에서 사용할 수 있게 된다.
    [Listen(obj="this.closeButton", event="click")]
    public function closeClickHandler(event:MouseEvent) {...}
    

    메타데이타 태그는 위처럼 메소드 뿐 아니라 변수 및 클래스에도 사용할 수 있다.


    커스텀 메타데이타를 사용하는 방법

    커스텀 메타데이타를 사용하는 방법은 3단계로 이뤄진다.

    1. 컴파일러 구성
    Flex 프로젝트 컴파일 옵션으로 "-keep-as3-metadata+=Meta1, Meta2" 를 삽입한다. 만약 라이브러리 프로젝트에서 한다면 거기에 이 옵션을 사용하면 이 라이브러리 프로젝트를 참조하는 다른 프로젝트에 따로 줄필요는 없다.

    2. metadata를 작성

    package
    {
        [Meta2(param1 = "param 1 value")]
        public class TestClass
        {
    
            [Meta1(param1 = "param 1 value", param2 = "param 2 value")]
            public var test1:String;
            
            
            [Meta2(paramA = "param 1 value", paramB = "param 2 value")]
            public function get test2():String
            {
                return null;
            }
            
            public function set test2(val:String):void
            {
            }
    
            [Meta1(param1 = "param 1 value")]
            public function someMethod():void
            {
            };
    
        }
    }
    

    3. 런타임(runtime)시에 작성한 메타데이타를 사용
    describeType(TestClass)를 이용한다. 위처럼 클래스와 메소드에 메타데이타를 작성했다면 다음과 같이 E4X형태의 XML로 접근할 수 있다.

    <type name="TestClass" base="Class" isDynamic="true" isFinal="true" isStatic="true">
      <extendsClass type="Class"/>
      <extendsClass type="Object"/>
      <accessor name="prototype" access="readonly" type="*" declaredBy="Class"/>
      <factory type="TestClass">
    
        <metadata name="Meta2">
          <arg key="param1" value="param 1 value"/>
        </metadata>
    
        <extendsClass type="Object"/>
    
        <method name="someMethod" declaredBy="TestClass" returnType="void">
          <metadata name="Meta1">
            <arg key="param1" value="param 1 value"/>
          </metadata>
        </method>
    
        <variable name="test1" type="String">
          <metadata name="Meta1">
            <arg key="param1" value="param 1 value"/>
            <arg key="param2" value="param 2 value"/>
          </metadata>
        </variable>
    
        <accessor name="test2" access="readwrite" type="String" declaredBy="TestClass">
          <metadata name="Meta2">
            <arg key="paramA" value="param 1 value"/>
            <arg key="paramB" value="param 2 value"/>
          </metadata>
        </accessor>
    
      </factory>
    </type>
    

    만약 Class의 [Meta2]의 param1에 접근한다면 다음과 같처럼 하면 된다.
    var testClass:TestClass = new TestClass();
    var xml:XML = describeType(testClass);
    trace(xml.metadata.(@name==Meta2).arg.(@key==param1).@value);
    

    위에 대한 결과는 'param 1 value'이 된다.


    어떻게 활용할 수 있을까?
    이것을 어떻게 활용할지에 대해서는 찬익님의 언급처럼 FlexUnit 4에서 지원하는 [Test] [BeforeClass]등과 같은 좋은 예시가 있다. 그 외에 것도 예제가 있는지 확인해봤다. 그 결과 재미있는 글을 발견했다.

    Annotating ActionScript Classes with Custom Metadata + Simple ORM Framework for AIR

    이 글에서 말하고 있는 요지는 커스텀 메타데이타를 이용해서 Value Object로 작성한 클래스에 이로 만들어진 객체가 데이타베이스의 어떤 테이블과 어떤 필드에 들어가는지 결정해줄 수 있다는 것이다.


    package
    {
    	[Bindable]
    	[Table(name="contact")]
    	public class Contact
    	{
    		[Id]
    		[Column(name="contact_id")]
    		public var contactId:int;
    
    		[Column(name="first_name")]
    		public var firstName:String;
    
    		[Column(name="last_name")]
    		public var lastName:String;
    		public var address:String;
    		public var city:String;
    		public var state:String;
    		public var zip:String;
    		public var phone:String;
    		public var email:String;
    	}
    }
    
    

    위처럼 작성된 클래스는 contactId 값은 contact 테이블의 contact_id 필드와 매치가 되도록 만든다는 것이다. [Id]메타데이타는 Primay Key와 같은 존재이다. 결국 이것을 해석해서 DB와 연동하는 AIR기반의 EntityManager를 만들어 위 클래스의 객체를 다음과 같이 사용하면 DB연동까지 된다.


    var contact:Contact = new Contact();
    contact.firstName = "Christophe";
    contact.lastName = "Coenraets";
    contact.email = "ccoenrae@adob.com";
    entityManager.save(contact);
    


    이를 수정하려면 다음처럼 쓴다.
    contact.firstName = "Chris";
    entityManager.save(contact);
    


    삭제하려면 다음처럼 쓴다.
    entityManager.remove(contact);
    

    너무 기발하다. 만약 Metadata를 사용하지 않았다면 Value Object와 DB 테이블의 필드명을 맞추기 위해 좀 노가다를 해야할지 모른다. 그런데 Metadata를 이용함으로써 프레임워크 단위로 말끔하게 이 문제를 해결해준다. 

    이에 대한 소스와 테스트 자료는 [여기]에서 다운로드 받는다.
    혹시 링크가 깨졌다면 다음 링크에서 받길 바란다. 
     
    이렇게 활용할 수 있다는 것이 감동이다. 
     

    정리하며
    찬익(http://blog.chanik.com)님 덕분에 아침부터 재미있는 정보를 얻을 수 있었다. 좋은 정보를 공유해주신 찬익님께 감사하며 커스텀 메타데이타에 대한 활용을 담은 글들이 많이 나왔으면 한다.


    참고글
    Custom metadata in three simple steps.
    Annotating ActionScript Classes with Custom Metadata + Simple ORM Framework for AIR
    찬익님의 커스텀 메타데이터 태그


    위 모든 예제는 Flash Builder 4 및 Flex Builder 3에서 테스트 해볼 수 있습니다.


    글쓴이 : 지돌스타(http://blog.jidolstar.com/620)

    Flash Platform 개발자 분들에게 반가운 소식이 있습니다. AIR 2.0 Beta와 Flash Player 10.1 Prelease 버전이 공개되었습니다. 이제 Adobe Labs(http://labs.adobe.com/)에서 직접 다운로드 받을 수 있습니다.


     

    Adobe AIR 2.0 beta

    AIR 2.0은 다음과 같은 새로운 feature들이 추가되었습니다.(영어 압박? 그럼 : http://blog.chanik.com/entry/AIR-20-Beta-릴리즈 )

    • Support for the detection of mass storage devices.
    • Advanced networking capabilities like secure sockets, UDP support, and the ability to listen on sockets.
    • Support for native code integration.
    • The ability to open a file with its default application.
    • Multi-touch and gesture support.
    • New APIs for access to raw microphone data.
    • Webkit update with HTML5/CSS3 support.
    • Global error handling.
    • Improved cross-platform printing
    • Improved security and support for enterprise and government standards.

    AIR 2.0에 대해서 자세한 설명 다음 글들을 참고하세요. 



    AIR 2.0으로 개발테스트 하시려면 다음과 같이 합니다. 윈도우, Flash Builder 4 beta 2 환경을 가정하고 설명드립니다.

    더 쉽게 환경을 구축하고 테스트 해보시겠다면 다음 링크를 참고하세요.
    http://blog.jidolstar.com/619 

     

    1. 만약 Flash Builder를 설치 안했다면 다음 링크를 통해 받으세요.
    2. SDK와 Runtime을 다운로드 받습니다.
    3. 다운받은 Runtime을 실행해 설치합니다.
    4. SDK는 압축을 풀고 그안에 있는 내용을 Flash builder가 설치된 sdks/4.0.0과 sdks/3.4.1 폴더에 각각 덮어씌웁니다. 제 경우는 C:\Program Files\Adobe\Adobe Flash Builder Plug-in Beta 2\sdks\4.0.0
    5. Flash Builder를 실행합니다.
      Windows>Preferences에 들어가 Flash Builder > Installed Flex SDKs를 확인해보세요.
    6. Learn to Use Adobe AIR 2 Beta에 들어가 관련 내용을 학습합니다.
    7. Adobe AIR 2 Sample Applications에 들어가 Sample을 받아보고 실제 Flash Builder에서 작업해봅시다. (해당작업화면을 이미지 캡쳐하고 이런거 너무 힘들어서요. 그냥 말로 주절주절 써봅니다.)
      저는 일단 수많은 예제들중에 Microphone 예제의 소스를 다운로드 받았습니다.
      Flash Builder에서 Flex Project를 생성합니다. 물론 Application Type은 Desktop으로 설정해야겠죠? 예제를 다운받아 사용하므로 프로젝트 이름은 예제 소스 압축을 풀어보면 메인소스의 이름을 선택해주면 됩니다. 저의 경우 MicrophoneExamples군요. 프로젝트를 생성했으면 그 다음으로 Flash Builder에서 방금 생성한 프로젝트를 선택한 상태에서 마우스 오른쪽 버튼을 눌러 Import로 들어갑니다. 창이 뜨면 General > Archive File을 선택하고 다음 버튼을 누릅니다. Browse...버튼을 눌러 다운받은 소스압축파일을 선택합니다. 그리고 Finish하세요. Overwrite할거냐 물으면 Yes To All 을 선택하시면 됩니다. 초반에 sdk 에러가 뜰겁니다. 원본 소스의 sdk 설정이 달라서 그러는데요. 이것을 해결하기 위해 프로젝트명을 선택한후 마우스오른쪽 버튼을 눌러 Properties로 들어가 Flex Compiler를 선택한 다음 Use a specific SDK를 Flex 3.4로 선택해주시면 됩니다. 4.0이 아닌 이유는 예제 소스가 mx:WindowedApplication으로 만든 것으로보아 Flex 3.4 기반으로 만들어졌기 때문입니다. 다른 예제가 s:WindowedApplication으로 만들어져 있다면 Flex 4.0을 선택하세요. 다 끝났습니다. 이제 실행해보세요.


      앗... 제 데톱에 마이크가 없군요... ㅡㅡ; 아무튼 이렇게 하면 됩니다. Sample에는 Flex뿐 아니라 Ajax, Flash용도 있으니 잘 활용하시면 학습하는데 도움이 될겁니다.

     

    Flash Player 10.1 Prelease

    Flash Player 10.1의 가장 큰 특징은 바로 모바일 지원입니다. 제 블로그에서 앞서 설명했지만 Flash Player 10.1은 오픈소스프로젝트를 통해 탄생된 결과물입니다. 데스크탑 뿐아니라 다양한 기기에서도 Adobe Flash Platform 기술이 적용될 수 있도록 Flash Player 10.1을 만든겁니다. 이는 모바일과 같이 저급(?) 하드웨어 기반에서 항상 이슈가 되어 왔던 메모리, 전력소비, 속도, 하드웨어가속등의 문제를 해결한 Flash Player를 만들었다는 것을 의미합니다. 이외에도 차세대 모바일에 걸맞는 몇가지 기능(멀티터치등)을 구현할 수 있는 API도 추가되었죠. 또한 H.264 비디오도 지원해줍니다.

    Flash Player 10.1에 대해서 더욱 자세히 알고 싶다면 Flash Player 10.1 Beta Release Notes를 참고하시면 될 것 같습니다.

    Flash Player 10.1 기반의 프로그램을 개발하고 싶다면 Flash Player 10.1 플러그인을 자신의 컴퓨터에 먼저 설치한뒤 Player Global SWC를 다운받아 개발하면 됩니다. 일련의 절차를 간단하게 설명드립니다.

    참고로 Flash Player 10.1은 정식 배포버전이 아닙니다. 테스트 목적으로 하시고 실제 배포는 하지 마세요.

    Flash Player 10.1 플러그인을 http://labs.adobe.com/downloads/flashplayer10.html 에서 다운로드 받습니다. 기존에 설치된 Flash Player는 삭제를 하시고 설치하세요. 윈도우의 경우 파이어폭스와 모질라 계열이라면 Download plug-in for Windows (EXE, 2.2 MB)를 받고 IE라면 Download active-x for Windows (EXE, 2.2 MB)를 다운로드 받으세요. 아쉽게도 개발자를 위한 디버그 버전은 아직 없는 것 같습니다.

    Flash Player 10.1 기반 개발을 위해 해당 API로 개발할 수 있도록 지원해주는 SWC를 다운로드를 같은 페이지에서 받을 수 있습니다. 다운받아 압축을 풀면 playerglobal.swc가 있습니다. 이것을 자신의 프로젝트에 포함하여 개발하면 됩니다. 함께 포함된 readme.txt파일을 보면 사용하는 방법이 잘 나와 있는데 여기서도 간단히 설명해 드리죠. (단, Flash Builder 4 beta 2 기준입니다.)

    1. 만약 Flash Builder를 설치 안했다면 다음 링크를 통해 받으세요.
    2. 새로운 애플리케이션 프로젝트를 만듭니다.
    3. playerglobal.swc를 playerglobal10.1.swf로 이름을 바꾸고 만들어진 프로젝트의 libs폴더에 복사합니다. libs폴더에 복사하면 자동으로 Referenced Libraries로 설정됩니다. (여기서 이름을 바꾼 이유는 다음 내용을 설정할 때 playerglobal.swc의 Link Type을 수정못하도록 Flash Builder가 만들어져 있기 때문입니다.)
    4. 프로젝트명을 선택후 마우스 오른쪽 버튼을 눌러 properties를 선택한 뒤 Flex Builder Path를 선택합니다. 그런 다음 Library path 탭을 선택한뒤 libs 폴더를 열어 Link Type을 External로 바꿉니다. 그런 다음 Flex 4.0 를 열어 기존 playerglobal.swc는 삭제합니다. Link type이 External이라는 것은 컴파일시 사용한 클래스를 빼놓는다는 뜻입니다. 어짜피 playerglobal.swc에 정의된 클래스는 이미 Flash player 10.1에서 지원해주기 때문에 굳이 swf안에 포함할 필요가 없기 때문이지요.
    5. Flash Player 10.1을 요구하는 HTML이 되도록 만들어주기 위해 Properties 창에서 Flex Compiler를 선택합니다. Adobe Flash Player options에서 Use a specific version을 10.1.0으로 바꾸거나 Additional compiler arguments에 -target-player=10.1.0 을 추가합니다.

    이로써 Flash Player 10.1 에서 돌아가는 Flash 애플리케이션을 만들때 환경 구축을 모두 완료했습니다.

    아래처럼 Flash Player 10.1 API인 TouchEvent, TransformGestureEvent 등을 사용할 수 있게 되었습니다.



    아래 링크를 통해 Flash Player 10.1에 대한 다양한 정보를 얻을 수 있습니다.


    앞으로 정식버전이 배포되고 Flash CS5도 나오게 되면 아이폰 및 다양한 기기에서 동작하는 재미있는 애플리케이션들을 만들 수 있게 될 것입니다. 

    Flash Platform 개발자들이여.. 향후 10년 밥벌이 벌었습니다. ㅋㅋㅋ


    글쓴이 : 지돌스타(http://blog.jidolstar.com/617)
     



    Flash, Flex, AIR 개발자들이 한권정도는 꼭 가지고 있을 만한 책이다. 이 책은 콜린 무크의 유명한 책인 Essential ActionScript 3.0을 지금도 업계에서 활발히 일하고 계신 유윤선, 송호철님이 번역한 책이다. ActionScript 3.0에 관한한 거의 바이블 수준이다. 시간될 때마다 쭉 훑어보며 느낀 거지만 ActionScript 3.0에 대한 전반적인 개념을 습득하는데 이만한 책이 없다고 생각된다. 

    Flash, Flex, AIR를 개발할 때 가장 기초가 되는 개념은 ActionScript 3.0이다. ActionScript 3.0에 대한 전반적인 개념 및 지식없이 Flex에 접근하다 보면 결국 한계를 느끼게 될 것이다. 왜냐하면 Flex 프레임워크가 모든 기능을 수행해 줄 수 있도록 만들어진 것은 아니기 때문이다. Flex는 프레임워크로서 가치가 있는 것이지 모든 기능을 Flex에서 찾으면 안된다. 또한 Flash로 개발할 때도 마찬가지 인데 타임라인만 의지하다가 뭔가 고급기술을 다뤄야할 필요가 있을때 ActionScript 3.0을 알아야 가능해진다. Flash든 Flex든 AIR든... Flash Platform 개발자가 접근할 수 있는 가장 기초가 되는 것은 결국 ActionScript 3.0이다. (예외적으로 AIR의 경우 Javascript로 만들 수 있는데 이는 컴파일러를 지원하는 차원이지 근간은 ActionScript 이다.)  

    이 책의 한가지 단점이라면 Flash Player 10 API에 해당하는 내용까지 다루지는 않고 있다. 이와 관련된 내용은 여전히 온라인의 ActionScript 3.0 라이브 독을 참고해야한다.

    글쓴이 : 지돌스타(http://blog.jidolstar.com/615

      

    일본에 Spark 프로젝트가 있다. 이 프로젝트는 ActionScript Class Library를 오픈소스로 만들고 공유하는 것을 하나의 모토로 삼고 있는데 그 유명한 증강현실(FLARToolKit)을 Flash로 구현한 것도 이 프로젝트에서 진행된 것이다. 이외에도 너무 멋진 라이브러리가 이 프로젝트를 통해 만들어졌고 여기서 만들어진 몇몇 라이브러리를 실무에 적용하고 있다.

     
    Flex 4에는 Spark로 구성된 새로운 컴포넌트들이 존재한다. 그런데 이 Spark가 바로 일본의 Spark 프로젝트의 이름에서 온것임이 확신된다. 즉, Flex 4의 Spark 컴포넌트는 많은 부분에서 일본이 관여했다는 것을 의미한다. 실제로 2009 Adobe MAX에서 Spark 패키지 설계에 나이 20정도 되는 젊은 일본 개발자와 관계가 있다는 것을 확인했다.

    Spark 프로젝트로 일본은 Adobe의 큰 관심을 받게 되었고, 일본 RIA시장에 있어서 없어선 안될 정도로 크게 성장해 있는 상태이다. 아마 일본 RIA 분야에 있어서 자부심을 생기게 하는 훌륭한 프로젝트 팀이라고 생각한다.

    이에 반해 한국은 이 정도로 활발히 진행되는 오픈 프로젝트가 전무하다. 이는 빨리빨리 주위의 한국의 개발 환경덕택에 개발자들이 다른 활동할 수 있는 여지가 없는 것이 가장 큰 문제겠고, 오픈 지향이 미덕으로 방향을 잡고 있는 마당에도 유독 소프트웨어는 폐쇄적인 것도 문제라고 생각한다. 또한 개발자들은 무슨 문서 작성하는 사람처럼 취급해 버리는 무지한 관리자들이 있는한 한국에서 일본과 같은 개방적이고 활발한 개발 커뮤니티나 오픈 소스, 오픈 프로젝트는 어려울 것이다. 당장 문제를 해결하고 이익만 추구하는 한국의 IT시장이 지속된다면 소프트웨어 개발자는 그저 노동만 하고 그에 대한 돈만 벌어가는 존재로 전락할 수 밖에 없다. 창의적인 개발자는 사라지고 그저 일만 받고 처리하는 수동적인 개발자만 늘어나게 될 것이고 결국 한 나라의 IT시장의 발전에 큰 저해요소로 작용할 것이 분명하다.

    한국에도 일본 Spark 프로젝트와 같은 활발하고 멋진 팀이 자발적으로 시행될 수 있는 국가적, 기업적 지원이 적극적으로 이뤄지길 희망한다.

    글쓴이 : 지돌스타(http://blog.jidolstar.com/573)


    프로그램상에 폰트를 포함할 때 다음과 같은 문장을 사용할 것이다.

    [Embed(source='C:/WINDOWS/Fonts/ARIAL.TTF', fontName = "MyFont", mimeType = "application/x-font-truetype")]
    private var font:Class;
    

    그런데 Flash Builder 4에서 작업할 때부터 위처럼 Embed한 폰트가 적용이 되지 않았다. 사용한 True Type 폰트는 언제나 테스트할때 문제없이 동작한 것이기 때문에 왜 안되는지 의문이 들었다. Flash Builder 4의 컴파일러인 mxmlc가 버그가 있거나 다른 설정이 추가되었나 싶었지만 그렇지 않았다. 그래서 열심히 구글링해봤더니 폰트를 Embed 처리할때 embedAsCFF 속성이 추가되었다는 것을 발견하고 아래처럼 테스트 코드를 작성해봤다.

    package {
    	import flash.display.Sprite;
    	import flash.text.TextField;
    	import flash.text.TextFormat;
    	import flash.text.TextFieldAutoSize;
    	import flash.text.AntiAliasType;
    	[SWF(width = "500", height = "240", backgroundColor = "#FFFFFF", framerate = "24")]
    	public class FontTest extends Sprite {
    		[Embed(source='C:/WINDOWS/Fonts/ARIAL.TTF', embedAsCFF="false", fontName = "MyFont", mimeType = "application/x-font-truetype")]
    		private var font:Class;
    		public function FontTest() {
    			var format:TextFormat = new TextFormat();
    			format.font = "MyFont";
    			format.size = 30;
    			format.color = 0x000000;
    			var label:TextField = new TextField();
    			label.embedFonts = true;
    			label.autoSize = TextFieldAutoSize.LEFT;
    			label.antiAliasType = AntiAliasType.ADVANCED;
    			label.defaultTextFormat = format;
    			label.text = "blog.jidolstar.com";
    			addChild(label);
    			label.rotation = 5;
    		}
    	}
    }
    


    여기서 embedAsCFF 속성은 도데체 뭔가? 이 전에 CFF(Compact Font Format)가 뭔지 알아야만 했다.

    폰트형태는 여러가지 종류가 있다. OTF(Open Type Font)와 TTF(True Type Font)등이 있다. OpenType은 MS와 Adobe가 TrueType의 후속작으로 Cross Platform을 지원하도록 만들 파일 포멧이라고 한다. 이 OpenType에는 Glyph Outline형식에 대한 정의는 없고 TrueType, CFF, Adobe Type 1(PostScript)를 사용한다고 한다. 이 말은 OTF중에는 TrueType으로 글자모양을 정의한 폰트도 있고 CFF 또는 PostScript Font로 정의한 폰트도 있음을 의미한다.
     
    OpenType과 TrueType에 대한 더욱 자세한 내용은 아래 링크를 참고하자.
    http://en.wikipedia.org/wiki/OpenType
    http://en.wikipedia.org/wiki/TrueType

    CFF는 OpenType의 하나로서 다음 링크에 더 세세하게 설명하고 있다.
    http://en.wikipedia.org/wiki/Compact_Font_Format#Compact_Font_Format

    CFF에 대한 스펙은 다음 파일을 참고한다.


    Flash Player 10과 Adobe AIR 1.5이상부터 TTF뿐 아니라 CFF도 지원하게 되었다. 이는 PDF와 직접적인 관계가 있는 것 같다.  그래서 폰트를 포함할때 TTF인지 CFF인지 명시할 필요에 의해 생긴 것이 embededAsCFF인듯하다. 만약 TTF를 사용한다면 위 예제처럼 embededAsCFF를 false로 지정해야한다.

    필자도 Font Type에 대한 지식은 거의 없어서 난감했다. CFF를 포함하면 글꼴 렌더링시에 텍스트를 보다 쉽게 읽을 수 있으며 작은 크기에서 글꼴의 표시 품질이 향상된다고 Adobe ActionScript 3.0 가이드 문서에는 나와 있을뿐 정확히 TTF와 CFF에 대한 명확한 해석을 찾지는 못했다.

    Adobe ActionScript 3.0 가이드 : 글꼴을 이용한 작업


    갑자기 대두된 Font 포함문제 때문에 매우 당혹스러웠지만 그나마 해결방법이라도 찾아 다행이다. 이에 대해 정확히 기술된 한글문서를 아직 찾지 못했다. 더욱 다양한 글들이 많이 올라왔으면 한다.

    이 실험은 Flash Builder 4 Beta 2에서 테스트 했으며 아래 링크로부터 Flash Builder 4를 다운받을 수 있다.
    http://www.adoberia.co.kr/pds/down.html?src=text&kw=000026



    글쓴이 : 지돌스타(http://blog.jidolstar.com/614)
    Flex 또는 ActionScript 3.0 라이브러리를 만들면서 하나의 네임스페이스를 지정키 위해 manifest설정을 하게 된다. (manifest를 모른다면 일단 Flex Builder에서 나만의 manifest만들기를 먼저 읽어보길 바란다.)

    Flash Builder 4 beta 2를 이용하면서 같은 방법으로 manifest를 설정하는데 아래와 같은 에러가 계속 나는 것이다.


    경험상 소스상에는 문제가 없는 것이기 때문에 다른 부분을 찾다가 beta 2에 있는 새로운 기능을 포착했다. 아래 이미지는 해당 프로젝트에서 Properties > Flex Library Builder Path 에서 Classes 탭을 선택했을때 화면이다. 이전 버전의 Builder에서는 보이고 있는 라디오 버튼이 없었던 것으로 알고 있는데 이번에 새롭게 들어갔나보다.

    저 기능은 라이브러리 컴파일시 컴파일할 대상의 Class를 선택하는 기능인데 이번에 기능이 바뀌면서 자동으로 모든 클래스가 포함되는 것을 선택하도록 하는 기능이 추가된 것이다. 이게 기본값이다. manifest관련 에러가 났던 것인 이 부분이 원인이였다. 다음 처럼 Select classes to Include In the library를 선택해보고 다시 컴파일하면 에러가 사라진다.


    아놔~~ 이 때문에 1시간 허비했다. 아직 beta버전이니깐 넘어가자. 정식버전 나오면 나아지겠지.

    Flash Builder 4는 이전 Flex Builder 3에 비해 너무도 많은 부분이 개선이 되었다. 이제 개발툴로서 제대로 자리매김하는 것으로 보인다. Flash Builder 4 및 다른 제품군을 다운 받기 위해 아래 링크를 참고하길 바란다.

    http://www.adoberia.co.kr/pds/down.html?src=text&kw=000026

    글쓴이 : 지돌스타(http://blog.jidolstar.com/613)
    Flash Builder 4 Plugin을 설치후 기존 프로젝트로 열었을때 황당한 문제에 봉착했다. 아래 그림처럼 툴바에 Run, Debug 버튼이 없어진 것이다.


    한번도 이런적이 없어서 몇시간 당황했는데, 해결방법은 이외로 간단했다.

    먼저 툴바위에 마우스 오른쪽 버튼을 눌러 Customize Perspective 를 선택한다. 또는 메뉴에서 Window > Customize Perspective 를 선택하면 되겠다. 그럼 다음과 같은 창이 나온다. 여기서 Command 탭을 선택한다.

    위 그림과 같이 왼쪽 Available command groups에 Launch를 체크한뒤 OK버튼을 누른다.



    휴~ 이거 하나 알아낼려고 엄청 힘들었다. 별것도 아닌것이... ㅎㅎㅎ

    Flash Builder 는 언제든지 다운받을 수 있다. 다음 링크를 참고바란다.
    http://www.adoberia.co.kr/pds/down.html?src=text&kw=000026 

    글쓴이 : 지돌스타(http://blog.jidolstar.com/608)
    다시 오픈했습니다. http://blog.jidolstar.com/618



    사용자 삽입 이미지

    Flex 2 기반으로 근 2년 이상 한글문서를 담당했던 Flexdocs.kr 서비스를 하지 못하게 되었습니다. 그동안 Flexdocs.kr은 제 개인서버에서 서비스 했습니다. 한글작업을 위해 몇몇분들이 관심을 가지고 지속적으로 수정했지만 개인서버라는 제약과 관심부족 그리고 그 서버를 유지하는데 있어서 필요이상의 개인자본을 넣어야한다는 부담이 있었습니다. 그래서 집에서 간단한 서버 구축으로 유지하려고 했으나 인터넷공급업체에서 80번 포트를 막아놓아 더 이상 서비스를 하기에는 불가능하게 되었습니다.(요즘 대부분 인터넷 공급업체는 80번 포트 이용을 막고 있습니다.)

    flexdocs.kr의 문서는 모두 제가 가지고 있습니다. 만약 flexdocs.kr을 계속 유지해야한다고 생각하시고 서버 호스팅을 무료로 해주실 수 있는 분이 있으시다면 연락부탁드리겠습니다. flexdocs.kr은 Apache, php, mysql이 지원되야하며 svn과 mod_rewrite등이 지원되면 되겠습니다.

    이 문서는 누구의 소유가 아닙니다. 상업적 용도로 사용할 수 없습니다.

     


     

    무사히 미국 LA에서의 일정을 보내고 돌아왔습니다. 주요 목적은 Adobe MAX 행사 참석이였습니다.

    ACC(Adobe Community Champion)1년 활동평가를 통해 발탁되어 좋은 기회를 가지게 되었습니다.

    행사기간은 3일이였으며 남는 시간에는 미국의 가족들과 오붓한 시간도 보냈습니다. ^^

     

    참석한 Adobe MAXAdobe의 가장 큰 행사중에 하나로 1년에 한번씩 미국의 주요 도시를 돌면서 열립니다이번 행사 참여로 Adobe 로드맵에 대해서 어느 정도 알 수 있게 되었습니다.

     

    이 로드맵의 첫번째 단추는 Adobe의 기술의 핵심인 Flash Player을 모든 플랫폼에 적용하는 겁니다. 이 플랫폼이라는 것은 모바일이 될 수 있고  각종 다른 기기들이 될 수 있을겁니다. 이것이 가능하게 하기 위해 Adobe는 Open Screen Project(http://www.openscreenproject.org/) 라는 것에 참여하고 있습니다. 이 프로젝트로 각종 기업에서 만들어지는 모바일등의 디바이스에 Flash Player가 설치되고 이미 엄청나게 보급화 되어 있는 Flash 개발인력을 어렵지 않게 흡수 시킬 수 있게 됩니다.

     

    Open Screen Project를 반영하여 탄생된 것이 바로 Flash Player 10.1 입니다. 이 Flash player 10.1은 데스크탑 뿐 아니라 모바일에도 최적화되어 돌아갈 수 있도록 메모리 및 속도 향상에 큰 변화를 가져왔습니다. 그리고 기존에 Flash Lite로만 개발했던 인력을 ActionScript 3.0, Flex 개발자들까지 모바일 프로그램을 할 수 있도록 된거지요. 메모리,속도향상등에 더욱 자세한 내용을 보고 싶다면 제 블로그를 보세요.

    http://blog.jidolstar.com/594

     

    대부분의 개발자의 주요 관심사인 Apple의 경우 Open Screen Project에 참여하지 않고 있습니다. 그래서 AdobeFlash로 개발하고 아에 iPhone용 애플리케이션이 나오도록 해버렸습니다. 이미 어도비 LabsFlash로 만든 iPhone용 애플리케이션이 애플스토어에 올라왔다는 것을 확인할 수 있습니다. 현재 직접 아이튠즈에서 다운로드 받아볼 수 있습니다.

    http://labs.adobe.com/technologies/flashcs5/appsfor_iphone/

     

    Open Screen Project를 통해 대부분의 디바이스 및 각종 플랫폼에 Flash Player가 설치될 수 있도록 하여 Adobe가 얻을 수 있는 것은 Flash 애플리케이션의 유통일겁니다. Adobe가 내놓은 모든 것들이 이제는 모두 이 유통에 집중될 모양입니다. 이에 대한 구체적인 시스템이 바로 Flash Platform Service(http://www.adobe.com/devnet/flashplatform/services/index.html) 입니다. 아래링크는 제 블로그에 올린 Flash Platform Service에 대한 전문입니다.

    http://blog.jidolstar.com/601

     

    정리하자면, AdobeOpen Screen Project를 통해 각종 디바이스에 Flash Player가 돌아갈 수 있도록 하여 시장은 선점하고 여기에 유통시장을 만들어 앱스토어 처럼 수익을 창출하겠다는 겁니다.

     

    이것이 제가 Adobe MAX에 참석해서 파악한 Adobe가 나아가는 방향입니다.

     

    (제가 정확히 파악했는지는 모르겠습니다. 사실 큰 회사의 전체적인 로드맵을 이 짧은 글에 담는 것은 많이 부족하겠지요. 잘못된 내용이나 보강할 내용있다면 댓글 또는 트랙백 걸어주시길 바랍니다.)

     

    글쓴이 : 지돌스타(http://blog.jidolstar.com/603)

    여러분은 지금 Flash로 만든 iPhone, iPod 용 애플리케이션을 애플 스토어에서 다운로드 받을 수 있습니다. Adobe Lab(http://labs.adobe.com)에서 올해 말에 나올 Flash Professional CS5를 홍보하기 위해 떡밥 제대로 내놯습니다. ^^

     

    공식 페이지는 아래 링크를 찾아가세요.

    http://labs.adobe.com/technologies/flashcs5/

    http://labs.adobe.com/technologies/flashcs5/appsfor_iphone/

     

    아래 이미지를 클릭하면 아이튠즈를 통해 받을 수 있습니다. 무료도 있고 유료도 있어요. (아이튠즈가 설치 되어있어야 겠죠?)

     

     

    Chroma Circuit

    chromacircuit

    Trading Stuff

    trading

    Fickleblox

    fickleblox

    Just Letters

    justletters

    South Park

    southpark

    That Roach Game

    roach

    Red Hood

    redhood
     

     

     

    Flash로 아이폰 프로그램을 만든다?!

    Flash/Flex 개발자들 사이에서는 큰 반향일 일으킬게 분명합니다.

    국내에도 곧이어 아이폰이 나온다는데 하고 싶은 개발의 폭이 한층 넓어지겠네요.

     

    단! 기능은 기능일 뿐입니다.

    사업적 가치를 위해서 어떻게 접근할 것인가는 Object-C든 Java든 ActionScript 든 같습니다.

     

    아~ 그리고... 미국애들은 아이팟말고 아이폰만 사용하더군요. 덕분에 MAX 행사 내내 아이팟은 제대로 꺼내보지 못했습니다. ㅋ 그러니까 저 프로그램인 아이폰용으로만 작동될 수도 있다는 거죠. ^^

     

    글쓴이 : 지돌스타(http://blog.jidolstar.com/602)


    호텔에서 Adobe에서 제공하는 셔틀버스를 타고 Adobe MAX 행사장인 LA 컨벤션 센터에 왔습니다. 오늘부터 3일간 행사에 참가하게 됩니다. 등록을 마치고 제공해주는 간단한 아침식사(빵과 커피)를 먹고 첫날 키노트 행사에 가기 위해 근처 Nokia Theater에 갔습니다. 전 ACC라 Adobe Community Leader라 태그가 붙은 명찰을 받았습니다. 이 마크가 달려있으면 주요인사, 기자단, 주요발표자 다음으로 자리배치 해줍니다.

    근데 이름아래 회사이름이 스타플이군요. ㅎㅎ 서비스가 스타플인데... 등록을 잘못해주신듯... 아무튼 괜찮습니다. ^^

    우리 열이아빠님도 명찰에 만족하신듯.. 자랑스럽게 명찰들고 포즈 취해주시네요 ㅋ

    Nokia Theater 무대입니다. 저기 위에서 키노트를 진행하는군요.

    이 키노트 행사에 무려 3500명 정도가 왔다고 하네요. 다들 무슨 이야기가 올까 궁금해하는 것 같았습니다.
    마이크 챔버스 아저씨도 왔네요. 초상권 침해나? ^^


    어도비의 윤미선님과 우야꼬와 나~~ 행사중에 있을 3D영화를 보기 위해 준 안경을 쓰고 함께 찰칵
    그나마 잘나온 야꼬와 내 사진.. ㅋ


    오픈 공연을 시작했네요.... 아무튼 이렇게 Adobe MAX가 시작되었습니다. ^^

    이날 Adobe MAX에서 Flash Player 10.1과 AIR 2.0등 각종 최신정보를 들을 수 있었고 기억에 남는 것은 플래시가 iPhone 애플리케이션으로 컨버팅해주는 기능을 CS5 부터 넣겠다는 것과 Flash Player가 오픈 스크린 프로젝트하에 많은 회사에서 제작하는 모바일등 다양한 플랫폼에서 동작하도록 지원한다는 것, 그리고 더욱 강력해지는 AIR 2.0에서 USB 지원 및 소켓서버, 멀티터치 지원등입니다.

    키노트 마지막쯤에 AVATAR라는 3D영화 제작과정과 각종 씬을 보여주었는데....3D안경을 끼고 보는 이 영화는 정말 실세계 3D에 빠지는 듯 했다. 영화내용도 너무 실감나더군요. 이 영화가 아마도 올해말에 미국에 개봉할 터인데 한국에서도 크게 인기를 끌지 않을까 생각합니다.

    Flex 4 컴포넌트와 AIR 2.0에 대한 세션을 듣고 저녁에는 Adobe 관계자 및 기자들과 만나 식사를 같이 했습니다. 시차적응 못해서 전날 1시간 밖에 못잤는데 오늘은 푹 자야겠네요.

    글쓴이 : 지돌스타(http://blog.jidolstar.com/595)


    + Recent posts