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
相关推荐
崔庆才丨静觅26 分钟前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60611 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了1 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅1 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅2 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅2 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment2 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊3 小时前
jwt介绍
前端
爱敲代码的小鱼3 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax