본문 바로가기

액션스크립트 3.0

AS3.0 크로스스크립팅 : ApplicationDomain 클래스


문제

main.swf 에서 sub.swf 를 불러와서 어떻게 상호제어 할 수 있을까?

 

AS2.0에서는 인스턴트네임을 이용해서 바로 접근이 가능했지만 3.0에 와서는 더 이상 그런 기능을 사용할 수 없습니다. 대신 인스턴스 네임이 아닌 getDefinition("클래스네임") 메서드를 이용해 해당 객체를 참조할 수 있습니다.

 

사용법

/******************************************

 * Main.as : 이벤트리스너 클래스

 * Sub.as : 이벤트를 발생하는 이벤트소스클래스

 ******************************************/

 

//Sub.as 클래스 -------------------------------------------

package

{
    import flash.display.Sprite;

    public class Sub extends Sprite
    {
        public function Sub()
        {
        }

        /**

         * @Func : init      main.swf 에서 제어할 메서드  

         **/

        public function init():String {
            trace( "Good Morning" );
        }

        /**

         * @Func : sentEventToMainSWF      main.swf 에서 Sub.swf로 이벤트를 보낼 메서드

         **/

        private function sentEventToMainSWF(): void

        {

            dispatchEvent( new Event( Event.CHANGE ));

        }
    }
}

 

//Main.as 클래스 -------------------------------------------

package

{
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.events.Event;

    public class Main extends Sprite {
        private var _loader:ClassLoader;


        public function Main () {            
            this._loader = new ClassLoader();
            this._loader.addEventListener( ClassLoader.LOAD_ERROR,loadErrorHandler );
            this._loader.addEventListener( ClassLoader.CLASS_LOADED,classLoadedHandler );
            this._loader.load( "Sub.swf" );
        }
        private function loadErrorHandler( e:Event ):void {
            throw new IllegalOperationError("Cannot load the specified file.");
        }
        private function classLoadedHandler( e:Event ):void {

            var runtimeClassRef:Class = this._loader.getClass("Sub");

 

            //스테이지에 addChild 하려면...

            //var displaySub: DisplayObject = runtimeClassRef() as DisplayObject;

            //var sub: Object = displaySub as DisplayObject;


            var sub: Object = new runtimeClassRef(); 

            //Sub.swf 내부 init() 메서드 제어

          sub.init(); 

          //Sub.swf 에서 이벤트를 받을 리스너 등록

          sub.addEventListener( Event.CHANGE, onChangeHandler );
        }

        private function onChangeHandler ( e: Event ): void

        {

            //메서드 구현

        }

    }
}

 

//ClassLoader 클래스( 외부자원 로드클래스 )

package {
    import flash.display.Loader;
    import flash.errors.IllegalOperationError;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.IOErrorEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.URLRequest;
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;

    class ClassLoader extends EventDispatcher {
        public static var CLASS_LOADED:String = "classLoaded";
        public static var LOAD_ERROR:String = "loadError";
        private var loader:Loader;
        private var swfLib:String;
        private var request:URLRequest;
        private var loadedClass:Class;

        public function ClassLoader() {
            loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler);
            loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
            loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler);
        }
        public function load(lib:String):void {
            swfLib = lib;
            request = new URLRequest(swfLib);
            var context:LoaderContext = new LoaderContext();
            context.applicationDomain = ApplicationDomain.currentDomain;

            //다른 폴더 같은 클래스명일 경우 사용.
            //context.applicationDomain = new ApplicationDomain();
            loader.load(request,context);
        }
        public function getClass(className:String):Class {
            try {

                 //Sub 클래스에 접근하기 위한 핵심 구문

                return loader.contentLoaderInfo.applicationDomain.getDefinition(className)  as  Class;
            } catch (e:Error) {
                throw new IllegalOperationError(className + " definition not found in " + swfLib);
            }
            return null;
        }
        private function completeHandler(e:Event):void {
            dispatchEvent(new Event(ClassLoader.CLASS_LOADED));
        }
        private function ioErrorHandler(e:Event):void {
            dispatchEvent(new Event(ClassLoader.LOAD_ERROR));
        }
        private function securityErrorHandler(e:Event):void {
            dispatchEvent(new Event(ClassLoader.LOAD_ERROR));
        }

    }
}