2009년 6월 29일 월요일

mxml이 interface를 구현하려면?

root tag의 implements 속성에 interface명을 넣어주면 된다.

 

implements="Interface1,Interface2"

2009년 6월 25일 목요일

flex 컴포넌트에 sprite 넣기

flex 컴포넌트에 sprite를 넣으려면 다음처럼 하면 된다.

 

component.rawChildren.addChild(sprite);

AS3.0 화면객체 밖에서 Mouse UP 된 것을 알아내기

1. Down 됐을때 stage에 addEventListener로 MOUSE_UP 이벤트 리스너를 추가한다.

2. 1.에서 만든 이벤트 리스너에서 removeEventListener 해준다.

 

참고 : http://anilmathewm.blogspot.com/2008/01/event-handling-in-actionscript-30.html

2009년 6월 22일 월요일

PureMVC에서 Popup은 어떻게 다룰까?

PopManager 라는 게 있다. PureMVC 내부에 있는 건 아니고 따로 구현해야 한다. PopUp을 생성하면서 Mediator와 연결시켜 준다.

 

참고 : http://forums.puremvc.org/index.php?topic=105.0

ApplicationControlBar에서 정렬

flex에서 ApplicationControlBar의 왼쪽과 오른쪽에 컨트롤을 두고 싶을때가 있다. 이때 가운데 공간을 넣는 쉬운 방법이 있다. <mx:Spacer width="100%">를 중간에 삽입하면 된다.

2009년 6월 21일 일요일

Flex에서 이미지를 부드럽게

읽어들인 Image를 리사이징 하고 부드럽게 바꾸려면 Image컨트롤에 대해서 complete 이벤트에 아래 이벤트 핸들러를 실행시키면 된다.

 

protected function onImgLoadComplete(event:Event):void

{

    var bitmap:Bitmap = ( event.target as Image ).content as Bitmap;

   
    if ( bitmap != null )

        bitmap.smoothing = true;

}

XML이냐 Array냐

Array로 구성한 트리를 마구 돌아다니다가 "XML 노드들을 기본 클래스로 바꾸고 Array 같은 기본 컬렉션에 담는 것"이 과연 좋은 일인지 생각하게 됐다.

 

처음에는 바꾸는 게 좋다고 생각 했다. XML 구조가 바뀌어도 오브젝트의 프로퍼티들을 바꿔주면 컴파일 타임에 문제가 생기는 위치를 알 수 있었다. 컴파일 에러가 나는 위치로 가서 코드를 고쳐주면 간단했다.

 

타입을 명확히 하여 생긴 이득이다. 소트웍스 앤솔러지에서도 보면 원시값은 아무 의미 없는 스칼라 값이며 의미를 분명히 하는 데 노력하라고 써있다. 날짜를 받기위한 매개변수 when을 int 타입으로 설정하면 누군가는 날짜 대신에 시간을 넣을지도 모를 일이다.

 

그러나 기본 컬렉션의 단점도 있다. 자료구조를 검색, 수정 하려니 만만치 않다. Flash에서는 DB를 지원하지 않아서 불편하다. MFC 할 때도 웬만한 자료구조는 기본 컬렉션을 쓰지 않고 SQLite로 처리했다. 검색, 수정, 추가등이 편리하기 때문이다.

 

Flash에서 XML, 특히 E4X로 XML을 다루면 자료구조를 어느정도 쉽게 다룰 수 있을거라고 생각된다. XML만 사용하고 타입이 모호해지는 문제(런타임에서야 문제를 확인할 수 있는 단점)는 테스트를 강하게 하는 쪽으로 해결하는 게 더 효율적일 것 같다.

 

아직 추측이니 XML 쓰면서 익혀봐야겠다. 당장에 객체에 해당하는 XML 노드에 행위(메소드)를 부여하려고 하면 XML은 불편해 보인다.

 

참고 :

(1) http://www.actionscript.org/forums/showthread.php3?t=156040

(2) http://norman.walsh.name/2003/06/01/xmlnotoo

(3) http://stackoverflow.com/questions/719674/hierarchy-data-structure-in-java-or-xml-to-object-conversion-best-practices

2009년 6월 19일 금요일

마지막 시험

11시에 마지막 시험을 본다. 컴퓨터 구조. 시험 끝나면 flash로 커뮤니티 사이트 하나 만들 생각이다.

2009년 6월 10일 수요일

블로거 시국 선언문.

6월항쟁 22주년을 맞는 오늘 우리 블로거들은 다시 민주주의와 사회적·경제적 정의를 고민한다.

 

이명박 정부 출범 이후 표현의 자유와 언론의 독립성이 크게 훼손되고, 인터넷에 대한 통제가 심각한 수준에 이르고 있다. 이명박 정부는 헌법에 보장된 집회와 시위의 자유를 사전적·포괄적으로 봉쇄하여 국민의 알 권리와 말할 권리를 모두 틀어막으려 하고 있다. 경제적 양극화가 날로 심화되고 있고 노동자와 서민, 사회적 약자들은 벼랑 끝으로 내몰리고 있다.

 

우리 블로거들은 다음을 요구한다.

1. 정부는 언론 장악 시도를 중단하고 국민들의 표현의 자유를 폭넓게 보장해야 한다.
2. 정부는 민주주의를 지탱하고 대의절차의 왜곡을 보완하는 기본권인 집회·결사의 자유를 폭넓게 보장해야 한다.
3. 정부는 독단적인 국정 운영을 중단하고 사회적 약자 및 소수자의 목소리에 진지하게 귀기울여야 한다.

 

대한민국 블로거 구준호.

 

참고 : http://www.leejeonghwan.com/media/archives/001516.html

2009년 6월 9일 화요일

PureMVC MultiCore에서 AppSkeleton 문제 해결

PureMVC AS3 Standard에 보면 App Skeleton 예제가 있다. 이 예제는 MultiCore로 바꾸면 문제가 된다. 원인은 이렇다.

 

총 3개의 Proxy들이 등록되는데 두 개의 Proxy는 나머지 한 개의 Proxy를 retrieveProxy로 얻으려고 한다. 이때 생성자에서 facade를 사용하는데 Standard는 ApplicationFacade가 Singleton이기 때문에 문제가 없다. 하지만 MultiCore에서는 Proxy나 Mediator가 register되기 전에 facade를 호출하면 key를 알 길이 없어서 죽어버린다.

 

좌절은 금지다. 잘 찾아보니 onRegister() 라는 메소드를 오버라이드 할 수 있다. 이 메소드를 오버라이드 하면 Proxy나 Mediator가 등록될 때 onRegister()가 호출된다. 여기에 facade를 사용하는 코드를 넣으면 된다. 문서에선 이게 무슨 의미인지 아직 정확히 안써놔서 몰랐었는데 결국 알게됐다. 이런건 꼭 퇴근시간 지나면 자연히 알게 되더라. 철야.

PureMVC의 proxy를 flexunit으로 테스트 하기

죽음의 테스트를 완벽하게 통과한 튼튼한 모델이라 할지라도 PureMVC 상에서 메세지를 잃게되면 프로그램은 먹통으로 보이게 된다. 맘편하게 Notification처리 구조를 바꾸고 싶다면 어떻게 해야 할까? Notification에 대한 테스트를 만들어야 한다. flexunit은 순수한 ActionScript3 이벤트는 테스트 할 수 있어도 PureMVC의 Notification을 이해하지 못한다. 해서 나온 것이 이것이다. http://code.google.com/p/puremvc-flexunit-testing/

 

사용법

1. 라이브러리를 추가하고 PureMVCTestCase를 상속받는 TestCase를 만든다.

2. TestCase 내부에 테스트를 하고자 하는 proxy와 view를 얻는 getter를 만든다.

 

  public function get proxy():MyProxy
  {
   return ApplicationFacade.getInstance(ApplicationFacade.NAME).

      retrieveProxy(MyProxy.NAME) as MyProxy;
  }
 
  public function get view():IView
  {
   return View.getInstance(MyMediator.NAME);
  }

3. registerObserver(view, proxy, MyProxy.INIT, OnInit, 1000); 이런 식으로 테스트 안에서 실행 시킨다.

4. public function OnInit(event:PureMVCNotificationEvent):void 이렇게 받는다.

 

컴파일 된 라이브러리를 받아다가 프로젝트에 적용하니 multicore쪽 패키지를 찾으려고 했다. 코드 볼 시간이 없어서 그냥 PureMVC를 Standard에서 Multicore로 바꾸고 프로젝트 구조를 example 따라서 바꿨더니 쉽게 됐다.

 

참고 : http://marburger.cc/posts/flexunit-testing-puremvc-code

2009년 6월 8일 월요일

flexunit으로 event 테스트하기

1. 테스터를 만들때 TestCase 대신 EventfulTestCase를 상속받는다.

2. listenForEvent(이벤트Dispatcher, 이벤트타입, 발생할 것으로 예상하면 true 아니면 false);

3. dispatchEvent()

4. assertEvents(); 하면 2번에서 기대한 이벤트가 3번을 통해 발생됐는지 확인된다. 만약 2번에서 3번째 인자를 false로 했는데 이벤트가 감지되면 테스트가 실패한다.

 

연습삼아 해봤다. 별로 쓸모 없지만 custom event 자체를 테스트 해보려고 EventfulTestCase에서 IEventDispatcher를 구현하고 필요한 메소드들을 오버라이드 했다. 이벤트 발생시 이벤트를 통해 넘어온 값들을 바꾸고 테스트 쪽에서 해당 값이 잘 들어왔는지 assertEquals 테스트도 해봤다.

프로젝트 진행 상황

헤헤.

2009년 6월 7일 일요일

dispatchEvent로 Event 전송시 추가적인 오브젝트 보내기

1. Event를 상속받은 custom event를 만든다.

2. 생성자로 추가로 전송하기 원하는 오브젝트들을 받는다.

3. 생성자에서 이벤트의 멤버로 받은 오브젝트들을 저장한다.

4. clone()을 override하고 new CustomEvent를 return한다.

5. dispatchEvent에서 custom event를 사용한다.

6. 이벤트 핸들러에서 custom event로 받고 event 멤버의 값을 사용한다.

ActionScript Event Bubbling

여러 아이템을 갖고있는 Sprite가 있다. 아이템에 뭔가가 drop되면 이벤트를 발생시켜서 Sprite를 사용하는 시스템이 drop 된 사실을 알 수 있어야 한다. drop 이벤트 처리는 아이템 객체들이 각자 처리하기 때문에 이벤트를 부모의 부모가 받아야 하는 상황이다. Sprite가 중간에 뭔가 해야하잖아? 설계가 후져서 생긴 일이라고 좌절하려던 찰나 dispatchEvent에서 bubble을 true로 했더니 부모의 부모가 알아서 받더라. 땡큐 어도비.

ActionScript 달에 몇 일이 있는지 얻는 방법

 

new Date(year, month, 0).getDate() as int;
위의 코드처럼 하면 된다. month는 0~11을 입력하게 되는데 3월을 알고 싶을때 month에 2를 넣으면 3월로 취급한다. date는 1~31까지인데 0을 넣었으므로 하루 전 날. 즉 month월의 마지막 날이 된다. 마지막 날은 그 달에 있는 일 수와 같다.

TDD는 Unit Test가 아니다

내가 테스트를 만들고 있기는 한데 TDD는 아니라는 생각이 들어 그 차이가 무엇인지 짚어본 사람이 있을까 있어 찾아봤다. http://stephenwalther.com/blog/archive/2009/04/11/tdd-tests-are-not-unit-tests.aspx

2009년 6월 6일 토요일

Flexunit UI testing

링크 : http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=2&postId=7222

 

화면 객체를 flexunit으로 테스트 하려다 보니 오류가 났다. 방법을 찾아봤더니 위의 링크가 나왔다. 다 읽지는 않고 소스만 잠시 봤는데 Application.application을 얻는 방법이 나오는 것 같아서 setUp()에서 application에 테스트 하려는 화면 객체를 addChild하고 tearDown()에서 화면 객체를 removeChild 했더니 잘 된다.

mxml에서 script를 별도 파일로 빼내기

mxml에 ActionScript 코드를 바로 삽입 할 수도 있지만 아래처럼 할 수도 있다.

<mx:Script source="SomeFile.as" />

주의 사항이 있다. Haha.mxml파일은 Haha 클래스를 의미하기 때문에 Haha.as파일을 만들면 동일한 클래스가 두 개 존재하는 것으로 보고 오류를 낸다.

 

코드를 분리하니 스크롤 영역이 줄어들어서 파일을 한 번에 파악하기 좋고 ASDoc 태그를 사용할 수 있어서 좋다. mxml용 ASDoc 태그는 나중에 지원되는 것으로 보인다.

2009년 6월 5일 금요일

Flex tree 아이템 drag

온라인 상의 예제를 보고 Tree 드래그 드롭을 구현했다. dragDrop의 핸들러로 dragDropHandler을 지정하고 dragDropHandler에서 아래와 같이 코딩했는데 자꾸 죽더라.

 

var items:Array = dragSource.dataForFormat("items") as Array;

 

dragSource의 멤버들을 보니 formats라는 배열이 있길래 봤더니 말그대로 format 종류들을 리턴해줬다. treeItems라는 것으로 들어 있길래 위의 items를 treeItems로 바꿨더니 잘 된다.

 

items의 값 안에 뭐가 들어있는 지도 문제였다. 한 개의 값을 꺼내서 toLocaleString()으로 찍어보니 XML이었다. XML로 형 변환 하고 tree에서 dataProvider로 지정한 XML에 맞춰 attributes를 꺼내서 찍어보니 잘 들어온다.

 

이런 종류의 삽질은 경험으로 다 해결해야 하는 건가? 스트링에 뭐가 들어갔을줄 알고. 요즘 디버거가 작동이 안되는데 디버거로 보면 좀 자세히 나오려나. 책 한 권 살까? 휴=3

 

참고 : http://www.adobe.com/devnet/flex/quickstart/adding_drag_and_drop/

Flash에서 비동기로 얻어오는 XML파일 순서대로 여는 방법

Flash에서 몇 개의 XML을 읽을 때 1번 파일에서 얻은 값을 2번을 읽는데 사용하는 경우가 생길 수 있다. 문제는 XML을 비동기로 호출하니 1번은 다 얻어오기 전에 2번을 읽으려고 한다는 것.

 

PureMVC의 App Skeleton에서는 리소스 목록을 관리하는 StartupMonitorProxy에 XML파일 하나를 대표하는 Proxy들을 추가하여 Proxy가 생성되는 순서대로 XML을 얻어오게 하는 코드가 있다.

 

물론 내가 뛰어난 실력으로 그런 것들을 한 눈에 파악한 것은 아니고. 아무 생각없이 지웠다가 안되길래 다시 보며 파악한 것. ㅎ 집에 가고싶다.

2009년 6월 4일 목요일

Flex UI Testing

flexmonkey라는 툴이 있는데 사용자가 flex상에서 한 행동들을 레코딩 해서 다시 플레이 하는 형태의 테스트를 제공한다.

ActionScript E4X에서 attribute 값으로 찾기

아래처럼 찾으면 전체 course 중에서 id attribute가 4인 값을 찾는다.

var course:XMLList = treeData..course.(@id == 4);

 

이때 해당 course가 없으면 오류가 나므로 위의 줄을 사용하기 전에 개수를 확인해 주면 좋다.

var length:int = treeData..course.(@id == courseId).length();

 

위의 값이 0이면 사용하지 않는다.

2009년 6월 3일 수요일

Ant에서 ASDoc 실행

build.xml에서 exec 형태로 ASDoc을 실행시키는 것 같다. 명령창에서는 잘 되는데 어찌된 일인지 Ant로는 잘 안됐다. 그래서 명령창에서 실행시킨 명령어를 batch 파일로 만들고 그걸 Ant에서 exec로 실행시키니 된다.

ASDoc 실행

"C:\Program Files\Adobe\Flex Builder 3\sdks\3.2.0\bin\asdoc"

 

-source-path "원하는 Flex 프로젝트의 src 디렉토리"

 

-external-library-path "원하는 Flex 프로젝트의 libs 디렉토리"

 

-doc-classes "package를 포함한 클래스명"

(최상위 디렉토리의 MXML Application 이름(이게 클래스 명이니까)으로 해도 된다.)

 

-main-title "main title"

 

-window-title "window title"

 

-output flex-framework-asdoc

 

pause

위처럼 하니 된다. -doc-classes 에 com.domain... 이런 식으로(여러 개라면 띄어쓰기로 구분)해서 클래스를 지정하면 된다. 지정된 클래스와 관련된 클래스는 다 문서화 되나 보다. 최상위에 존재하는 MXML Application 파일의 이름을 지정하면 프로젝트 전체에 대한 도큐먼트가 생성된다.

 

외부 라이브러리를 사용하면 -external-library-path를 지정한다. 나의 경우에는 PureMVC를 libs에 넣고 사용하기 때문에 그 위치를 넣어줬다.

 

프로젝트에서 mx:AdvancedDataGrid를 사용하는데 그 부분에서 에러가 났다. 구글에서 찾아보니 flex sdk에 포함되어 있는 asdoc을 사용해서 그렇다. flex sdk에는 mx:AdvancedDataGrid가 포함되어 있지 않다. 그래서 Flex Builder 안에 있는 asdoc을 실행시켰더니 잘 된다.

PureMVC에서 Proxy 클래스 만들기

PureMVC에서 Proxy 클래스를 어떻게 구성해야 할지 생각해봤다. 다수의 아이템들을 포함하는 배열과 같은 구조를 만든다고 하면 배열 클래스와 아이템 클래스들 모두 Proxy여야 할까 배열 클래스만 Proxy고 아이템 클래스는 일반적인 클래스로 해야 할까?

 

처음에는 한 개의 아이템이 바뀌면 Notification이 전송되고 그 아이템에 해당하는 UI상의 한 요소가 자동으로 바뀌는 모양을 생각했다. 즉 아이템도 Proxy로 만드는 구조를 생각했다. 그런데 예제들 중 동적으로 생성된 Proxy에 이름을 부여하는 예제는 못본 것같다. PureMVC는 모델을 얻어오건 Notification 종류를 분류하건 동적으로 생성된 인스턴스의 이름을 알아야 얻을 수 있는데 정적으로 되어 있는 경우만 봤다. 동적으로 생성된 모델의 이름을 뷰 등에서 알 수 있게 하는 방법도 편해 보이지는 않는다.

 

아직 깊이 생각을 못해봤지만 Proxy는 시스템 상에서 한 개로 존재하는 값들을 저장하는 공간이 되어야 할 것같다.

2009년 6월 1일 월요일

Adobe Flex Builder 3 + Ant

+ Ant로 컴파일

가능. 이클립스 플러그인으로 설치. 쉽게 사용가능. CI를 위해서는 Stand-Alone으로 설치해야 하나?

 

+ Ant로 테스팅

Ant로는 FlexUnit 아직 실행 시키지 못했음. 그냥 FlexUnit은 쉽게 됨.

 

+ Ant로 ASDoc 생성

ASDoc 만드는 커맨드 명령어를 Ant에서 exec로 등록해서 쓰면 됨.

 

+ 결론

CI용 컴퓨터 구입하기 전까지는 FlexUnit이랑 ASDoc 정도만 사용한다.