이번 Flash Player 10.1에서는 많은 기능들이 추가되었다.

특히 모바일에 최적화되는 업데이트가 많았는데 그 밖에도 Flash에 몇 가지 큰 기능들이 추가되었다.

하나씩 살펴보자.



1. 에러창을 없애보자.



예기치 못하게 나타나는 Flash 에러창은 사용자나 개발자 모두에게 당황스러운 경험일 것이다.

개발하는 입장에서도 모든 에러를 예상하기란 쉽지 않은 일이고

사용자 입장에서 이제는 어느정도 당연스럽게 여기는 지경이다.

이번 Flash Player 10.1에서는 예상하지 못한, 즉 미리 처리해놓지 않은 에러들을 한 곳에서 처리할 수 있게 되었다.

잡히지 않은 에러라는 뜻으로 UncaughtErrorEvent라는 이벤트가 사용된다.

UncaughtErrorEvent는 각 SWF마다 하나의 장소로 모이게 된다.

어디서 에러가발생하건간에 SWF의 LoaderInfo객체 전달된다. 즉 UncaughtErrorEvent를 사용하는 방법은 다음과 같다.

import flash.events.UncaughtErrorEvent;

this.loaderInfo.uncaughtErrorEvents.addEventListener( UncaughtErrorEvent.UNCAUGHT_ERROR, globalErrorHandler );

function globalErrorHandler( $e: UncaughtErrorEvent ): void
{
     trace( "Global Error : " + $e.error );
}

각 SWF마다 uncaughtErrorEvents라는 속성이 새로 추가되었다.

이 객체는 처리되지 못한 에러들이 지나가는 길이라고 생각하면 된다.

이 객체에게 UncaughtErrorEvent 이벤트를 받아 리스너를 등록해놓으면 된다.

실제로 사용하는 코드는 다음과 같다.

import flash.events.UncaughtErrorEvent;
import flash.errors.IllegalOperationError;
import flash.events.MouseEvent;

this.loaderInfo.uncaughtErrorEvents.addEventListener( UncaughtErrorEvent.UNCAUGHT_ERROR, globalErrorHandler );

function globalErrorHandler( $e: UncaughtErrorEvent ): void
{
     trace( "Global Error : " + $e.error );
    
     switch( $e.error.constructor )
     {
          case SecurityError :
               trace( "security error occured." );
               break;
         
          case IllegalOperationError :
               trace( "works wrong." );
               break;
              
          default :
               trace( "Unexpected error occured." );
               break;
     }
    
     $e.preventDefault();
}

this.stage.addEventListener( MouseEvent.CLICK, clickListener );

function clickListener( $e: MouseEvent ): void
{
     throw new SecurityError( "Do" );
}

위 코드에서는 예상하지 못한 에러가 발생했을 경우 에러의 종류에 따라 행동을 달리 하는 코드다.

그리고 globalErrorHandler의 마지막구문인 preventDefault 메소드를 호출함으로써 해당 에러를 소멸시키는 것이다.

단 UncaughtErrorEvent를 구현하면서 주의할 점은

예상하지 못한 에러가 발생할 경우 더 이상 Flash가 진행할 수 있는지 없는지는 개발자가 판단하여 사용자의 진행을 중지시키거나 다른 쪽으로 유도하는 장치가 마련되어 있어야한다.

에러라는 성격자체가 프로세스가 정상적으로 진행되지 못함을 의도하는 것이기 때문에

어떤 예상치 못한 에러가 발생하더라도 프로세스를 정확하게 보장해야하는 몫은 여전히 남아있는 것이다.



2. 마이크를 다뤄보자.

예전에는 마이크에서 받아오는 사운드는 단지 볼륨 조절 수준 밖에 할 수 없었다.

하지만 이번에 새로 추가된 Microphone 클래스에서는

SampleDataEvent.SAMPLE_DATA라는 이벤트가 발생하게 되어

마이크에서 들어오는 사운드를 바이트 수준에서 처리할 수 있게 되었다.

마이크에서 들어오는 사운드를 캡쳐하는 방법은 다음과 같다.

import flash.media.Microphone;
import flash.events.SampleDataEvent;
import flash.utils.ByteArray;

var mic: Microphone = Microphone.getMicrophone();

if( mic == null )
     return;
    
mic.gain = 44;
mic.rate = 60;
mic.setUseEchoSuppression( true );
mic.setLoopBack( false );
mic.addEventListener( SampleDataEvent.SAMPLE_DATA, micSampleHandler );

function micSampleHandler( $e: SampleDataEvent ): void
{
     this.sample = $e.data;
    
     trace( this.sample.bytesAvailable );
}

var sample: ByteArray;

위 코드를 1 Frame에 넣고 실행하면 다음처럼 마이크 입력을 받을 것이냐는 확인 창이 나타난다.



“허용”을 누르면 이때부터 마이크에 사운드가 입력될 때 마다 SampleDataEvent.SAMPLE_DATA이벤트가 발생하게 된다.

여기서 받아오는 사운드 데이터를 sample이라는 변수에 저장해놓는 것이다.

위 예제에서는 setLoopBack( false )를 함으로써 마이크에서 들어오는 사운드를 스피커로 재생하지 않도록 해놓았다.

아래 예제에서는 이렇게 받아온 사운드 데이터를 직접 Sound클래스를 통해서 재생하는 방법을 살펴보겠다.

import flash.media.Microphone;
import flash.events.SampleDataEvent;
import flash.utils.ByteArray;
import flash.media.Sound;

var mic: Microphone = Microphone.getMicrophone();

if( mic == null )
     return;

mic.gain = 44;
mic.rate = 60;
mic.setUseEchoSuppression( true );
mic.setLoopBack( false );
mic.addEventListener( SampleDataEvent.SAMPLE_DATA, micSampleHandler );

function micSampleHandler( $e: SampleDataEvent ): void
{
     this.sample = $e.data;
    
     this.sound.play();
}

var sample: ByteArray;

var sound: Sound = new Sound;
sound.addEventListener( SampleDataEvent.SAMPLE_DATA, soundSampleHandler );

function soundSampleHandler( $e: SampleDataEvent ): void
{
     var i: int = 8192;
     var float: Number;
     while( i-- && this.sample.bytesAvailable )
     {
          float = this.sample.readFloat();
         
          $e.data.writeFloat( float );
          $e.data.writeFloat( float );
     }
}

마이크를 통해서 사운드가 들어올 때마다 sample에 사운드 데이터를 저장하고 Sound.play()를 통해 사운드를 재생시킨다.

그 이유는 Sound객체가 사운드를 재생하려고 할 때 재생할 데이터가 없으면 SampleDataEvent.SAMPLE_DATA 이벤트가 발생하는데

이때 재생할 데이터를 넣어주면 Sound는 그 데이터를 재생하게끔 되어 있기 때문이다.

사운드 데이터는 8192 크기의 사운드이지만 간혹 그 이상의 데이터가 들어올 경우가 있다.

하지만 유효한 데이터의 크기는 무조건 8192이기때문에 사운드 데이터를 사용할 때는 다음과 같이 사용하도록 한다.

function soundSampleHandler( $e: SampleDataEvent ): void
{
     var i: int = 8192;
     var float: Number;
     while( i-- && this.sample.bytesAvailable )
     {
          float = this.sample.readFloat();
         
          $e.data.writeFloat( float );
          $e.data.writeFloat( float );
     }
}

위 예제를 실행한 후에 마이크에 말을 하게 되면 직접 스피커로 재생되는 것을 볼 수 있을 것이다.

이처럼 Flash Player 10.1에서는 마이크에서도 사운드 데이터를 직접 활용할 수 있게 되었다.

또 뿐만아니라 mp3 에서도 512크기의 샘플 데이터를 추출할 수 있게 되었다.

이를 활용하면 리듬 게임같이 사운드를 정밀하게 다루는 게임도 만들 수 있게 된 것이다.

앞으로 사운드를 활용한 다양한 서비스들이 나타나지 않을까 예상된다.



3. 보다 세밀해진 국가별 언어 서비스

이번 Flash Player 10.1에서는 flash.globalization이라는 패키지가 추가됐다.

나라마다 다른 화폐 단위나 문자등을 보다 세밀하게 다룰 수 있게 되었다. 하나씩 살펴보도록 하자.

먼저 사용할 수 있는 Locale의 종류를 알아봐야한다. Locale이란 국가별 언어의 종류라고 볼 수 있다.

미국에서 쓰는 영어는 en-US라고 하고 한국은 ko-KR, 일본은 ja-JP라고 한다.

Locale을 설정하는 방법을 살펴보자.

import flash.globalization.LocaleID;

var locale: LocaleID = new LocaleID( "en_US" );

locale은 이제 앞으로 사용될 언어 설정에서 미국의 영어로 설정되어질 것이다.

이 Locale설정으로 “adobe”와 “Adobe”가 같은 단어인지를 판별하는 메소드를 만들어보자. 

문자열을 비교하는데는 Collator 클래스가 사용된다. 아래는 Collator를 이용해서 문자열을 비교하는 코드이다.

import flash.globalization.LocaleID;
import flash.globalization.Collator;
import flash.globalization.CollatorMode;

var locale: LocaleID = new LocaleID( "en_US" );

var collator: Collator = new Collator( locale.name, CollatorMode.MATCHING );
trace( collator.equals( "adobe", "Adobe" ) ); // true

locale을 설정하고 Collator의 모드를 비교로 설정한 후 두 문자열을 비교하면 두 문자열이 같은 단어인지를 판별해준다.

이번엔 정렬하는 Collator를 살펴보자.

import flash.globalization.Collator;

var text: Array = [ "cafe", "cafe", "cafe" ];

text.sort( new Collator( "en_US" ).compare );

trace( text ); // cafe,cafe,cafe

text.sort( new Collator( "fr_FR" ).compare );

trace( text ); // cafe,cafe,cafe

배열의 정렬 메소드인 sort 메소드에 각 Collator의 compare 메소드를 파라미터로 정렬을 하게된다.

이처럼 각 국가별로 다른 언어 체계에 맞춰서 대응할 수 있다.

다음은 화폐 단위에 대한 클래스인 CurrencyFormatter를 살펴보자.

미국은 달러($)를 사용하고 한국은 원(₩)을 사용한다.

이처럼 복잡한 화폐 체계에 대응하기 위한 클래스이다.

국가별 단위를 얻는 방법은 다음과 같다.

import flash.globalization.CurrencyFormatter;

var koreaCurrency: CurrencyFormatter = new CurrencyFormatter( "ko_KR" );
trace( koreaCurrency.currencyISOCode ); // KRW
trace( koreaCurrency.currencySymbol ); // ₩

var usCurrency: CurrencyFormatter = new CurrencyFormatter( "en_US" );
trace( usCurrency.currencyISOCode ); // USD
trace( usCurrency.currencySymbol ); // $

언어별로 화폐 코드와 기호를 나타냅니다.

이번에는 숫자를 화폐단위를 적용하여 출력하는 방법을 알아보자.

CurrencyFormatter의 format 메소드는 정해진 속성들에 따라서 숫자를 출력하는 메소드다.

구분점을 찍어주는 groupingFormat을 이용해서 출력해보자.

import flash.globalization.CurrencyFormatter;

var money: int = 100000000;

var koreaCurrency: CurrencyFormatter = new CurrencyFormatter( "ko_KR" );
koreaCurrency.groupingPattern = "4;*";
trace( koreaCurrency.format( money, true ) ); // ₩1,0000,0000

var usCurrency: CurrencyFormatter = new CurrencyFormatter( "en_US" );
usCurrency.groupingPattern = "3;*";
trace( usCurrency.format( money, true ) ); // $100,000,000.00

실제로 쓰이진 않지만 한국어로 읽기 편하게 한국 화폐단위는 4 자리로, 미국은 3자리로 구분해서 출력한다. format의 두번째 파라미터는 화폐 단위를 붙일 것인지를 결정한다. 여기서 사용되는 패턴은 다음과 같다.

“2;3;*” - 2는 소숫점 구분 후 첫번째 그룹을 지을 갯수, 3은 그 다음 숫자를 그룹지을 갯수, 그리고 *는 나머지 모두에 적용한다는 것을 의미한다.

10000000000 을 예로 들어보자.

“2” - 100000000,00
“2;3” - 100000,000,00
“2;*” - 1,00,00,00,00,00
“2;3;*” - 100,000,000,00

이처럼 Flash Player 10.1에서는 화폐와 언어에 대해서 매우 정밀해졌다. 그 밖에도 날짜를 보다 다양하게 설정할 수 있는 DateTimeFormatter와 숫자를 설정할 수 있는 NumberFormatter가 새롭게 추가되었다.



4. 메모리

이번에 모바일에 최적화에 맞춰 많은 것들이 향상되었는데 그 덕분에 Flash Player에서 이제 메모리에 관련되어 많은 것들을 알 수 있게 되었다.

import flash.system.System;

trace( System.freeMemory ); // 2306048

freeMemory는 Flash Player가 사용할 수 있는 남은 메모리를 말한다.

이는 시스템의 전체 메모리와는 달리 Flash Player에게 할당된 메모리중 아직 사용하지 않은 메모리를 뜻한다.

import flash.system.System;

trace( System.privateMemory ); // 376557568

privateMemory는 브라우저를 포함해 전체 프로세스에 관련된 현재 사용중은 전체 메모리를 말한다.

AIR에서는 애플리케이션이 사용하는 전체 메모리를 이야기한다.

import flash.system.System;

trace( System.totalMemoryNumber ); // 29937664

기존의 totalMemory는 uint속성이기 때문에 4기가 이상의 용량을 표시할 수 없었다.

이번 Flash Player 10.1에서는 totalMemoryNumber 속성이 Number 값으로 반환하여 더 큰 메모리도 파악할 수 있게 되었다.




p.s 1) 이 글은 어도비에 기술문서로 올라가게되면 삭제될 수도 있습니다. (I hope this wouldn't happen.)

p.s 2) "new Sound();"가 아니라 "new Sound;" 라고 해놓것은 오타가 아닙니다. 이는 어도비가 생성자에 파라미터가 필요없을 경우 () 이것을 빼는 것을 권하고 있습니다. 실제로도 "new Sound();" 보다 "new Sound;" 가 객체 생성 시간이 약~간 빠릅니다. :)

+ Recent posts