Last active
February 29, 2016 11:08
-
-
Save sunny352/d2fba8f3aa5a97e327a7 to your computer and use it in GitHub Desktop.
Unity的web图片管理,自动回收
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//#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