博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

API文档参考:http://doc.starling-framework.org/core/starling/utils/AssetManager.html

项目想以不改动starling的情况下对某些功能扩展,为的是方便starling升级后可直接替换, 之前写了个GAssetsMgr 接管了 纹理加载,方便文件缓存。还有一个问题是这个管理类是单一队列,并且只给外部传一个进度信息 loadQueue(onProgress), 当不断地往队列里加任务时,纹理回调会被明显推迟。于是想在尽量少改动的前提下实现分批次回调。

改造后,实际调用如下:

GAssetsMgr.getInstance().enqueue( _ImagePath, _XMLPath ).progress = OnAssetsLoadProgress;
GAssetsMgr.getInstance().loadQueue( null );

 

GAssetsMgr 并不是直接继承AssetManager, 内建一个AssetManager的变量

        private static const LOADING:int=0;
        private static const LOADED:int=1;
        private var _loadDic:Dictionary;
        private var _enqueue:Vector.<Object>;
        private var _enqueueList:Vector.<EnqueueNorm>;
        private var _starlingAMgr:AssetManager;
        private static var _instance:GAssetsMgr;        

定义一封装批次的类, 每更新资源列表时往外传递批次进度

class EnqueueNorm
{
    private var _progress:Function;
    public var enqueue:Vector.<Object> = new Vector.<Object>;
    private var _len:int=-1;
    
    public function set progress($fun:Function):void
    {
        if(0 == enqueue.length) $fun(1);
        else _progress = $fun;
    }
    
    public function appendEnqueueObj($obj:Object):void
    {
        enqueue.push($obj);
    }
    
    public function completeSource($name:String):Boolean
    {
        var isComplete:Boolean=false;
        if(-1 == _len) _len = enqueue.length;
        
        for (var i:int=0; i < enqueue.length; i++)
        {
            if($name == enqueue[i].name) 
            {
                enqueue.splice(i,0);
                break;
            }
        }
        
        if(enqueue.length > 0) 
        {
            if(null != _progress) _progress((_len - enqueue.length)/_len);
        }
        else
        {
            if(null != _progress) _progress(1);
            isComplete = true;
            _progress = null;
        }
        
        return isComplete;
    }
}

每次封装一个批次,并避免重复加载

        public function enqueue(...rawAssets):EnqueueNorm
        {
            var objects:Array =[];
            var rawAsset:Object;
            var eqn:EnqueueNorm = new EnqueueNorm;
            _enqueueList.push(eqn);
            if(rawAsset is Array) 
            {
                enqueue.apply(this, rawAsset);
            }
            else
            {
                for each( rawAsset in rawAssets)
                {
                    if(rawAsset is Array) enqueue.apply(this, rawAsset);
                    else if(rawAsset is String) push2Queue(String(rawAsset), eqn);
                    else objects.push(rawAsset);
                }
                
                if(objects.length > 0) _starlingAMgr.enqueue(objects);
            }
            return eqn;
        }
        
        private function push2Queue($rawAsset:String, $enqueueNorm:EnqueueNorm=null):void
        {
            var obj:Object = {asset:$rawAsset, name:getName($rawAsset)};
            if(LOADED != _loadDic[$rawAsset] && null != $enqueueNorm) $enqueueNorm.appendEnqueueObj(obj);
            
            if(null == _loadDic[$rawAsset])
            {
                _enqueue.push(obj);
                
                _loadDic[$rawAsset] = LOADING;
            }
        }

每加载完一个资源时从各个批次的资源列表里删除引用

            function resume():void
            {
                if(null != currentAssetInfo) completeSource(currentAssetInfo);
                ...
            }
        private function completeSource($assetObj:Object):void
        {
            _loadDic[$assetObj.asset] = LOADED;
            
            var eqn:EnqueueNorm;
            var i:int=0;
            for (; i < _enqueueList.length; i++)
            {
                eqn = _enqueueList[i] as EnqueueNorm;
                if(eqn.completeSource($assetObj.name))
                {
                    _enqueueList.splice(i,1);
                    i--;
                }
            }
        }

so Enjoy it!