Unity图片、AssetBundle、GameObject等资源通过path或url加载,避免在内存中重复加载。
该脚本只是管理,由于是采用object类型,所以可用于管理Unity中上述资源。
首次加载过程需要自己实现,可参考FIleGet、HttpGet进行扩展,这两个方法是图片网络、本地加载,回调为加载成功后的资源,需要在回调中进行强制类型转换。
如果不是通过该类进行加载,需要显式调用Reference。例如,调用GameObject.Instantiate后需要调用。
using System;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;
public class MemoryCache : ISingleton
{
public class FuncColl
{
public WeakReference tar;
public Action over;
}
[Serializable]
public class table
{
public bool load;
public string url;
public WeakReference res;
public List tars;
public List> over;
public List funcList;
}
private List cachelist = new List();
private table FindTable(string url)
{
for (int i = 0; i < cachelist.Count; i++)
{
if (url == cachelist[i].url) return cachelist[i];
}
return null;
}
private void push(List list,Object obj)
{
for (int i = 0;i callback,Action> request)
{
if (tar == null) return;
//todo:tar替换素材需要移除,
var tab = FindTable(url);
if (tab != null)
{
if (tab.load)
{
if (tab.res?.Target!=null&&tab.res.Target.ToString()!="null")
{
// push(tab.tars,tar);
callback?.Invoke(tab.res.Target);
return;
}
cachelist.Remove(tab);
}
else
{
//回调已解决,给叽几比个耶。
resetFunc(tar);
tab.funcList.Add(new FuncColl(){over = callback,tar = new WeakReference(tar)});
// push(tab.tars,tar);
return;
}
}
resetFunc(tar);
var item = new table() {url = url,load = false,tars = new List() {},funcList = new List()};
item.funcList.Add(new FuncColl(){over = callback,tar = new WeakReference(tar)});
cachelist.Add(item);
request(oo =>
{
item.res = new WeakReference(oo);
oo = null;
item.load = true;
for (int i = 0; i < item.funcList.Count; i++)
{
item.funcList[i].over?.Invoke( item.res?.Target);
}
item.funcList.Clear();
});
}
public void Reference(string url,Object tar)
{
var tab = FindTable(url);
if (tab != null)
{
if (tab.load)
{
push(tab.tars,tar);
}
}
}
public void Get(string url,Action callback,Action> request)
{
var tab = FindTable(url);
if (tab != null)
{
if (tab.load)
{
if (tab.res?.Target!=null&&tab.res.Target.ToString()!="null")
{
callback?.Invoke(tab.res.Target);
return;
}
cachelist.Remove(tab);
}
else
{
tab.over.Add(callback);
return;
}
}
var item = new table() {url = url,load = false,tars = new List() {},over = new List>(){callback}};
cachelist.Add(item);
request(oo =>
{
item.res = new WeakReference(oo);
oo = null;
item.load = true;
for (int i = 0; i < item.over.Count; i++)
{
item.over[i]?.Invoke( item.res?.Target);
}
item.over.Clear();
});
}
///
/// 不会用,不要调这个方法
///
public void release()
{
bool des;
for (int i = cachelist.Count-1; i >=0 ; i--)
{
des = true;
var ll = cachelist[i].tars;
for (int j = 0; j < ll.Count; j++)
{
if (ll[j] != null&&ll[j].ToString()!="null")
{
des = false; break;
}
}
if (des)
{
if (cachelist[i].res?.Target!=null&&cachelist[i].res.Target.ToString()!="null")
{
Destroy(cachelist[i].res.Target as Object);
}
cachelist.RemoveAt(i);
}
}
}
public List RemoveNoRef()
{
bool des;
var list = new List();
for (int i = cachelist.Count-1; i >=0 ; i--)
{
des = true;
if(!cachelist[i].load)continue;
var ll = cachelist[i].tars;
for (int j = 0; j < ll.Count; j++)
{
if (ll[j] != null&&ll[j].Target != null&&ll[j].Target.ToString()!="null")
{
des = false; break;
}
}
if(des){
list.Add(cachelist[i]);
cachelist.RemoveAt(i);
}
}
return list;
}
public void FileGet(string url,Object tar,Action callback)
{
//和设置点击事件一样,完美
Set(url,tar, callback,
call=>
{
HttpFileHelper.Instance.Texture(url, call);
});
}
public void HttpGet(string url,Object tar,Action callback)
{
Set(url,tar, callback,
call=>
{
HttpFileHelper.Instance.Texture(url, call,null,true);
});
}
///
/// todo:待测试
///
public static void Release()
{
Resources.UnloadUnusedAssets();
System.GC.Collect();
// Instance.release();
}
}