*** 5.25일, SLoader의 next()메서드에서 에러의 소지가 있어 수정.

*** 4.23일, 로드중인 SLoader를 unload()하거나 close() 시키면 이어서 연속 로드가 되지 않는 버그를 수정.

 

이전의 (link)SequenceLoader는 OOP에 적용하기에는 유연하지 못하다는 것을 이번 프로젝트에서 느끼게 되어 새롭게 만든 SLoader.

 

Loader의 동생벌로서 사용법은 같으나 싱글톤인 SequenceCenter의 지배를 받아 로딩이 순차적으로 이루어지는 클래스이다.



- 사용법 : Loader와 같다. 

for (var i:int = 0; i<_len; ++i) {
        var sl:SLoader = new SLoader();
        sl.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler);
        sl.load(new URLRequest(url));
}
 
function completeHandler(event:Event):void {
        trace("****", event);
        var ld:Loader = event.target.loader;
        ld.x =50;
        stage.addChild(ld);
}


- SLoader.as

/**
 * SLoader -
 *
 * @author: showjean in http://showjean.com/works, mobile, mailto:showjean@hanmail.net
 * @version: 1.2.2
 * @date: 2009.4.23.
 *
 * @comment:
 */
package com.showjean.net{
 
        import flash.net.*;
        import flash.display.*;
        import flash.events.*;
        import flash.system.*;
 
        public class SLoader extends Loader {
 
                //센터에서 다음 순서를 확인해서 자신이라면 로드시작
                protected var center:SequenceCenter=SequenceCenter.getInstance();
 
                protected var __uindex:int;
                protected var __request:URLRequest;
                protected var __context:LoaderContext;
 
                function SLoader() {
                        _isLoading = false;
                        center.addEventListener(SequenceCenterEvent.NEXT,__nextTurnHandler);
                        __uindex=center.index;// 시퀀스 센터에서 고유의 인덱스를 받아온다.
                }
                // _____________________________________________________ override
 
                // 로드를 하기전 시퀀스센터에 등록, 차례를 기다린다.
                override public function load(request:URLRequest,context:LoaderContext=null):void {
                        __request=request;
                        __context=context;
 
                        center.add(__uindex);
 
                        center.next();
                }
                override public function close():void {
                        dispose();
                        super.close();
                }
                override public function unload():void {
                        dispose();
                        super.unload();
                }
 
                // _____________________________________________________ public
                // _____________________________________________________ protected
                protected function dispose():void {
                        if (center) {
                                // 로딩중 멈추는 것이라면 다음을 로드
                                if(_isLoading && center.isActive){
                                        next();
                                }
                                removeEvent();
                                center.remove(__uindex);
                                center = null;
                                __request = null;
                                __context = null;
                        }
                }
                protected var _isLoading:Boolean
                protected function __load():void {
                        // 센터의 현재(자신)을 제거
                        center.removeEventListener(SequenceCenterEvent.NEXT,__nextTurnHandler);
                        center.shift();
 
                        addEvent();
 
                        center.isActive=true;
                        super.load(__request, __context);
                }
                protected function next():void {
                        if (center) {
                                center.isActive=false;
                                center.next();
                        }
                }
                protected function addEvent():void {
                        _isLoading = true;
                        this.contentLoaderInfo.addEventListener(Event.COMPLETE, __completeHandler);
                        this.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, __ioErrorHandler);
                }
                protected function removeEvent():void {
                        _isLoading = false;
                        this.contentLoaderInfo.removeEventListener(Event.COMPLETE, __completeHandler);
                        this.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, __ioErrorHandler);
                }
                // ____________________________________________________________ listener
                protected function __nextTurnHandler(event:SequenceCenterEvent):void {
                        //다음 로더가 자신이라면
                        if (__uindex == event.index) {
                                event.stopImmediatePropagation();
                                __load();
                        }
                }
                protected function __completeHandler(event:Event):void {
                        removeEvent();
                        next();
                }
                protected function __ioErrorHandler(event:IOErrorEvent):void {
                        removeEvent();
                        next();
                }
        }
}


- SequenceCenter.as

/**
 *  SequenceCenter
 *
 * @author: showjean in http://showjean.com/works, mobile , mailto:showjean@hanmail.net
 * @version: 1.0.2
 * @date: 2009.4.19.
 *
 * @comment: SequenceLoader를 순서대로 실행시키는 싱글톤
 */
package com.showjean.net{
 
        import flash.net.*;
        import flash.events.*;
 
        public class SequenceCenter extends EventDispatcher {
 
                static private  var instance:SequenceCenter=new SequenceCenter();
 
                private var _dataArr:Array;
                private var _isActive:Boolean = false;
                private var _index:int = 0;
 
                function SequenceCenter() {
                        if (instance) {
                                throw new Error("Singleton can only be accessed through Singleton.getInstance()");
                        }
                        _dataArr = new Array();
                }
                static public function getInstance():SequenceCenter {
                        return instance;
                }
                // _______________________________________________ public
                public function set isActive(b:Boolean):void {
                        _isActive = b;
                }
                // 로드 중인지 확인
                public function get isActive():Boolean {
                        return _isActive;
                }
                public function get index():int {
                        return _index++;
                }
                public function remove(idx:int):void {
                        var idx:int = _dataArr.indexOf(idx);
                        if(idx > -1){
                                _dataArr.splice(idx, 1);
                        }
                }
 
                public function add(idx:int):void {
                        _dataArr.push(idx);
                }
                public function shift():void {
                        _dataArr.shift();
                }
                public function next():void {
                        if (_dataArr.length > 0 && isActive==false) {
                                //trace("center next : ", _dataArr[0]);
                                dispatchEvent(new SequenceCenterEvent(SequenceCenterEvent.NEXT, int(_dataArr[0])));
                        }
                } 
 
        }
}


- SequenceCenterEvent.as

/**
 *  SequenceCenterEvent
 *
 * @author: showjean in http://showjean.com/works, mobile , mailto:showjean@hanmail.net
 * @version: 1.0.1
 * @date: 2008.9.26.
 *
 * @comment:
 */
package com.showjean.net{
 
        import flash.events.*;
        import flash.net.*;
        import flash.display.*;
 
        public class SequenceCenterEvent extends Event {
 
                public static  const NEXT:String = "next";
 
                private var _slIndex:int;
                public function SequenceCenterEvent(type:String, idx:int, bubbles:Boolean=false, cancelable:Boolean=false) {
                        super(type, bubbles, cancelable);
                        _slIndex = idx;
                }
                public function get index():int {
                        return _slIndex;
                }
                override public function clone():Event {
                        return new SequenceCenterEvent(this.type,_slIndex,this.bubbles,this.cancelable);
                }
                override public function toString():String {
                        return formatToString("SequenceCenterEvent","type","index","bubbles","cancelable","eventPhase");
                }
 
 
        }
}