Laya 是如何管理资源的?

Laya资源加载类,主要是Loader

所有资源:Loader.loadedMap

贴图资源:Loader.textureMap

c 复制代码
_loadResource(type, url) {
	switch (type) {
		case Loader.IMAGE:
		case "htmlimage":
		case "nativeimage":
			this._loadImage(url);
			break;
		case Loader.SOUND:
			this._loadSound(url);
			break;
		case Loader.TTF:
			this._loadTTF(url);
			break;
		case Loader.ATLAS:
		case Loader.PREFAB:
		case Loader.PLF:
			this._loadHttpRequestWhat(url, Loader.JSON);
			break;
		case Loader.FONT:
			this._loadHttpRequestWhat(url, Loader.XML);
			break;
		case Loader.PLFB:
			this._loadHttpRequestWhat(url, Loader.BUFFER);
			break;
		default:
			this._loadHttpRequestWhat(url, type);
	}
}
//加载完成
complete(data) {
	this._data = data;
	if (this._customParse) {
		this.event(Event.LOADED, data instanceof Array ? [data] : data);
	}
	else {
		Loader._loaders.push(this);
		if (!Loader._isWorking)
			Loader.checkNext();
	}
}
//逐批处理
static checkNext() {
	Loader._isWorking = true;
	var startTimer = Browser.now();
	while (Loader._startIndex < Loader._loaders.length) {
		Loader._loaders[Loader._startIndex].endLoad();
		Loader._startIndex++;
		//如果某一帧处理 超过100毫秒 则停止,下一帧再继续处理
		if (Browser.now() - startTimer > Loader.maxTimeOut) {
			console.warn("loader callback cost a long time:" + (Browser.now() - startTimer) + " url=" + Loader._loaders[Loader._startIndex - 1].url);
			ILaya.systemTimer.frameOnce(1, null, Loader.checkNext);
			return;
		}
	}
	Loader._loaders.length = 0;
	Loader._startIndex = 0;
	Loader._isWorking = false;
}
//分发事件
endLoad(content = null) {
	content && (this._data = content);
	if (this._cache)
		Loader.cacheRes(this._url, this._data);
	this.event(Event.PROGRESS, 1);
	this.event(Event.COMPLETE, this.data instanceof Array ? [this.data] : this.data);
}


//获得
static getRes(url) {
	var res = Loader.textureMap[URL.formatURL(url)];
	if (res)
		return res;
	else
		return Loader.loadedMap[URL.formatURL(url)];
}
static getAtlas(url) {
	return Loader.atlasMap[URL.formatURL(url)];
}
//缓存
static cacheRes(url, data) {
	url = URL.formatURL(url);
	if (Loader.loadedMap[url] != null) {
		console.warn("Resources already exist,is repeated loading:", url);
	}
	else {
		if (data instanceof Texture) {
			Loader.loadedMap[url] = data.bitmap;
			Loader.textureMap[url] = data;
		}
		else {
			Loader.loadedMap[url] = data;
		}
	}
}
//清除
static clearRes(url) {
	url = URL.formatURL(url);
	var arr = Loader.getAtlas(url);
	if (arr) {
		for (var i = 0, n = arr.length; i < n; i++) {
			var resUrl = arr[i];
			var tex = Loader.getRes(resUrl);
			delete Loader.textureMap[resUrl];
			if (tex)
				tex.destroy();
		}
		arr.length = 0;
		delete Loader.atlasMap[url];
	}
	var texture = Loader.textureMap[url];
	if (texture) {
		texture.destroy();
		delete Loader.textureMap[url];
	}
	var res = Loader.loadedMap[url];
	(res) && (delete Loader.loadedMap[url]);
}

资源存取类 Resource

针对Loader资源的一个处理

c 复制代码
class Resource extends EventDispatcher {
	//当前内存,以字节为单位。	 
	static get cpuMemory():number;
	
	//当前显存,以字节为单位。
	static get gpuMemory():number;
	
	//通过资源ID返回已载入资源。
	static getResourceByID(id:number):Resource;
	
	//通过url返回已载入资源。
	static getResourceByURL(url:string,index?:number):Resource;
	
	//销毁当前没有被使用的资源,该函数会忽略lock=true的资源。
	static destroyUnusedResources():void;

	//是否加锁,如果true为不能使用自动释放机制。
	lock:boolean;
	//获取资源的引用计数。
	get referenceCount():number;
	
	//是否已处理。
	get destroyed():boolean;
	//销毁资源,销毁后资源不能恢复。
	destroy():void;
}

Resource销毁

c 复制代码
static destroyUnusedResources() {
	for (var k in Resource._idResourcesMap) {
		var res = Resource._idResourcesMap[k];
		//条件是:锁定为false,引用数量为0
		if (!res.lock && res._referenceCount === 0){
			res.destroy();
		}
			
	}
}

destroy() {
	if (this._destroyed)
		return;
	this._destroyed = true;
	this.lock = false;
	//Resource子级实现
	this._disposeResource();
	//移除全局 source
	delete Resource._idResourcesMap[this.id];
	var resList;
	//_url不为空,表示有贴图,之所以用数组,是因为图集大的有可能超过一张贴图
	if (this._url) {
		resList = Resource._urlResourcesMap[this._url];
		if (resList) {
			resList.splice(resList.indexOf(this), 1);
			(resList.length === 0) && (delete Resource._urlResourcesMap[this._url]);
		}
		//顺便删除Loader 引用
		var resou = ILaya.Loader.loadedMap[this._url];
		(resou == this) && (delete ILaya.Loader.loadedMap[this._url]);
	}
}

Resource存放字典

c 复制代码
	//Key从1开始 value为Resource子类
	Resource._idResourcesMap = {};
	//Key为文件路径 value为Texture2D
	Resource._urlResourcesMap = {};

Resource子类

c 复制代码
1.位图
bitmap:  BaseTexture  HTMLCanvas  HTMLImage
BaseTexture:Texture2D  RenderTexture2D  VideoTexture


2.
BaseShader:Shader
Shader: Shader2X

3.文本
TextTexture
相关推荐
mldong3 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排4 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60614 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角6 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!6 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰6 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi7 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen8 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马9 小时前
AI源码分析:拆解模型底层实现逻辑
前端
BillKu9 小时前
全局样式变量:CSS 自定义属性(--border-color)和SCSS 变量($border-color)的说明
javascript·css·scss