简单改造 starling 中的 AssetManager 让其更适合 批次加载纹理
Posted on 2013-08-10 21:41 bobolive 阅读(1008) 评论(0) 编辑 收藏 举报
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!