Tip And Tech2012.02.09 15:12

if
(Capabilities.cpuArchitecture=="ARM") { NativeApplication.nativeApplication.addEventListener(Event.ACTIVATE, handleActivate, false, 0, true); NativeApplication.nativeApplication.addEventListener(Event.DEACTIVATE, handleDeactivate, false, 0, true); NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, handleKeys, false, 0, true); }

Define handlers:

private function handleActivate(event:Event):void
{
	NativeApplication.nativeApplication.systemIdleMode = SystemIdleMode.KEEP_AWAKE;
}
 
private function handleDeactivate(event:Event):void
{
	NativeApplication.nativeApplication.exit();
}
 
private function handleKeys(event:KeyboardEvent):void
{
	if(event.keyCode == Keyboard.BACK)
	NativeApplication.nativeApplication.exit();
}
저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by 정윤수 버터백통
Tip And Tech2012.01.05 13:10

ADT컴파일을 사용하기 위해서는 여러 방법이 있지만 여기서는 윈도우 명령프롬프트를 이용한 방법을 사용한다.
우선 AIR 프로젝트를 만들고 빌드하다보면 자연스레 bin-debug에 swf와 xml등 컴파일에 필요한 파일들이 생성된다.
나는 주로 bin-debug에서 테스트를 하였다.
컴파일 환경 XML파일을 열어 런타임이 3.0 이상인지 확인한다.
<application xmlns="http://ns.adobe.com/air/application/3.1"> XML파일 최상위에 이부분이다.
나의 경우는 3.1을 사용한다.

ADT를 사용하기 위해 기나긴 경로를 모두 적어주어도 좋지만 윈도우 환경 변수로 설정하여 adt명령문을 바로 사용하도록 한다.

컴퓨터 속성에서 고급시스템 설정에 환경변수를 추가한다.


본인의 Flash Builder의 설치 경로에  sdks폴더아래에서 현재 사용하는 SDK의bin폴더를 등록한다. 그러면 어느 경로에서든 접근이 가능해 진다.

작업 중인 프로젝트의 bin-debug폴더로 이동하면 swf와 XXX-app.xml이 있다. xml파일을 열면 <content>노드가 있다.
아마 <content>[This value will be overwritten by Flash Builder in the output app.xml]</content> 이렇게 되어있을 것이다. 값을 같이 있는 swf의 이름으로 변경한다.
예) <content>myApp.swf</content>

이제 컴파일 환경과 재료는 준비 되었다.

실행창에 CMD라고 입력하고 명령프롬프트에 ADT명령문을 입력한다. 프롬프트 위치는 컴파일할 xml과 swf가 있는 곳에서 실행하여야 한다.
adt -package -target apk-captive-runtime -storetype pkcs12 -keystore ../My_cert.p12 myApp.apk myApp-app.xml myApp.swf
참고) http://help.adobe.com/ko_KR/air/build/WS901d38e593cd1bac1e63e3d128cdca935b-8000.html

실행하면 인증서 암호를 입력하라고 한다.
본인의 인증서 암호를 입력하면 완료!! 귀찮으면 -storepass옵션을 AIR_SIGNING_OPTIONS영역에 추가하고 본인의 암호를 적는다.

Ant컴파일러를 사용하여도 좋고 배치파일을 만들어 사용해도 좋다. 나 같은 경우는 배치파일을 만들어 파일명과 옵션만 바꾸어 사용하도록 하였다.

문제1) Could not load keystore file<password may be incorrect> 암호도 맞고 모든게 정산인데 암호가 다르다고 에러가 나는 경우 인증서를 소스폴더에 두지 말고 다른 곳으로 두고 컴파일해 본다. 그래도 안되면 옵션이 잘 못 입력된 것이다.

문제2) Could not generate timestamp: Connection timed out: connect 라며 타임스탬프 서버와의 통신 에러나는 경우 본인의 JRE폴더에 lib폴더에 net.properties파일을 찾아 열어 아래의 항목을 고친다.
java.net.useSystemProxies=false -> java.net.useSystemProxies=true

문제3) 이번 경우가 아닌 AIR컴파일의 경우인데 Could not generate timestamp: handshake alert: unrecognized_name이라고 에러가 나면 -tsa none으로 설정한다.
참고 http://help.adobe.com/ko_KR/air/build/WS5b3ccc516d4fbf351e63e3d118666ade46-7f72.html

이 밖에 ADT 오류 메시지 http://help.adobe.com/ko_KR/air/build/WSBE9908A0-8E3A-4329-8ABD-12F2A19AB5E9.html

저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by 정윤수 버터백통
Tip And Tech2012.01.04 16:39

우선 거지 같은 AIR ADT;;;;

ADT는 콘솔을 사용하여 커맨드 입력을 통해 직접 컴파일하고 컴파일 옵션 등을 설정하여 개발자가 컴파일에 관여하는 것이다.
참고 http://help.adobe.com/ko_KR/air/build/WS5b3ccc516d4fbf351e63e3d118666ade46-7fd9.html

또한 AIR3.0이후 버전에서는 apk-captive-runtime 이라는 옵션을 두어서 AIR런타임을 어플리케이션에 포함시켜 컴파일 할 수 있어 별도로 AIR플레이어를 다운 받도록 하지 않아도 된다.
참고 http://help.adobe.com/ko_KR/air/build/WS901d38e593cd1bac-4f1413de12cd45ccc23-8000.html

ADT는 프로그램 폴더에 설치된 Flash Builder의 sdks안에 사용하는 SDK폴더의 bin폴더 안에 들어있다. 이를 사용하기 위해서는 콘솔을 이용해야 하고 번잡한 작업이 필요하다.

우선 PC전체 경로에서 사용하려면 [컴퓨터]-[속성]-[환경변수]에서 Path 항목에 경로 ADT의 경로를 추가한다.
예) C:\Program Files (x86)\Adobe\Adobe Flash Builder 4.5\sdks\flex_sdk_4.6 with AIR 3.1\bin;
이처럼 설정하면 어느 경로에서든 콘솔에서 adt명령을 실행 할 수 있다. 물론 adt뿐만 아니라 bin폴더 안에 있는 ADL이나 MXMLC등도 전역접근이 가능하다.

오토배치 파일을 만든다면 위의 경로를 처음에 잡아주고 adt명령을 CALL할 수 있겠다.
예)
SET ADT_HOME="C:\Program Files (x86)\Adobe\Adobe Flash Builder 4.5\sdks\flex_sdk_4.6 with AIR 3.1\bin\adt"

CALL %ADT_HOME% -package -target apk-captive-runtime  -storetype pkcs12 -keystore ../codesign.p12  myApp.apk  myApp-app.xml  myApp.swf icons

주의 사항을 살펴보면 아래와 같다.
인증파일은 절대 src또는 코드가 있는 souce폴더에 같이 두면 안된다.
위의 예에서 처럼 한단계 위의 경로에 codesign.p12를 두었다. 또는 평소 관리하는 인증서 폴더에 저장하고 -keystrore의 경로를 설정하여도 된다.

런타임은 최소 2.0이상 이여야 한다.
xml파일의 제일 위에 있는 <application xmlns="http://ns.adobe.com/air/application/3.1">항목을 보면 최소 2.0이여야 한다. 이코드는 3.1버전을 의미한다.
참고 http://help.adobe.com/ko_KR/air/build/WSfffb011ac560372f-5d0f4f25128cc9cd0cb-7ffd.html

아래 경로는 ADT를 이용한 컴파일의 자세한 설명이다.
http://www.petefreitag.com/item/667.cfm

ADT쓰기에 많이 불편하고 리눅스 스럽다;;;; 꽤 비싼 비용을 들여 사용하기엔 상당히 불만족스럽다는 얘기다. 생각컨데 머지않아 이러한 컴파일 옵션들이 Flash Builder에 포함되어서 나오지 않을까 싶다. 
저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by 정윤수 버터백통
Tip And Tech2008.07.13 14:27

SharedObject는 사용자 컴퓨터 공유객체에 저장하는 공간을 만들어 쿠키처럼 호출하여 값을 참조할 수 있도록 한다. 공유객체에 참조자를 만들기 위해서는 반드시 getLocal()를 설정해야 한다. 그리고 swf에서 쿠키처럼 사용할 수 있는 공간 100kb밖에 안된다.

예) 오늘본 상품 등록..
생성시...아래의 메서드를 선언해야 한다.
getLocal : 컴퓨터에 저장
getRemote : 서버를 통해 공유(예: 두 pc가 같이 그림을 그릴수 있다...) 특정 서비스 서버가 있어야한다.



[Public 속성]
client : Object
콜백 메서드가 호출되는 객체를 나타냅니다.

data : Object
[read-only] 객체의 data 속성에 할당된 특성 모음입니다. 이러한 특성은 공유 및 저장이 가능합니다.

defaultObjectEncoding : uint
[static] SWF 파일에서 만들어진 모든 로컬 공유 객체에 대한 기본 객체 인코딩(AMF 버전)입니다.

fps : Number
[write-only] 공유 객체에 대한 클라이언트의 변경이 서버로 전송되는 초당 횟수를 지정합니다.

objectEncoding : uint
이 공유 객체의 객체 인코딩(AMF 버전)입니다.

size : uint
[read-only] 공유 객체의 현재 크기(바이트)입니다.

[Public 메서드]
clear():void
로컬 공유 객체의 경우, 모든 데이터를 제거하고 디스크에서 공유 객체를 삭제합니다.

close():void
원격 공유 객체와 서버 간의 연결을 종료합니다.

connect(myConnection:NetConnection, params:String = null):void
지정된 연결을 통해 서버의 원격 공유 객체에 연결합니다.

flush(minDiskSpace:int = 0):String
로컬 영구 공유 객체를 로컬 파일에 즉시 기록합니다.

getLocal(name:String, localPath:String = null, secure:Boolean = false):SharedObject
[static] 현재 클라이언트에만 사용 가능한 로컬 영구 공유 객체에 대한 참조를 반환합니다.

getRemote(name:String, remotePath:String = null, persistence:Object = false, secure:Boolean = false):SharedObject
[static] Flash Media Server와 같은 서버를 이용하여 여러 클라이언트 간에 공유할 수 있는 객체에 대한 참조를 반환합니다.

send(... arguments):void
메시지를 보낸 클라이언트를 포함하여 지정된 원격 공유 객체에 연결된 모든 클라이언트로 메시지를 브로드캐스트합니다.

setDirty(propertyName:String):void
공유 객체의 속성 값(data 속성으로 정의)이 변경되었음을 서버에 알립니다.

setProperty(propertyName:String, value:Object = null):void
공유 객체의 속성 값(data 속성으로 정의)을 업데이트하고 해당 속성의 값이 변경되었음을 서버에 알립니다.

asyncError
기본 비동기 코드에서 비동기적으로 예외가 발생할 때 전달됩니다.

netStatus
SharedObject 인스턴스가 상태 또는 오류 상황을 보고할 때 전달됩니다.

sync
서버에서 원격 공유 객체(SharedObject)를 업데이트하면 전달됩니다.

아래 코드는 간단히 SharedObject 를 사용하여 방문기록을 표현한 것이다.
private var so: SharedObject = SharedObject.getLocal( "www.xprime.co.kr");

public function SharedObjectTest()
{
   super();
   if( so.data.count == undefined ){
    so.data.count = 1;    
   }else {
    so.data.count ++;
   }
   
   if( so.data.date == undefined ){
    so.data.date = new Date();
   }

   trace( "당신은 "+  so.data.count + " 번 접속했습니다. " , so.data.date.toString()  );
   so.data.date = new Date();
 }


// 출력 : 당신은 3 번 접속했습니다.  Sun Jul 13 14:03:41 GMT+0900 2008

신고
Posted by 정윤수 버터백통
Tip And Tech2008.07.06 15:01
AS3에 또하나의 치명적인 버그가 있다. 많은 분들이 swf파일을 만들어 html에 포함시켰을 때 swf의 마우스 휠을 만들어 사용하면 브라우저창에도 같이 휠이 사용되어 버린다. 즉 swf에 휠스크롤이 있고 브라우저에도 휠스크롤이 있을 때 둘이 동시에 적용된다는 문제가 있다 현재 어도비에서는 아예 브라우저에 스크롤을 막아버렸다..이것은 내부적으로 이러한 문제를 인식하고 있음을 알 수 있으므로 곧 해결방안이 나올 듯 싶다....
현재로서는 이러한 문제가 없는 AS1이나 AS2의 스테이지를 AS3에 불러와 해결하는 방안 밖에는 없다.
this.onMouseWheel = function(){
 }
Mouse.addListener(this)

위와 같이 선언된 swf파일을 만들어 as3프로젝트의 스테이지로 불러와 붙인 다음 실행하면 swf에만 마우스 휠을 사용할 수 있다.

보다 세련되게 하고 싶으면 프로토타입을 만들어 사용하면 된다. 가령 확장자를 xprime등으로 붙인 다음 이를 읽어와 ByteArray를 사용하여 화면에 붙이면 된다. 단 불러올 때 Embed의 속성 중에 mimeType을 "application/octet-stream"으로 설정하여야 한다.
[Embed(source="./assets/MouseWheelEnable.xprime" , mimeType="application/octet-stream") ] private var MouseWheelClass:Class;

var wheel:ByteArray = new MouseWheelClass() as ByteArray;
var ldr:Loader = new Loader()
ldr.loadBytes( wheel );
addChild( ldr );

   

신고
Posted by 정윤수 버터백통
Tip And Tech2008.07.06 14:48

AS3는 기본적으로 국제 표준인 UTF-8을 사용한 인코딩을 하고 있다. 하지만 경우에 따라서 시스템인코깅을 사용해야할 경우가 발생한다. 그럴때는 System.useCodePage를 설정한다.
* 국제 표준을 지키지 않고 현재 시스템의 인코딩을 사용하겠다.
System.useCodePage = true
* 국제표준 인코딩을 사용하겠다.(AS3 프로젝트 기본값)
System.useCodePage = false

그리고 프로젝트를 하다보면 여러단계의 서버를 걸치게 된다. 그때마다 도메인을 수정하기에 번거롭고 더욱 중요한것은 최종 테스트 서버에서 실서버에 오를때는 파일 수정없이 바로 올라가는 경우가 많다. 따라서 xml설정파일을 두어 경로 데이터를 수정하여 올리거나 내부적으로 URLManager에 자신의 도메인을 root.loaderInfo.url 통해얻어와 setter를 설정하여 사용하도록 한다.

신고
Posted by 정윤수 버터백통
Tip And Tech2008.07.06 14:01
swf에서는 flv파일을 재생할 수 있는 Video객체가 존재한다.
flv파일은 스트리밍이 가능한 파일이다 이는 곧 파일의 일부인 패킷(packet)단위의 데이터만 들어와도 재생할 수 있는 것이다.

* 스트리밍(streaming)
스트리밍의 정의는 파일의 일부만 존재하여도 재생 활용 할수 있는 의미를 갖는다.
현재 swf는 반스트리밍 파일이다 이는 root의 프레임단위 스트리밍이기 때문에 프레임에 모션을 담은 무비클립이나 loader를 통한 애니메이션이 존재한다면 재생 중 이를 다 받고 다음프레임의 정보를 다운로드하게 된다.
그렇기 때문에 모션이나 영상 개발시 프레임구조 또한 중요한 차지를 하게 된다. 이를 제외하고 swf에 포함되는 flv만 놓고 보았을 때는 스트리밍을 지원한다. 이때 파일을 제공하는 서버가 FMS가 아니면 progressive방식으로 스트리밍을 한다. progressive방식은 패킷단위로 저장된 정보순으로 재생을 하며 이를 벗어나서는(스킵) 재생할 수 없다. 하지만 FMS에서 제공하는 flv파일 재생은 nonprogressive가 된다.
nonprogressive는 클라이언트에 저장된 패킷(데이타)이 없더라도 가고자 하는 장면(시간)으로 이동 재생할 수 있는 마치 내 컴퓨터에 파일이 존재하는 것 처럼 사용할 수 있다.

참고) 영상(VOD)이나 음원(AOD)처럼 일부 패킷만으로  스트리밍이 가능하여 재생할 수(사용할 수 )있지만 zip , 이미지파일 , hwp , doc등 전체 파일포맷이 다운되어 완성되어 보여져야 하는 파일들은 스트리밍의 개념이 없다. 단 http://www.bytearray.org/에서 제공하는 ASZip같은 경우에는 압축파일이 전송된 양만큼 활용할 수 있다.


아래 그림은 swf에서 flv를 받는 과정을 그려보았다
사용자 삽입 이미지
swf에는 Video라는 객체가 있다. 이 객체는 제공받은 flv파일을 재생하기 위한 viewer인데 제공받기 까지의 과정에 2개의 필수 객체가 필요하다. 우선 어느 서버(경로)로 접근할 때 사용할 길(대역 : 帶域 )인 NetConnection 필요하다. 그리고 이를 관리할 NetStream이 필요하다. 비디오객체에서 필요한 요청을 할 때는 NetStream를 통해서 요청을 하고 NetStream는 NetConnection을 통해 서버에 던진다. 요청받은 일을한 서버는 응답을 NetConnection를 통해 되돌려주고 가만히 앉아서 기다리던 NetStream은 응답이 오자 결과를 자신을 바라 보고 있는 Video객체에 전달하도록 되어있다.

* NetConnection 역할
 - 단순히 서버와의 길을 연결하는 통신선이다

* NetStream(흐름관리자) 역할 
- 자신이 관리할 NetConnection를 정하여 서버에 요청을 하고 응답이 오면 값을 전달하는 객체이다.
- ordering(순서) : 재생 순서(시간)를 지켜서 데이터를 Netconnection을 통해 보내거나 받는다.
- jitter(지터) : 패킷과 패킷사이에 거리(시간차), 거리를 맞추기 위해서 NetStream이 조절한다.

* 비디오 객체
- 흐름을 타고 넘어온 데이터가 최종적으로 화면에 출력하는 객체

위처럼 각 역할을 맡은 객체들이 서로의 역할을 수행하면서 비디오 파일을 가져올 때 해당 파일에 필요한 메타정보를 반드시 가져와야 한다. 가령 비디오파일 확장자를 가지고는 있지만 실제 파일이 이미지나 기타 파일 포맷인지를 재생하기 전에 확인하는 절차가 필요하기 때문이다. 따라서 비디오 객체를 포함하는 클래스에는 public으로 onMetaDataonCuePoint라는 함수를 반드시 만들어 놓아야 한다.

참고) 메타데이타(부가 정보)
- 이미지의 메타데이타는 크게 아래와 같다
  [ 부가정보(이름 , 파일용량 , 가로 , 세로 , 확장자 .. ) ] [ 핵심데이터(블럭) ] [ 핵심데이터(블럭) ]..

- 동영상의 메타데이타도 이미지와 비슷한 정보를 갖는다.
  [ 부가정보(이름 , 파일용량 , 가로 , 세로 , 전체 재생길이 , 코덱...) ] [ 핵심데이터(블럭) ] ....
단 flv만의 부가적 특징이 바로 cuePoint가 있다. 이는 영상 중간 중간에 변수(정보)를 삽입할 수 있다.
따라서 AS3에서는 반드시 onMetaDataonCuePoint를 체크하여야 한다. FMS서버일 때 이러한 cuePoint를 체크하여 서버의 파일의 위치를 찾아가 바로 바로 재생할 수 있도록 하기 위해서 이다.

신고
Posted by 정윤수 버터백통
2008.07.06 11:17

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

Tip And Tech2008.06.25 11:03

과거 AS1에서는 대부분의 클래스가 동적 클래스 이므로  런타임시 변수를 선언하고 값을 줄 수 있었다. 하지만 AS3로 오면서 Object와 Array클래스 MovieClip클래스를 제외한 대부분의 사용가능한 클래스가 동적객체가 아니고 일반 public으로 비동적 객체로 설정되어있다. 따라서 이러한 비동적 객체에 런타임 변수를 설정하고 할때는 Dictionary()클래스를 사용해야한다.

동적 객체는 런타임시 무비클립에 mc.testVar = "변수값" 이라고 변수와 값을 설정할 수 있지만 Sprite등의 비동적 객체에는 런타임 변수설정이 불가능하다.

* AS1처럼 동적 변수 설정(AS3에서도 동적객체이 이와 같이 선언 할 수 있다)
function init():void
{
var man1:Object = new Object()
var man2:Sprite = new Sprite(); 
var man3:MovieClip = new MovieClip();
var man4:Array = new Array()

man1.testVar = "var 1"
man2.testVar = "var 2" -> 비동적 클래스인 Sprite이므로 런타임 변수를 줄 수 없다(에러발생)
man3.testVar = "var 3"
man4.testVar = "var 4"
}

위의 코드처럼 동적 클래스는 Delegate된 인스턴스 네임에 직접 접근하여 따로 속성이 없어도 변수와 값을 설정할 수 있다.
그러나 플렉스에서 사용하는 대부분의 UI기능을 하는 클래스는 Sprite(프레임이 없는 클래스)를 사용한다. 이 Sprite클래스는 비동적 클래스이므로 내부에 public변수나 setter / getter등으로 자리를 컴파일 시 마련해 두어야 한다. 하지만 어떠한 상황에 따라 런타임 변수를 설정해야하는 경우 Dictionary를 이용해야한다.

* Dictionary()
변수명을 Dictionary의 클래스 Delegate로 사용하고 그 안에 참조할 인스턴스 객체를 대입시킵니다.
개념적으로는 사용할 변수를 미리 설정하고 참조대상을 정하면 그 참조대상에 변수와 값을 딕셔너리를 통해 참조할 수 있습니다.. 방식으로 보면 "객체.변수 = 값"과 같은 형태가 아니고 사용할 변수(딕셔너리클래스)를 미리 선언하고 어떤 객체가 쓸 것인가를 정하는 "변수[객체] = 값"으로 사용방법이 조금은 낯설어 보입니다.

var addr:Dictionary = new Dictionary( );
var nick:Dictionary = new Dictionary( );
var age:Dictionary = new Dictionary( );


addr[ man1 ] = "삼성동";
addr[ man2 ] = "청담동";
addr[ man3 ] = "역삼동";
addr[ man4 ] = "갈월동";
   
nick[ man1 ] = "man1"
nick[ man2 ] = "man2"
   
age[ man1 ] = "34";
age[ man2 ] = "36";
age[ man3 ] = "32";
age[ man4 ] = "28";


이처럼  참조할 변수를 Dictionary 클래스로 선언하여 변수의 그룹을 만들어 줍니다.. 가령 "학교, 주소 , 이름 .."등 사용할 변수를 미리 딕셔너리로 설정하고 그 변수를 참고해야할 클래스를 대입시킵니다.
위의 코드에서는 man1~man4는 주소와 나이를 모두 알수있는 dictionary()참조가 있지만 별명은 man1~man2만 보유하고 있습니다.

값의 참조는 addr[ man1 ]과 같이 합니다.
tracce( addr[ man1 ] )              // 출력 : "삼성동"

for(var i:int=1; i<=4; i++ ){
    trace(addr[ this["man"+i] ])    //출력 : "삼성동"  "청담동"  "역삼동"  "갈월동"

 }

* Dictionary() 클래스를 생성시 생성자 파라미터가 weakKeys라는 부울변수가 있다,
  이는 weak reference의 성분을 설정하여 가비지 컬렉터의 대상여부를 설정합니다.

신고
Posted by 정윤수 버터백통
Tip And Tech2008.06.24 12:15

*** 가비지 컬렉터 관련 이전내용을 아래 내용으로 업데이트 하였습니다. ***

현재는 디버거와 AIR프로젝트에서만 gc가 실행되고있습니다. 따라서 저를 포함한 많은 분들이 소위 낚였습니다. 자~알 실행되는 줄알고...하지만 일반 플레이어에서는 아무리 gc()를 실행하여도 메모리는 꿈쩍도 하지 않습니다.

많은 고민과 연구를 거듭한 결과 출처불명의 로컬커넥션을 이용한 방법이 있다고 들었고 시행착오와 명용이의 자문을 구해 테스트한 결과 정말 gc()가 실행되더랍니다..

로컬커넥션은 메모리에 통신이 가능한 주소지를 설정하여 이곳을 통해 send객체와 이를 바라보는 connect객체를 통해 서로다른 swf간 통신을 하게하는것입니다.
주소지의 등록은 connect("이름")을 통해 주소지를 등록하는데, 메모리에 같은 주소지를 두번 호출(할당)하게 되면 그때 에러를 발생하면서 시스템의 가비지 컬렉션이 실행하게 됩니다. 따라서 try~catch문을 사용하여 무비가 먹통이 되는것을 방지하여야 합니다.



이 파일을 디버거가 아닌 플레이어 실행결과 System.gc();는 실행되지 않고 LC에 의한 메모리 감소를 확인하였습니다.

var before:String = tmp.currencyFormat( System.totalMemory , {  group:"," , decimal:"." ,
                                                                                          currency:"" , before : false } );

try {
          new LocalConnection().connect('myConnection');
          new LocalConnection().connect('myConnection');
} catch (error:ArgumentError) {
          trace("이미 연결되어있다");
}

var after:String = tmp.currencyFormat( System.totalMemory , {  group:"," , decimal:"." ,  
                                                                                        currency:"" , before : false } );

memory.text = "before :" + before + ",  after :" + after;


테스트 코어부분입니다...테스트를 위해 설정하는 코딩이 너무 많아서 생략하고 실제 LC를 통한 가비지 컬렉터를 실행하는 부분입니다.


* 중요 참고 
gc()에 의해 제거 될수 있는 대상은 사용이 끝난 불필요한 말그대로 쓰레기를 회수합니다. 따라서 제거하고자 하는 대상은 화면에 붙어있다면 지워진 상태이며 이름은 null이고 addEventListener를 통해 바라보고 있는 객체가 있으면 안됩니다...지우거나 null까지는 어떻게 해보겠지만 다른클래스에 있는 리스너까지 손보려면 좀 성가시죠....따라서 addEventListener의 useWeakReference를 활용합니다.

* addEventListener 이외에도 Dictionary클래스에도  WeakReference를 제공합니다. 가비지 컬렉션 시스템에서는 WeakReference(약한 참조)를 무시하므로, WeakReference만 있는 객체는 가비지 컬렉션의 대상이 됩니다.
신고
Posted by 정윤수 버터백통
Tip And Tech2008.06.07 20:09
AS3에는 외부 파일이나 데이타에 접근하기 위해 URLLoader와 URLRequest ,Loader클래스를 사용한다.
우선 네트워크 다이어그램을 보면 그림과 같다.
사용자 삽입 이미지
그림을 보면 swf가 서버에 Request(요청)한다. 그러면 서버는 필요한 응답을 하게된다. 중요한 것은 swf가 요청할 때 이다. Request클래스는 swf에서 서버로 요청하기 위해 사용되는 클래스이다.
다만 무엇이 요청하느냐에 따라 요청하는 마스터 클래스를 선택해야 한다.

1 URLLoader
URLLoader클래스는 문자형 데이터(XML이나 파라미터.. 등), 2진데이터(바이너리 데이터 , zip...)등을 처리하기 위해 사용한다.
참고로 AS1같은 경우에 이와 비슷한 역할을 하는 것이 바로 "경로.loadVariables("url 경로")"이다.

2 Loader
Loader클래스는 주로 화면에 보여지는 이미지나 swf등의 파일을 담는 역할을 한다. 이것 역시AS1에 있는
경로.loadMovie("url 경로")와 같은 것이라고 생각하면 된다.

3 URLRequest
서버와 통신시 필요한 파라미터나 메소드(GET , POST)방식을 설정하여 서버에 전달하는 객체이다.
이 객체는 loadVariables("url")이나 loadMovie("url")에서 필요한 "url"을 담당하는 객체이다.
따라서 이 URLRequest()는 서버와의 통신이 필수인 객체이다.

가령 불러올 데이터가 파라미터나 2진 데이터이면 URLLoader()클래스를 사용하고 그래픽 적인 요소를 불러올 것이면 Loader() 클래스를 사용한다. 이 두 객체가 외부와의 통신을 시도하려면 URLRequest()를 필수로 사용하게 된다. 이 두개의 클래스는 모두 load()라는 메서드를 가지고 있다. 이부분에 URLRequest()를 인자로 넣어서 사용하면 된다.

 private var loader:Loader = new Loader();
 private  var request:URLRequest = new URLRequest("./imgs/sample.jpg");
 loader.load(request);
 loader.contentLoaderInfo.addEventListener( Event.COMPLETE , onComp )

 private function onComp( e:Event ):void
{
    addChild( loader )
}

위의 코드는 Loader클래스에 sample.jpg라는 이미지를 불러들여 이를 addChild()하는 코드이다.



신고
Posted by 정윤수 버터백통
Tip And Tech2008.06.07 12:07

AS3에는 Event클래스나 MouseEvent클래스 KeyBoardEvent , FocusEvent등 다양한 이벤트들은 제공하여 준다, 이 이벤트 클래스를 활용하여 보기 좋게 이벤트 이름을 설정하거나 필요한 값을 이벤트에 실어서 보낼수 있게 만들어 보자.

가령 섬네일을 눌렀을 때 섬네일은 버튼이며 마우스 이벤트를 사용하면 된다.
thumb.addEventListener( MouseEvent.MOUSE_DOWN , onSelect )

function onSelect(  event:MouseEvent ):void
{
        섬네일을 눌렀을 때 할일...
}


그러면 해당되는 이미지가 커다란 다른 View Pannel에서 크게 보여진다고 하자. 이 때 섬네일에서 필요한 최소의 정보는 커다란 사진의 경로를 View Pannel에게 알려주는 것이다.
function onSelect(  event:MouseEvent ):void
{
        dispatchEvent( 발생시킬 이벤트 )
}

그러나 어도비에서 만들어준 기본 이벤트에는 view Pannel에게 알려줄 사진경로의 정보를 포함시켜서 이벤트를 발생시킬 수 없다... 따라서 우리는 나름대로의 이벤트를 만들어서 그안에 정보를 담아 보내주도록 한다.
아래와 같이 Event를 상속받아서 기능을 추가한다. 추가되는 기능은 photoURL라는 파라미터를 만들어서 이벤트가 발생할 때 그 값을 받아 넘겨주도록 하는 것이다.
package
{
import flash.events.Event;
public class SelectEvent extends Event
 {
  public static const Select:String = "select";
  public var photoURL:String;
 
public function SelectEvent ( photoURL:String , type:String, bubbles:Boolean=false, cancelable:Boolean=false )
  {
   super( type, bubbles, cancelable );
   this.photoURL= photoURL;
  }
 
  override public function clone() : Event
  {
   return new UserEvent(this.photoURL, this.type, this.bubbles, this.cancelable);
  }
 }
}

위의 SelectEvent를 섬네일에서 dispatch 하면 아래와 같이 코딩한다.
private var bigSizeURL:String = "큰사진의 URL경로"
function onSelect(  event:MouseEvent ):void
{
        dispatchEvent( new SelectEvent(this.bigSizeURL,"select") )
       //SelectEvent에
photoURL의 값을 자신의 bigSizeURL로 설정
}

이처럼 섬네일에서만 알고있는 자신의 큰사진경로를 이벤트 발생시 이벤트의 파라미터로 등록하고 발송한다.
viewPannel에서는 사진을 불러들여야 하므로 다음과 같이 리스너가 등록되어있을 것이다.
thumbList.addEventListener.(SelectEvent.Select , onLoadPhoto)
function onLoadPhoto( event:SelectEvent ):void
{
      var photoUrl : String = event.photoURL;//SelectEvent에 포함되어있는 파라미터
      이미지를 photoUrl 에서 불러오는 코드....
}

위처럼 viewPannel에서는 섬네일 목록을 SelectEvent로 보고있다가 이벤트가 발생하면 섬네일에서 넘겨주는
url정보를 바탕으로 큰 사진의 이미지를 불러오도록 하는것이다.
중요한 것은 이벤트도 클래스이며 이를 상속받아 기능추가하거나 재정의가 가능하여 필요에 맞게 고쳐서 사용하면 되는 것이다.





신고
Posted by 정윤수 버터백통
Tip And Tech2008.06.07 11:38

예전에 언어코드를 설계할 때 지금처럼 다양한 국가나 특수 문자 등의 설계가 포함되지 않았었다.
그래서 8비트의 아스키코드(ASCII : American Standard Code for Information Interchange)에서
확장된 16비트의 유니코드(Unicode)가 만들어지게 되었다.
하지만 아스키 방식은 문자당 1바이트를 사용하는데 반해 유니코드는 2바이트를 사용하게 되었다.
따라서 이러한 크기를 줄이기 위해 만들어진 것이 utf-8이다.
이 UTF-8은 아스키 코드의 영문이나 숫자등은 1바이트 형태로 표현하고 기타 국가언어는 2바이트 형태로
아스키와 유니코드를 혼용한 표현방식이 된 것이다.

신고
Posted by 정윤수 버터백통
Tip And Tech2008.06.01 14:46

플래시에서는 메인무비 클래스가 자동으로 document 클래스이며 무비를 설정할 수 있다.

사용자 삽입 이미지

위의 그림처럼 문서속성을 갖는 속성창에서 무비의 크기나 배경색 fps등을 설정하지만 플렉스는 메타테그를 사용하여 코딩하여야 한다. 이는 메인 클래스를 어떤 것으로 설정 하느냐에 따라 달라지기 때문이다.

가령 Sprite클래스를 상속받은 Main이라는 클래스를 메인 클래스로 사용하였다고 하자. 이는 플렉스에서 액션스크립트 프로젝트로 설정하였을 때 설정한다.
* 참고 : 플렉스 빌더에는 여러가지 프로젝트를 지원한다. 각각에 따라 실행되는 결과문의 형태나 설정, 메인 클래스의 종류(as/mxml)등으로 나누어 질 수 있다.. 또는 ant같은 플러그인을 사용하여 컴파일도 가능하다.

이것을 메인 클래스로 잡았다고 하여보자
package {
 import flash.display.Sprite;
 public class YS_TEST086_AS_Project extends Sprite
 {
  public function YS_TEST086_AS_Project()
  {
   trace("이것이 메인클래스다")
  }
 }
}
이것을 컴파일 하기 위해서는 이 파일을 소스코드 루트에 있어야 하며 상태는
Default Application으로 설정되어있어야 한다. 설정되면 앞에 동그란 아이콘이 붙는다
사용자 삽입 이미지






이러한 메인 클래스는 무비의 크기나 색상 또는 재생속도등을 정의하여야 한다...
[SWF(width="550", height="400", frameRate="30", backgroundColor="0x000000")]
위와 같이 무비의 폭과 높이 재생속도 배경색등을 정의하여 메인 클래스의 클래스 위에 선언한다
package {
 import flash.display.Sprite;
 
 [SWF(width="550", height="400", frameRate="30", backgroundColor="0x000000")]
 public class YS_TEST086_AS_Project extends Sprite
 {
  public function YS_TEST086_AS_Project()
  {
   trace("이것이 메인클래스다")
    var a :AA = new AA()
  }
 }
}

이처럼 액션스크립트 프로젝트인 경우에는 SWF태그를 만들어 포함시켜야 하고
플렉스 프로젝트인 경우에는 mxml이 메인 레퍼가 된다. 이곳을 보면 Application 태그에 환경을 설정하면 된다.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="최초실행할 함수()" width="550" height="400" backgroundColor="0x000000">
등과 같이 설정하여 무비의 상태를 설정한다.

* 참고 : 플렉스에서 메인 클래스(documaent 클래스)는 자동으로 display list에 등록된다.


신고
Posted by 정윤수 버터백통
TAG Flex
Tip And Tech2008.06.01 13:24
Action scipt 3.0 CookBook
플래시나 플렉스 코어개발을 위해서는 액션스크립트는 필수이다

리팩토링
지금까지 진행하는 프로젝트의 구조에 관한 관찰과 고민등 개선점을 찾아보자

디자인 패턴
이제는 대규모 개발에 주로 활용되기 때문에 구조에 대한 고민을 더욱 많이 하여야 한다
클래스와 메서드에 익숙해지면 구조를 공부하여 보자

누워서 읽는 알고리즘
보다 짧고 명료한 실행 결과를 얻기 위한 노력!!

the art of computer (알고리즘 편)
그래 조금더 알고리즘을 연구하여 보자!!

이외에도 주옥같은 책이 많지만 가장 유명하고 대표적인 책 몇권만 적어 보았습니다~
신고
Posted by 정윤수 버터백통
Tip And Tech2008.05.16 17:43
자바에서 JVM처럼 플렉스/플래시cs3는 AVM2라는 기반위에서 작동한다.
as1,as2는 AVM1에서 구동되고 as3는 AVM2에서 구동되어지며 대부분의 컴퍼넌트와
라이브러리를 내장하고 있기 때문에 실제 개발에 필요한 소스나 용량부분을 어느정도 플러그인단에서
해결할 수 있다고 생각한다.


우선 AVM구동시 우리의 컴퓨트는 4가지의 메모리를 할당하게 된다.
1) 스택영역(runtime stack) : 프로젝트를 실행시 사용하는 영역으로, 메모리를 이용하여 CPU에 의해 직접 관리되는 스택이다. 이는 함수를 호출하고 리턴하는데 있어서 필수적인 메커니즘이다. 런타임 스택은 항상 ESP(Extended Stack Pointer)레지스터를 이용하여 top을 가리키게 된다. 우리는 보통 스택의 개념을 설명할때 '쌓음'의 원리를 이용하여 아래서부터 위로 쌓여가는 것으로 설명하곤 한다. 하지만 IA-32아키텍쳐에서 스택은 아래로 자란다. 즉, 스택을 거꾸로 뒤집어 놓은 것이다.


<그림 1 : push동작>


2) 힙영역(garbage collection heap) : 동적 메모리 할당하는 영역으로 프로그래머가 개발시 변수등을 통하여 메모리 공간을 할당,소멸하는 영역이다. 이부분은 gc의 대상이 되어지고 system.gc실행시에 연결이 끊어진 변수나 객체는 메모리에서 제거된다.

3) 상수영역(constant & code segment) : 정적영역으로 static, const등을 할당하는 공간으로 값의 수정이나 제거가 불가능 하다.

4) 레지스터 영역 : 프로세서 실행 관련 메모리할당부분으로 CPU 안에 있는 고속 저장 장소이며 일반 메모리보다 훨씬 빠른 속도로 접근되도록 설계되었다. 레지스터의 종류로는 8개의 범용 레지스터와 6개의 세그먼트 레지스터, 프로레서 상태 플래그 레지스터(EFLAGS)와 명령어 포인터(EIP)가 있다.

사용자 삽입 이미지


 범용 레지스터(General-Purpose Register) : 범용 레지스터는 계산과 데이터 전송에 주로 사용된다. 다음 그림에서 보듯이 각 레지스터는 하나의 32비트 값이나 두 개의 16비트 값으로 다룰 수 있다. 16비트 값은 다시 2개의 8비트 값으로 다룰 수 있다.

사용자 삽입 이미지

32비트 값이 16비트와 8비트 값으로 각각 구분될 수 있는 레지스터는 다음과 같다.

사용자 삽입 이미지

나머지 범용 레지스터는 하위 16비트에 대해서만 특정한 이름을 갖는다.

사용자 삽입 이미지


*용도(Uses)
-EAX(Accumulator Register) :
  전송 및 연산에 사용. 곱셈과 나눗셈 명령어에 자동적으로 사용됨.

-EBX(Base Register) : 
  전송 및 연산에 사용. 번지의 간접 지정에 사용할 수도 있음.

-ECX(Count Register) : 
  전송 및 연산에 사용. 루프 카운터로 사용

-EDX(Data Register) : 
  전송 및 연산에 사용. 일부 연산 명령에 있어서 EAX와 함께 사용.

-ESI(Source Index) : 
  고속 메모리 전송 명령어에서 사용. 번지의 간접 지정에 사용. 스트링 명령에 있어서, 메모리로부터 레지스터로 데이터를 전송하기 위한 소스 번지의 지정에 사용.

-EDI(Destination Index) : 
  고속 메모리 전송 명령어에서 사용. 번지의 간접 지정에 사용. 스트링 명령에 있어서, 레지스터로부터 메모리에 데이트를 전송하기 위한 수신되는 목적번지를 지정할 때 사용.

-EBP(Base Pointer) :
  일반적인 계산과 데이터 전송에 사용되지 말아야 함. 스택상의 데이터 번지를 간접 지정할 때 사용. 함수 매개 변수와 지역 변수를 참조하기 위해 사용.

-ESP(Stack Pointer) : 
  보통의 계산과 데이터 전송에는 거의 사용되지 않음. 스텍의 최신 데이터가 저장되는 번지를 나타냄.


세그먼트 레지스터(Segment Register) : 실제 모드에서 세그먼트 레지스터는 세그먼트(Segment)라고 하는 미리 할당된 메모리 영역의 시작주소를 가리킨다. 보호 모드에서 세그먼트 레지스터는 세그먼트 서술자 테이블에 대한 포인터를 갖는다. 몇몇 세그먼트는 프로그램 명령어(코드)를 저장하고 다른 세그먼트들은 변수(데이터)를 저장하고 스텍 세그먼트(Stack Segment)라고 하는 또 다른 세그먼트는 함수의 지역 변수와 함수 매개변수를 저장한다.
CS(Code Segment) : 프로그램의 실행 명령어들이 내장되는 메모리 영역의 시작위치를 보관
SS(Stack Segment) : 스택으로 사용되는 메모리 영역의 시작위치를 보관
DS(Data Segment)  : 데이터가 저장되는 메모리 영역의 시작위치를 보관
ES(Extra Segment)  : 변수들을 위한 추가 메모리 영역의 시작위츠를 보관
FS :
GS :

명령어 포인터(EIP : Extended Instruction Pointer) : 실행항 다음 명령어의 주소를 포함
[출처] 1. 레지스터(Register)|작성자 파란바다



tip) 함수의 동작 원리
스택(stack)이라는 자료구조를 이용해 함수 호출이 가능하다는 것을 이야기 하고 싶을 뿐이다. 함수를 호출하게 되면 제어가 그 곳으로 넘어가야 하니까, 이전의 인스트럭션 포인터(EIP)레지스터를 어딘가에 저장시켜놨다가 나중에 다시 불러와야 할 것이다. 그런데 함수 여러개가 중첩되어 호출되었다면, 인스트럭션 포인터를 저장하는 자료구조는 가장 나중에 들어간 자료가 가장 먼저 나와야 올바르게 수행될 것이다. 즉, LIFO(Last-In, First-Out)여야 한다. 그렇다면 스택을 사용하여야 한다는 것은 두말할 필요도 없을 것이다.
개념이 비슷할 뿐 어셈블리어에서는 프로시져(Procedure)라고 한다.

tip) 레지스터 영역과 램영역
램과 레지스터 영역의 연산 속도의 차이는 수십~수백배의 차이가 발생한다.

* 화면에 보이기까지 과정
1 유니코드(utf-8)로 제작된 소스 : 우리가 신나게 개발하는 소스코드, *.as
2 컴파일(바이트코드로 변환) : 컴파일을 하면 바이트코드 형태인 swf파일로 변환한다.
3 .swf(반기계어)
4 인터프리터(JVM또는 AVM) : swf의 바이트 코드를 해석하기 위한 장치또는 플러그인/플레이어
5 실행결과



신고
Posted by 정윤수 버터백통
Tip And Tech2008.05.16 16:53
* 인풋텍스트필드.restrict = "0.123" // "a-z" : 지정된 특정 문자만 입력가능

* stage.focus = 대상입력텍스트필드 //결과 커서입력(캐럿)이 해당 필드에서 깜빡인다

* focus : 객체를 포커싱하는 방법
  as2: Selection.setFocus(객체) --> as3 : stage.focus=객체(최소한 인터레티브오브젝트를 상속받은 객체여야 한다)

* 입력텍스트 이벤트 프로세스
텍스트필드를 선택한 상태에서 키보드를 누르면...
1 KeyboardEvent.KeyDown
2 TextEvent.TEXT_INPUT-> 텍스트 필드에 입력된 텍스트 표시
3 KeyboardEvent.KEY_UP

TextEvent.TEXT_INPUT은
1 기본적으로 해당 텍스트 필드에서 넘어온 값을 표시하는 함수를 갖는다.
2 커서를 텍스트 맨뒤로 이동시킨다.

* event.preventDefault : 이벤트실행(behavior)을 막는다...

* appendText -> txt.text += "내용"
메서드는 추가 할당(+=)을 text 속성(예: someTextField.text += moreText)에
하는 것보다 효율적입니다.

* 글자입력 코드를 아스키로 분석하여 변환
String.formCharCode(e.text.charCodeAt(0) + 3)
입력된 클자보다 3이후의 값을 가진 문자를 반환


* tabIndex : 순차적으로 번호를 부여하여 순차적으로 포커스를 바꾸어 준다.

* FocusEvent.FOCUS_IN / FocusEvent.FOCUS_OUT : 포커스에 반응하는 이벤트

* as3에서는 비밀번호 ( * )를 하기위한 메서드 : 텍스트필드.displayAsPassword = true;

* 텍스트필드 마키
-키메서드
 텍스트필드.scrollH += 5 : 내용이 가로로 이동한다.
 텍스트필드.maxScrollH : 입력된 내용에 따른 스크롤 최대값을 산출

* 텍스트 포맷 적용
 텍스트필드.setTextFormat(tf) : 지금현재 텍스트 필드의 특성을 텍스트 포맷(tf)으로 설정(한번만)
 텍스트필드.defaultTextFormat = tf : 앞으로 텍스트필드에 텍스트형태를 tf으로 계속 설정

신고
Posted by 정윤수 버터백통
Tip And Tech2008.05.16 15:39

MovieClip -> Sprite -> DisplayObjectContainer -> InteractiveObject -> DisplayObject -> EventDispatcher -> Object

-Object : 모든 클래스는 오브젝트를 상속받는다....(상속 : 부모의 기능을 모두 가지는 것)

-EventDispatcher : 듣고 말하기가 가능
  - addEventListener()
  - removeeventListener()
  - dispatchEvent()

-DisplayObject : 눈에 보이는 객체(사용자반응 없다 )
  :일반 속성(x , y, rotation ...)
  parent{Shape , Graphics , bitmap}

-interactiveObject : 텍스트필드 , 심플버튼 ,
  마우스 이벤트 , 키보드 이벤트 , 포커스이벤트

- DisplayObjectContainer: 디스플레이 오브젝트를 담을수 있는 클래스
  :Child , index(자식들의 z-order : 자동관리)
  :addChild , addChildAt , removeChild() , removeChildAt ,
  :getChildAt , getChildAt , numChildren , contains(포함여부)

  => sprite , Stage , Loager로 상속

- Sprite : 프레임이 없는 무비클립

- MovieClip : 일반적인 무비클립[Embed시에 최소2프레임이상 되어야 MovieClip클래스로 캐스팅가능]

신고
Posted by 정윤수 버터백통
Tip And Tech2008.05.13 15:04

FLEX 그리고 AJAX

 

웹 2.0이 화두인 이 시기에 가장 주목받는 기술이 아닐까 싶다.


화려한 GUI와 더불어 페이지 전환없이 비동기적으로 서버와 데이터를 주고받을수 있다는 점에서 RIA개발에 많이 쓰이고 있다.


AJAX와 FLEX의 차이점은 단순하다.


AJAX가 자바스크립트를 사용하는데 반해서 FLEX는 기존 Flash 에서 사용하던 ActionScript와 MXML이라는 xml기반의 언어를 사용한다.


이를 제외하면, 서버와 비동기 통신을 하며 xml을 사용해 데이터를 주고 받는 다는 점에서는 기본적인 원리는 동일하다.


FLEX의 장점


하지만 AJAX과 비교했을때 FLEX는 분명한 우위를 점하고 있는 부분이 있다.


매크로 미디어가 어도비에 합병되고 나서 발표된 플래시 플레이어9 버전에서는, 기존에 어도비가 가지고 있던 이미지 처리 능력이 비약적으로 향상됨을 보여준다.


포토샵의 비트맵 기술이 플래시와 접목되면서 한층 더 확장성있는 구현이 가능해졌으며, 각종 필터를 제공함으로써 플래시로 제작된 어플리케이션에 화려한 효과를 줄 수 있게되었다.


이러한 플래시 기반의 화려한 그래픽 API를 그대로 FLEX에서도 쓸 수 있다는 점은 FLEX만이 가진 큰 장점이다.


거기에다가 FLEX Builder를 사용하면 FLEX어플리케이션을 간단하게 마우스로 구현할 수 있다는 점에서 생산성도 확보할 수가 있다.


html페이지를 드림위버를 사용해서 직접 html을 작성하지 않고 만드는 것처럼, FLEX에서 제공하는 각종 컴포넌트들을 드래그앤드롭을 통해 쉽게 화면에 구성할 수 있다.


FLEX의 배경

 

사실상 어도비는 벼랑 끝에 내 몰린 심정으로 FLEX를 개발했다.


플래시 어플리케이션이 웹에서 돌아가기 위해서는 플래시 무비파일인 swf파일로 컴파일이 되어야하는데, 애초에는 자사의 제품으로만 swf파일을 만들 수 있었다.


그러나 최근들어 오픈소스 프로젝트에서 무료 컴파일러들이 등장하면서 기술을 독점할 수 없는 상황에 이르렀기 때문에 새로운 수익모델이 필요해진 상황에 몰린것이다.


거기에다가 윈도우 비스타가 새로운 사용자경험(UX)을 제공하겠다며 맹추격 해오는 탓에 기존에 플래시가 확보하고 있던 RIA시장마저 빼앗길 처지에 달했다.


이러한 이유로 어도비사는 FLEX의 sdk와 Framework를 무료로 제공하게 되었으며, 자바 개발자를 끌어들이기 위한 이유로 자바 프로그래머들에게 익숙한 이클립스 기반의 FLEX Builder를 비교적 싼값에 배포하고, 이클립스 플러그인도 제공하고있다.


FLEX 와 Blend

 

2007년 마이크로 소프트는 닷넷 프레임워크 3.0과 함께 새로운 툴들을 발표하고 있다.


코드병 'Avalon'으로 알려진 WPF(Window Presentation Foundation)와 함께 다음과 같은 지원 툴을 발표했다.


Microsoft Expression Design.

Microsoft Expression Blend.

Microsoft Expression Media.

Microsoft Expression Web.


제목으로 미루어 보아도 알 수 있겠지만 기존에 어도비가 가지고 있던 대표 제품과의 정면 충돌이 예상된다.


포토샵과 일러스트레이터를 겨냥한 'Microsoft Expression Design'은 기존에 어도비제품군과 완벽하게 호환되기때문에 포토샵과 일러스트레이터에서 사용하던 파일뿐만아니라 PDF 파일까지 읽어 들일 수 있다.


이렇게 읽어 들인 파일들을 재구성해서 XAML이라는 파일 형식으로 export할 수 있는데 이는 플래시기반의 MXML과 같이 객체를 태그로 표현할 수 있도록 한다.


이렇게 저장된 파일은 'Microsoft Expression Blend'에서 불러와서 폼을 작성하거나 효과를 적용할 수 있다. 이 툴은 타임라인 기반의 애니메이션을 적용할 수 있으며, 각 객체에 효과를 주고 이벤트 연계를 하는등 FLEX와 유사한 기능을 하는 툴이다.


블렌드(Microsoft Expression Blend)는 플래시와는 달리 실행파일을 직접 만들어서 실행하게되는데, 이는 C#이나 VB.NET프로젝트 처럼 다루어지며 닷넷 프레임워크 3.0에서 제공하는 풍부한 기능을 사용할 수 있다.


이는 많이 발전했다고는하나 상대적으로 빈약한 언어적 기반을 가진 액션스크립트에게는 매우 취약한 부분이 될 수 있다.


이밖에도 'Microsoft Expression Media'와 'Microsoft Expression Web'역시 XAML이라는 공통 언어를 사용해서 익스프레션의 다른 모든 제품과 데이터를 교환 할 수 있다.


이러한 호환성은 FLEX가 가지지 못한 부분이기때문에 FLEX가 기술적인 경쟁력을 확보하는데 걸림돌이 될 여지가 있다.


JAVA VS .NET

 

자바 프로그래머들에게 있어서 FLEX는 RIA를 구현하는데 있어서 가장 쉽게 접근할 수 있는 툴이다.


FLEX에서는 FDS(Flex Data Service)를 통해 자바와의 리모팅을 지원하고 있는데, 이는 자바에서 사용하는 객체를 바로 FLEX에서 사용할 수 있게 해주며, 쌍방향 통신을 지원한다.


상대적으로 닷넷 진영에 비해 빈약한 그래픽 API를 가지고 있는 자바진영에서는 FLEX를 사용해서 이를 보완할 수 있을것이다.


더불어서 'FLEX Builder'는 이클립스 기반으로 개발되었기 때문에 자바프로그래머에게는 매우 익숙하다 할 수 있다.


앞으로의 RIA시장은 FLEX를 사용해 GUI를 보강한 JAVA진영과 익스프레션제품군을 필두로 한 닷넷진영이 벌이는 전쟁터가 될 가능성이 크다.


결론


기존의 RIA시장은 플래시를 사용한 어플리케이션이 주를 이루었다.


하지만 플래시는 분명 프로그래머를 위한 툴은 아니다.


당초 개발 목적이 웹에서 애니매이션을 보여주기 위함이었기 때문에 IDE의 액션 스크립트 편집창은 정말이지 형편없었다.


더욱이 반쪽짜리 객체지향언어인 액션스크립트 2.0은 사실상 대규모 어플리케이션을 제작하기에는 무리가 있었다.


반면에 FLEX는 컴파일된 결과가 똑같이 플래시 플레이어 위에서 돌아가기는 하나, 분명히 대규모 어플리케이션을 작성하기에도 무리가 없을만큼 잘 짜여진 구성이다. 마치 자바를 보는 듯 하다.


액션스크립트가 버전 3.0으로 넘어오면서 부터는 완전한 객체지향 언어라고 해도 무리가 없을 정도이며, 쉽게 컴포넌트를 확장하거나 재구성할 수 있는 방법을 제공한다.


하지만 FLEX역시 GUI를 구성하기 위한 툴 이상은 아니다.


데이터를 읽어오기위해서는 다른 언어의 도움을 빌려야하기 때문에 FLEX만 가지고는 아무것도 할 수 없다고 해도 과언이 아니다.


앞으로 FLEX를 공부하는데 있어서는 조금더 넓은 시야를 가지는 것이 필요하다고 생각한다.


어도비에서는 AJAX와 연동할 수 있는 API를 제공하기 시작했으며, FLEX와 닷넷을 리모팅하기 위한 오픈소스 프로젝트도 진행되고 있다. 구글 파이낸스는 FLEX와 AJAX를 적절히 혼합하여 사용한 좋은 예이다.


FLEX는 조금더 쉽고 화려하게 뷰를 구성할 수 있는 툴일 뿐이기 때문에, 그밖에 다른 부분에 관한 지식이 요구된다.


중요한 로직은 어차피 서버단에서 구성되어야 하기때문에 자바나 닷넷같은 서버사이드 언어를 공부해야 함과 동시에 FLEX의 컴포넌트를 확장해서 사용하기 위해서는 OOP를 넘어 CBD에 대한 개념도 숙지해야한다.


더불어서 지금까지 설명한 기술적인 부분에 대한 이해 뿐만아니라, 웹기술에 관한 트렌드와 철학에 대한 접근도 요구된다고 생각한다.

신고
Posted by 정윤수 버터백통
Tip And Tech2008.05.13 15:03

임베드된 폰트를 공유심볼로 사용할 일이 생겼는데 잘 안 되어서 무척 삽질했었습니다.

이렇게 정리를 안해 놓으면 다음에 또 기억이 나지 않아 반복적으로 시간을 낭비하게 되어 나름 정리 하였습니다.

삽질하면서 한 거라 정확한 방법인지는 모르겠으나 혹 필요하신 분들을 위해 공유합니다.

 

1. font.fla 제작하기

- font 정보를 담아 공유 할 파일을 제작 할 것이다. 먼저 새 문서를 생성 후 font.fla로 저장한다.

- Library 우클릭 -> New Font..을 클릭한다.

- 이름과 해당 글꼴 속성을 세팅하고 ok를 누른다.

- Library에 생성된 Font를 우클릭하여 Linkage Properties를 선택한다.

- 창이 뜨면 Linkage 항목 중 Export for runtime sharing과 Export in first frame을 체크한 후

   Identifier를 입력 (디폴트로 폰트 심볼 제작시 사용한 이름이 들어간다, 그냥 나둬도 된다,

   나중에 공유 시 식별은 이름이 아닌 Identifier로 구분된다) 후   

   URL 항목에 자신의 퍼블리쉬 되는 swf 이름을 입력한다. (font.fla이므로 font.swf를 입력)

   OK클릭

- Library 우클릭 -> New Symbol..을 클릭하여 빈 무비클립을 만든다. (이름은 자유롭게, 이 예제에서는 font라고 입력했다)

- Library에 생성된 font 무비클립을 우클릭하여 Linkage..을 선택한다.

- 창이 뜨면 Linkage 항목 중 Export for runtime sharing을 체크한 후(Export in first frame은 디폴트로 체크되는데 하고 안하고의 차이를 못 찾겠다)

   Identifier를 입력 (디폴트로 심볼 제작시 사용한 이름이 들어간다, 그냥 나둬도 된다) 후   

   URL 항목에 자신의 퍼블리쉬 되는 swf 이름을 입력한다. (font.fla이므로 font.swf를 입력)

- Stage에 font 무비클립을 드래그한다.

- swf문서를 publish한다.


2. test.fla 제작하기(임베드 된 글꼴을 사용할 파일)

- 공유된 폰트swf 파일을 가져와 사용할 파일을 제작 할 것이다. 먼저 새 문서를 생성 후 test.fla로 저장한다.

- font.fla의 Library를 열어 font 무비클립을 test.fla의 Stage에 Drag한다.

- test.fla의 Library에 들어온 font 무비클립을 우클릭하여 Linkage..을 선택한다.

- 창이 뜨면 Linkage 항목 중 Import for runtime sharing을 체크한 후(체크 되어 있을 것이다)

   Identifier를 입력 (디폴트로 드래그 한 무비클립 이름이 들어간다, 그냥 놔둬야 한다) 후   

   URL 항목에 가져올 swf 이름을 입력한다. (입력되어 있을 것이다, 여기선 font.swf를 입력)

- OK클릭


3. test.fla 에 스크립트를 넣어 테스트 해 본다.

- Stage에 레이어 추가 후 다음의 스크립트를 입력한다.


var fmt:TextFormat = new TextFormat();
fmt.color = 0xFF6600;
fmt.font = "Font 1"; // 자기가 제작한 font의 identifier를 입력한다.
fmt.size = 20;
_root.createEmptyMovieClip("mc", _root.getNextHighestDepth());
mc.createTextField("txt", _root.getNextHighestDepth(), 0, 0, 0, 0);
mc.txt.embedFonts = true;
mc.txt.autoSize = true;
mc.txt.text = "플래시 폰트 공유 라이브러리";
mc.txt.setTextFormat(fmt);
mc._x = 100;
mc._y = 100;


- Ctrl+Enter로 테스트 해본다.

신고
Posted by 정윤수 버터백통