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
相关推荐
石小石Orz3 小时前
我发现了开发者AI产品营收的新方向
前端·虚拟现实
老马识途2.03 小时前
关于跨域问题的总结
java·前端
魔力女仆3 小时前
分享一个 JS 鼠标跟随贪吃蛇背景库
开发语言·javascript·计算机外设
别惊醒渔人5 小时前
Vue3 Diff 优化:最长递增子序列 LIS
前端·javascript·vue.js
颜酱5 小时前
07 | 把字段与指标同步到 Qdrant(生成阶段)
前端·人工智能·后端
用户059540174465 小时前
把AI长期记忆测试从手动验证换成pytest,2天揪出11个隐藏Bug
前端·css
Larcher5 小时前
从“加载模型”界面到端侧推理:拆解一个 React + WebGPU 大模型 Demo
javascript·后端
Larcher6 小时前
从状态快照到惰性初始化:读懂 React useState 的三个关键场景
javascript·人工智能·后端
lichenyang4536 小时前
从 Vite 空项目到 AIGC 图片工作台:我如何打通生图、任务轮询、生成库与 Canvas 动态特效
前端·人工智能
泡沫冰@6 小时前
上章节中文件的讲解
前端·网络·nginx