Skip to content

Instantly share code, notes, and snippets.

@sunny352
Last active February 29, 2016 11:08
Show Gist options
  • Save sunny352/d2fba8f3aa5a97e327a7 to your computer and use it in GitHub Desktop.
Save sunny352/d2fba8f3aa5a97e327a7 to your computer and use it in GitHub Desktop.
Unity的web图片管理,自动回收
//#define _Debug_Tools
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public class ImageManager : MonoBehaviour
{
public static void Request(string url, System.Action<Texture2D> callback)
{
Ins.StartCoroutine(Request_impl(url, callback));
}
public static void Release(Texture tex)
{
_TexInfo texInfo = null;
if (m_dict.TryGetValue(tex.name, out texInfo))
{
texInfo.Release();
Debug.LogFormat("Release [{0}]", tex.name);
}
else
{
Destroy(tex);
Debug.LogWarningFormat("Can not find [{0}] in image manager, destroy it now", tex.name);
}
collectTime = 10;
}
private static readonly string ImagePath = "{0}/Image/{1}{2}";
private static IEnumerator Request_impl(string url, System.Action<Texture2D> action)
{
_TexInfo texInfo = null;
if (m_dict.TryGetValue(url, out texInfo))
{
Debug.LogFormat("[{0}] already managed", url);
action(texInfo.Get());
}
else
{
var ext = Path.GetExtension(url);
string fileName = HashTools.GenMD5String(url);
string path = string.Format(ImagePath, Application.persistentDataPath, fileName, ext);
if (File.Exists(path))
{
Debug.LogFormat("Exist {0}", path);
WWW request = new WWW("file://" + path);
yield return request;
texInfo = new _TexInfo(request.texture, url);
m_dict.Add(url, texInfo);
action(texInfo.Get());
}
else
{
Debug.LogFormat("Not exist {0}", url);
WWW request = new WWW(url);
yield return request;
if (!string.IsNullOrEmpty(request.error))
{
action(null);
yield break;
}
Directory.CreateDirectory(Application.persistentDataPath + "/Image");
File.WriteAllBytes(path, request.bytes);
texInfo = new _TexInfo(request.texture, url);
m_dict.Add(url, texInfo);
action(texInfo.Get());
}
}
}
private class _TexInfo
{
private Texture2D texture;
public int usingCount { get; private set; }
public int usedCount { get; private set; }
public _TexInfo(Texture2D tex, string url)
{
texture = tex;
texture.name = url;
}
public Texture2D Get()
{
++usingCount;
++usedCount;
return texture;
}
public void Release()
{
--usingCount;
}
}
private static Dictionary<string, _TexInfo> m_dict = new Dictionary<string, _TexInfo>();
private static ImageManager _ins;
private static ImageManager Ins
{
get
{
if (null == _ins)
{
GameObject mgr = new GameObject("_ImageManager");
_ins = mgr.AddComponent<ImageManager>();
}
return _ins;
}
set
{
_ins = value;
}
}
#if _Debug_Tools
#if UNITY_EDITOR
public int nextCollect = 0;
private IEnumerator TimeCollect()
{
nextCollect = collectTime;
int count = collectTime;
int pre = nextCollect;
for (int index = 0; index < count; ++index)
{
if (pre != nextCollect)
{
break;
}
nextCollect--;
pre = nextCollect;
yield return new WaitForSeconds(1.0f);
}
}
#endif
#endif
private static int collectTime = 10;
void Start()
{
StartCoroutine(Collect());
}
private static IEnumerator Collect()
{
for (bool removed = false; ;)
{
foreach (var pair in m_dict)
{
if (pair.Value.usingCount == 0)
{
m_dict.Remove(pair.Key);
removed = true;
Destroy(pair.Value.Get());
Debug.LogFormat("Destroy {0}", pair.Key);
break;
}
}
if (removed)
{
removed = false;
collectTime = 0;
yield return new WaitForEndOfFrame();
}
else
{
#if _Debug_Tools
#if UNITY_EDITOR
collectTime = 10;
Ins.StartCoroutine(Ins.TimeCollect());
#endif
#else
collectTime = Mathf.Clamp(collectTime + 1, 10, 30);
#endif
yield return new WaitForSeconds(collectTime);
}
}
}
public static void ForceCollect()
{
Ins.StartCoroutine(ForceCollect_impl());
}
private static IEnumerator ForceCollect_impl()
{
Debug.Log("Force collect textures memory");
for (bool removed = false; !removed;)
{
foreach (var pair in m_dict)
{
if (pair.Value.usingCount == 0)
{
m_dict.Remove(pair.Key);
removed = true;
Destroy(pair.Value.Get());
Debug.LogFormat("Destroy {0}", pair.Key);
break;
}
}
yield return new WaitForEndOfFrame();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment