노무현 대통령 배너

도큐먼트 클래스 *.as 파일을 연결하지 않은 fla 파일의 도큐먼트 클래스 이름은?

by on 2.25, 2010, under AS3.0 API

작년 7월에 작성한 “AS3.0 로더(Loader)로 불러온 다른 swf 의 클래스 사용하기” 를 보면, ApplicationDomain 클래스의 getDefinition() 메서드를 이용해서 다른 로더를 통해 가지고 온 다른 swf 파일의 클래스를 사용하는 방법을 알아본 바 있습니다.
그런데 이 포스트에 “료”님이, fla 파일의 타임라인에 직접 코딩한 경우에는 어떻게 해야 하느냐고 질문하셨길래 방법을 찾아 보았습니다.

우리가 Fla 에 도큐먼트 클래스를 연결해서 swf 를 만들었을 경우, Main.as 도큐먼트 클래스에서 trace( this ) 를 하면 [object Main] 이 출력 됩니다. “AS3.0 로더(Loader)로 불러온 다른 swf 의 클래스 사용하기” 의 예제 코드를 보면 다른 swf 의 도큐먼트 클래스의 이름을 통해 런타임으로 클래스로 만들고 그것을 객체화 하여 도큐먼트 클래스 내부에 있는 여러가지 자원들을 참조하게 됩니다. 도큐먼트 클래스의 이름이 곧 ApplicationDomain 이 되는 것이죠. 그것은 결국 도큐먼트 클래스의 클래스 이름을 알 수 없다면 getDefinition() 으로는 참조가 불가능하다는 이야기가 됩니다.

그런데 만약 도큐먼트 클래스를 사용하지 않은 fla 파일로 만든 swf 파일이라면 어떻게 되는 걸까요? “료”님의 질문을 받고 저역시 이 부분에서 살짝 당황했습니다. 도큐먼트 클래스 as 파일이 없는데 도큐먼트 클래스의 이름을 어떻게 알아낼 수 있을까 하는 것이었죠.

그런데 결국 추론를 통해 도큐먼트 클래스의 이름을 알아냈습니다.
라이브러리에 클래스 정의를 한 무비클립에도 물리적 as 파일을 연결하지 않으면, 컴파일 과정에서 자동으로 as 파일을 생성한다는것에 힌트를 얻었습니다.

라이브러리의 속성창에서 클래스 이름만 써 넣고 as 파일은 연결하지 않을때 나타나는 경고 다이알로그 박스

위의 다이알로그 박스의 메세지 내용인 즉슨, 클래스가 필요한 객체는 어떠한 형태로든 클래스 파일을 생성한다는 것이죠. 이와 마찬가지로 Flash IDE에서 도큐먼트 클래스 없이 컴파일을 하더라도 어딘가 가상으로 파일을 만들어 낼 거라는 생각이 들었습니다.

이때 빛을 발휘하는 프로그램이 바로 FlashDevelop(이하 FD) 이죠. FD 의 Project 패널은 as 파일과 디렉토리를 네비게이션 하는 1차적 용도를 가지고 있지만, 컴파일된 swf 파일이나 swc 파일의 구조를 분석할 수 있도록 기능도 가지고 있습니다.

FlashDevelop 의 Project 패널

FlaSubSystem.fla 은 도큐먼트 클래스가 없는 fla 파일 입니다. 이 파일로 FlaSubSystem.swf 파일을 컴파일 했습니다. 이 파일의 1프레임에는 간단한 무비클립과 코드 몇줄을 넣어놓았습니다.
Main.as 파일은 FD에서 프로젝트를 생성할때 만든 도큐먼트 클래스 입니다. 이 도큐먼트 클래스로는 GetDefinition.swf 파일을 만들었죠.

그러니까 “AS3.0 로더(Loader)로 불러온 다른 swf 의 클래스 사용하기” 의 내용과 매칭하자면 FlaSubSystem.swf 파일이 SubSystem.swf 이 되는 것입니다.

컴파일된 FlaSubSystem.swf 파일의 왼쪽에 있는 + 기호를 이용해 펼치면 swf 파일 내부에 정의되어 있는 클래스들을 모두 볼 수 있는데요, 보시는 바와 같이 fla 의 파일명에 _fla 라는 문자가 붙고 점 찍은 후에 MainTimeline 이 클래스 화 되어 있는것을 볼 수 있습니다. 1프레임에 코드를 넣게 되면 위와 같이 MainTimeline 이 클래스 화 되고, 프레임에 코드가 없으면 클래스가 생성되지 않습니다.

그러면 Main.as 파일의 코드를 살펴보겠습니다.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package
{
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain; 
 
	public class Main extends Sprite
	{
		private var loader:Loader = new Loader();
		private var request:URLRequest = new URLRequest( "FlaSubSystem.swf" );
 
		public function Main()
		{
			loader.contentLoaderInfo.addEventListener( Event.INIT, completeHandler );
			loader.load( request );
			trace( this )
		}
 
		private function completeHandler( e:Event ):void
		{
			var runtimeClassRef:Class = loader.contentLoaderInfo.applicationDomain.getDefinition( "FlaSubSystem_fla.MainTimeline" ) as Class;
			var displayObj:DisplayObject = new runtimeClassRef(); //addChild 하려면 DisplayObject 로 캐스팅
			addChild( displayObj );
 
			var subSystemObj:Object = displayObj as Object; //메서드를 호출하려면 다시 Object 로 캐스팅
 
			// 아래의 member 들은 모두 fla 파일의 stage 또는 타임라인의 1프레임에 정의한 내용.
			trace( subSystemObj.myInstance ); // stage 에 인스턴스네임 부여한 무비클립 객체. 참조 가능 // 출력 : [object MovieClip]
			trace( subSystemObj.myString ); // 변수에는 접근안됨 // 출력 : null
			trace( subSystemObj.myGetter ); // getter/setter 메서드 접근 가능
			trace( subSystemObj.myFunction() ); // 함수 접근 가능
		}
	}
}

getDefinition() 메서드를 보면 fla 파일의 메인 타임라인 클래스에 접근하기 위해 FlaSubSystem_fla.MainTimeline 라는 문자열을 사용한것을 볼 수 있습니다. 이 ApplicationDomain 을 런타임 클래스 화 하고 객체로 만들어 내는 과정은 동일합니다.

각 요소들에 대한 참조 여부는 코드 내부의 주석에 적었으므로 그것으로 설명을 대신합니다.

타임라인 코드에 var 키워드를 이용해 생성한 변수에는 접근이 되지 않는데, 차후에 방법을 알게되면 추가하겠습니다. 그러나 getter/setter 가 가능하므로 굳이 필요하다면 변수 대신 사용할 수 있을것 같습니다.

이 글을 복사해서 퍼가시는건 허용하지 않습니다. 글의 주소를 다른곳에 알려주시는 것은 환영합니다.

관련된 글

:, , , , , , , , , , , , , , ,

7 Comments for this entry

  • No Gravatar

    역시 대단한 분석력입니다.
    저두 첨에 “MainTimeline”까진 해봤는데 안되더라구요.

    테스트해봤는데 잘되네요.
    swf 생성시 fla 파일 이름을 기준으로 클래스가 생성되나보네요.

    포스트까지 쓰시고 정말 감사드리고 수고하셨습니다. ^^

    • 세계의끝No Gravatar

      파일이름에 _fla 를 붙인건, 파일이름.fla.MainTimeline 하게되면 fla 가 의도하지 않은 패키지가 되버리기 때문에 그런것 같습니다.
      여러모로 일등공신은 FD 인 셈인데… FD의 Project 패널을 이용한 클래스 분석은 참으로 쓸모가 많은것 같습니다.
      덕분에 한달만에 포스팅 했습니다. ㅎㅎ

  • pjsNo Gravatar

    질문드립니다.

    포스팅 하신데로 따라하고 있는데 자꾸 플래시가 다운이 되네요?

    var runtimeClassRef:Class = loader.contentLoaderInfo.applicationDomain.getDefinition( “FlaSubSystem_fla.MainTimeline” ) as Class;

    이부분이 실행되면 그러네요..

    왜그럴까요?ㅜㅜ

    • 세계의끝No Gravatar

      컴파일 에러도 아니고 다운이 된다면 다른 이유가 있는것 같습니다. 제가 확인해 드릴 수 있는게 없네요.

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Meta