diff --git a/Davinci/Assets/Davinci/Scripts/Davinci.cs b/Davinci/Assets/Davinci/Scripts/Davinci.cs
index 3932a00..9ccce7c 100644
--- a/Davinci/Assets/Davinci/Scripts/Davinci.cs
+++ b/Davinci/Assets/Davinci/Scripts/Davinci.cs
@@ -2,658 +2,269 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
+using System.Security.Cryptography;
using System.Text;
using UnityEngine;
using UnityEngine.Events;
-using UnityEngine.UI;
-#if UNITY_2018_3_OR_NEWER
using UnityEngine.Networking;
-#endif
+using UnityEngine.UI;
///
/// Davinci - A powerful, esay-to-use image downloading and caching library for Unity in Run-Time
-/// v 1.2
+/// v 2.0
/// Developed by ShamsDEV.com
+/// Modified by NyanHeavy.app
/// copyright (c) ShamsDEV.com All Rights Reserved.
/// Licensed under the MIT License.
/// https://github.com/shamsdev/davinci
///
public class Davinci : MonoBehaviour
{
- private static bool ENABLE_GLOBAL_LOGS = true;
-
- private bool enableLog = false;
- private float fadeTime = 1;
- private bool cached = true;
+ private static Davinci _instance;
+ private static string filePath;
- private enum RendererType
+ public static Davinci Get()
{
- none,
- uiImage,
- renderer,
- sprite
- }
-
- private RendererType rendererType = RendererType.none;
- private GameObject targetObj;
- private string url = null;
-
- private Texture2D loadingPlaceholder, errorPlaceholder;
-
- private UnityAction onStartAction,
- onDownloadedAction,
- OnLoadedAction,
- onEndAction;
-
- private UnityAction onDownloadProgressChange;
- private UnityAction onErrorAction;
-
- private static Dictionary underProcessDavincies
- = new Dictionary();
-
- private string uniqueHash;
- private int progress;
-
- private bool success = false;
-
- static string filePath = Application.persistentDataPath + "/" +
- "davinci" + "/";
-
+ if (_instance == null)
+ {
+ GameObject go = new("Davinci");
+ _instance = go.AddComponent();
+ DontDestroyOnLoad(go);
+ filePath = Path.Combine(Application.persistentDataPath, "davinci");
+ if (!Directory.Exists(filePath)) Directory.CreateDirectory(filePath);
+ }
- ///
- /// Get instance of davinci class
- ///
- public static Davinci get()
- {
- return new GameObject("Davinci").AddComponent();
+ //Return a NEW request instead of resetting a single instance
+ return _instance;
}
///
- /// Set image url for download.
+ /// Entry point for creating a new individual request.
///
- /// Image Url
- ///
- public Davinci load(string url)
+ public DavinciRequest Download(string url)
{
- if (enableLog)
- Debug.Log("[Davinci] Url set : " + url);
-
- this.url = url;
- return this;
+ return new DavinciRequest(this, url, filePath);
}
- ///
- /// Set fading animation time.
- ///
- /// Fade animation time. Set 0 for disable fading.
- ///
- public Davinci setFadeTime(float fadeTime)
- {
- if (enableLog)
- Debug.Log("[Davinci] Fading time set : " + fadeTime);
+ // Shortcut to maintain compatibility with your old code if desired.
+ public DavinciRequest Load(string url) => Download(url);
- this.fadeTime = fadeTime;
- return this;
+ public static string CreateMD5(string input)
+ {
+ using MD5 md5 = MD5.Create();
+ byte[] hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
+ StringBuilder sb = new();
+ for (int i = 0; i < hashBytes.Length; i++)
+ {
+ sb.Append(hashBytes[i].ToString("x2"));
+ }
+ return sb.ToString();
}
- ///
- /// Set target Image component.
- ///
- /// target Unity UI image component
- ///
- public Davinci into(Image image)
+ public static void ClearAllCachedFiles()
{
- if (enableLog)
- Debug.Log("[Davinci] Target as UIImage set : " + image);
-
- rendererType = RendererType.uiImage;
- this.targetObj = image.gameObject;
- return this;
+ if (Directory.Exists(filePath)) Directory.Delete(filePath, true);
}
///
- /// Set target Renderer component.
+ /// Return size of Davinci Cache files
///
- /// target renderer component
- ///
- public Davinci into(Renderer renderer)
+ public static string GetCacheSize()
{
- if (enableLog)
- Debug.Log("[Davinci] Target as Renderer set : " + renderer);
-
- rendererType = RendererType.renderer;
- this.targetObj = renderer.gameObject;
- return this;
+ filePath = Path.Combine(Application.persistentDataPath, "davinci");
+ if (!Directory.Exists(filePath)) return "0 KBs";
+ long bytes = GetDirectorySize(new DirectoryInfo(filePath));
+ return FormatBytes(bytes);
}
- public Davinci into(SpriteRenderer spriteRenderer)
+ private static long GetDirectorySize(DirectoryInfo dir)
{
- if (enableLog)
- Debug.Log("[Davinci] Target as SpriteRenderer set : " + spriteRenderer);
-
- rendererType = RendererType.sprite;
- this.targetObj = spriteRenderer.gameObject;
- return this;
- }
-
- #region Actions
- public Davinci withStartAction(UnityAction action)
- {
- this.onStartAction = action;
-
- if (enableLog)
- Debug.Log("[Davinci] On start action set : " + action);
-
- return this;
+ long size = 0;
+ foreach (FileInfo file in dir.GetFiles())
+ {
+ size += file.Length;
+ }
+ return size;
}
- public Davinci withDownloadedAction(UnityAction action)
+ private static string FormatBytes(long bytes)
{
- this.onDownloadedAction = action;
+ string[] Suffix = { "Bytes", "KB", "MB", "GB", "TB" };
+ int i;
+ double dblSByte = bytes;
- if (enableLog)
- Debug.Log("[Davinci] On downloaded action set : " + action);
+ for (i = 0; i < Suffix.Length && bytes >= 1024; i++, bytes /= 1024)
+ {
+ dblSByte = bytes / 1024.0;
+ }
- return this;
+ return string.Format("{0:0.##} {1}", dblSByte, Suffix[i]);
}
+}
- public Davinci withDownloadProgressChangedAction(UnityAction action)
- {
- this.onDownloadProgressChange = action;
-
- if (enableLog)
- Debug.Log("[Davinci] On download progress changed action set : " + action);
-
- return this;
- }
+///
+/// A class that stores the data for a specific request.
+///
+public class DavinciRequest
+{
+ private Davinci manager;
+ private string url;
+ private string cachePath;
- public Davinci withLoadedAction(UnityAction action)
- {
- this.OnLoadedAction = action;
+ private bool enableLog = false;
+ private float fadeTime = 0f;
+ private bool cached = true;
+ private GameObject targetObj;
+ private Texture2D loadingPlaceholder, errorPlaceholder;
+ private RendererType rendererType = RendererType.none;
- if (enableLog)
- Debug.Log("[Davinci] On loaded action set : " + action);
+ private UnityAction onStartAction, onDownloadedAction, onLoadedAction, onEndAction;
+ private UnityAction onDownloadProgressChange;
+ private UnityAction onErrorAction;
- return this;
- }
+ private enum RendererType { none, uiImage, renderer }
- public Davinci withErrorAction(UnityAction action)
+ public DavinciRequest(Davinci manager, string url, string cacheFolder)
{
- this.onErrorAction = action;
-
- if (enableLog)
- Debug.Log("[Davinci] On error action set : " + action);
-
- return this;
+ this.manager = manager;
+ this.url = url;
+ this.cachePath = cacheFolder;
}
- public Davinci withEndAction(UnityAction action)
- {
- this.onEndAction = action;
-
- if (enableLog)
- Debug.Log("[Davinci] On end action set : " + action);
-
- return this;
- }
+ #region Settings
+ public DavinciRequest Into(Image image) { rendererType = RendererType.uiImage; targetObj = image.gameObject; return this; }
+ public DavinciRequest Into(Renderer renderer) { rendererType = RendererType.renderer; targetObj = renderer.gameObject; return this; }
+ public DavinciRequest SetFadeTime(float time) { fadeTime = time; return this; }
+ public DavinciRequest SetCached(bool enable) { cached = enable; return this; }
+ public DavinciRequest SetEnableLog(bool enable) { enableLog = enable; return this; }
+ public DavinciRequest SetLoadingPlaceholder(Texture2D p) { loadingPlaceholder = p; return this; }
+ public DavinciRequest SetErrorPlaceholder(Texture2D p) { errorPlaceholder = p; return this; }
+ public DavinciRequest WithStartAction(UnityAction a) { onStartAction = a; return this; }
+ public DavinciRequest WithLoadedAction(UnityAction a) { onLoadedAction = a; return this; }
+ public DavinciRequest WithErrorAction(UnityAction a) { onErrorAction = a; return this; }
+ public DavinciRequest WithEndAction(UnityAction a) { onEndAction = a; return this; }
#endregion
- ///
- /// Show or hide logs in console.
- ///
- /// 'true' for show logs in console.
- ///
- public Davinci setEnableLog(bool enableLog)
- {
- this.enableLog = enableLog;
-
- if (enableLog)
- Debug.Log("[Davinci] Logging enabled : " + enableLog);
-
- return this;
- }
-
- ///
- /// Set the sprite of image when davinci is downloading and loading image
- ///
- /// loading texture
- ///
- public Davinci setLoadingPlaceholder(Texture2D loadingPlaceholder)
+ public void Init()
{
- this.loadingPlaceholder = loadingPlaceholder;
-
- if (enableLog)
- Debug.Log("[Davinci] Loading placeholder has been set.");
+ if (string.IsNullOrEmpty(url)) { Error("Empty URL."); return; }
+ if (targetObj == null) { Error("Target null."); return; }
- return this;
- }
-
- ///
- /// Set image sprite when some error occurred during downloading or loading image
- ///
- /// error texture
- ///
- public Davinci setErrorPlaceholder(Texture2D errorPlaceholder)
- {
- this.errorPlaceholder = errorPlaceholder;
-
- if (enableLog)
- Debug.Log("[Davinci] Error placeholder has been set.");
-
- return this;
- }
-
- ///
- /// Enable cache
- ///
- ///
- public Davinci setCached(bool cached)
- {
- this.cached = cached;
+ string uniqueHash = Davinci.CreateMD5(url);
+ string fullPath = Path.Combine(cachePath, uniqueHash);
- if (enableLog)
- Debug.Log("[Davinci] Cache enabled : " + cached);
+ if (loadingPlaceholder != null) SetPlaceholder(loadingPlaceholder);
+ onStartAction?.Invoke();
- return this;
+ // Initiates coroutine in the global instance of Da Vinci, allowing multiple instances.
+ manager.StartCoroutine(ProcessImage(fullPath));
}
- ///
- /// Start davinci process.
- ///
- public void start()
+ private IEnumerator ProcessImage(string fullPath)
{
- if (url == null)
- {
- error("Url has not been set. Use 'load' funtion to set image url.");
- return;
- }
-
- try
- {
- Uri uri = new Uri(url);
- this.url = uri.AbsoluteUri;
- }
- catch (Exception ex)
- {
- error("Url is not correct.");
- return;
- }
-
- if (rendererType == RendererType.none || targetObj == null)
- {
- error("Target has not been set. Use 'into' function to set target component.");
- return;
- }
-
- if (enableLog)
- Debug.Log("[Davinci] Start Working.");
-
- if (loadingPlaceholder != null)
- SetLoadingImage();
-
- if (onStartAction != null)
- onStartAction.Invoke();
-
- if (!Directory.Exists(filePath))
- {
- Directory.CreateDirectory(filePath);
- }
-
- uniqueHash = CreateMD5(url);
-
- if (underProcessDavincies.ContainsKey(uniqueHash))
+ yield return new WaitForEndOfFrame();
+ if (File.Exists(fullPath) && cached)
{
- Davinci sameProcess = underProcessDavincies[uniqueHash];
- sameProcess.onDownloadedAction += () =>
- {
- if (onDownloadedAction != null)
- onDownloadedAction.Invoke();
-
- loadSpriteToImage();
- };
+ if (enableLog) Debug.Log($"[Davinci] Cache found: {url}");
+ yield return LoadFromDisk(fullPath);
}
else
{
- if (File.Exists(filePath + uniqueHash))
- {
- if (onDownloadedAction != null)
- onDownloadedAction.Invoke();
-
- loadSpriteToImage();
- }
- else
- {
- underProcessDavincies.Add(uniqueHash, this);
- StopAllCoroutines();
- StartCoroutine("Downloader");
- }
+ yield return DownloadFromWeb(fullPath);
}
}
- private IEnumerator Downloader()
+ private IEnumerator DownloadFromWeb(string savePath)
{
- if (enableLog)
- Debug.Log("[Davinci] Download started.");
+ using UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
+ UnityWebRequestAsyncOperation operation = www.SendWebRequest();
-#if UNITY_2018_3_OR_NEWER
- UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
- yield return www.SendWebRequest();
-#else
- var www = new WWW(url);
-#endif
-
- while (!www.isDone)
+ while (!operation.isDone)
{
- if (www.error != null)
- {
- error("Error while downloading the image : " + www.error);
- yield break;
- }
-
-#if UNITY_2018_3_OR_NEWER
- progress = Mathf.FloorToInt(www.downloadProgress * 100);
-#else
- progress = Mathf.FloorToInt(www.progress * 100);
-#endif
- if (onDownloadProgressChange != null)
- onDownloadProgressChange.Invoke(progress);
-
- if (enableLog)
- Debug.Log("[Davinci] Downloading progress : " + progress + "%");
-
+ int progress = Mathf.FloorToInt(www.downloadProgress * 100);
+ onDownloadProgressChange?.Invoke(progress);
yield return null;
}
-#if UNITY_2018_3_OR_NEWER
- if (www.error == null)
- File.WriteAllBytes(filePath + uniqueHash, www.downloadHandler.data);
-#else
- if (www.error == null)
- File.WriteAllBytes(filePath + uniqueHash, www.bytes);
-#endif
-
- www.Dispose();
- www = null;
-
- if (onDownloadedAction != null)
- onDownloadedAction.Invoke();
-
- loadSpriteToImage();
-
- underProcessDavincies.Remove(uniqueHash);
- }
-
- private void loadSpriteToImage()
- {
- progress = 100;
- if (onDownloadProgressChange != null)
- onDownloadProgressChange.Invoke(progress);
-
- if (enableLog)
- Debug.Log("[Davinci] Downloading progress : " + progress + "%");
-
- if (!File.Exists(filePath + uniqueHash))
+ if (www.result != UnityWebRequest.Result.Success)
{
- error("Loading image file has been failed.");
- return;
+ Error($"Download Error: {www.error}");
+ yield break;
}
- StopAllCoroutines();
- StartCoroutine(ImageLoader());
+ if (cached) File.WriteAllBytes(savePath, www.downloadHandler.data);
+ onDownloadedAction?.Invoke();
+ Texture2D tex = DownloadHandlerTexture.GetContent(www);
+ yield return ApplyTexture(tex);
}
- private void SetLoadingImage()
+ private IEnumerator LoadFromDisk(string path)
{
- switch (rendererType)
- {
- case RendererType.renderer:
- Renderer renderer = targetObj.GetComponent();
- renderer.material.mainTexture = loadingPlaceholder;
- break;
-
- case RendererType.uiImage:
- Image image = targetObj.GetComponent();
- Sprite sprite = Sprite.Create(loadingPlaceholder,
- new Rect(0, 0, loadingPlaceholder.width, loadingPlaceholder.height),
- new Vector2(0.5f, 0.5f));
- image.sprite = sprite;
-
- break;
-
- case RendererType.sprite:
- SpriteRenderer spriteRenderer = targetObj.GetComponent();
- Sprite spriteImage = Sprite.Create(loadingPlaceholder,
- new Rect(0, 0, loadingPlaceholder.width, loadingPlaceholder.height),
- new Vector2(0.5f, 0.5f));
-
- spriteRenderer.sprite = spriteImage;
- break;
- }
-
+ byte[] data = File.ReadAllBytes(path);
+ Texture2D tex = new(2, 2);
+ tex.LoadImage(data);
+ yield return ApplyTexture(tex);
}
- private IEnumerator ImageLoader(Texture2D texture = null)
+ private IEnumerator ApplyTexture(Texture2D tex)
{
- if (enableLog)
- Debug.Log("[Davinci] Start loading image.");
+ if (targetObj == null) yield break;
- if (texture == null)
+ if (rendererType == RendererType.uiImage && targetObj.TryGetComponent(out var img))
{
- byte[] fileData;
- fileData = File.ReadAllBytes(filePath + uniqueHash);
- texture = new Texture2D(2, 2);
- //ImageConversion.LoadImage(texture, fileData);
- texture.LoadImage(fileData); //..this will auto-resize the texture dimensions.
+ img.sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
+ img.sprite.name = GetFileNameFromUrl(url);
+ onLoadedAction?.Invoke();
+ if (fadeTime > 0) yield return FadeEffect(img);
}
-
- Color color;
-
- if (targetObj != null)
- switch (rendererType)
- {
- case RendererType.renderer:
- Renderer renderer = targetObj.GetComponent();
-
- if (renderer == null || renderer.material == null)
- break;
-
- renderer.material.mainTexture = texture;
- float maxAlpha;
-
- if (fadeTime > 0 && renderer.material.HasProperty("_Color"))
- {
- color = renderer.material.color;
- maxAlpha = color.a;
-
- color.a = 0;
-
- renderer.material.color = color;
- float time = Time.time;
- while (color.a < maxAlpha)
- {
- color.a = Mathf.Lerp(0, maxAlpha, (Time.time - time) / fadeTime);
-
- if (renderer != null)
- renderer.material.color = color;
-
- yield return null;
- }
- }
-
- break;
-
- case RendererType.uiImage:
- Image image = targetObj.GetComponent();
-
- if (image == null)
- break;
-
- Sprite sprite = Sprite.Create(texture,
- new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
-
- image.sprite = sprite;
- color = image.color;
- maxAlpha = color.a;
-
- if (fadeTime > 0)
- {
- color.a = 0;
- image.color = color;
-
- float time = Time.time;
- while (color.a < maxAlpha)
- {
- color.a = Mathf.Lerp(0, maxAlpha, (Time.time - time) / fadeTime);
-
- if (image != null)
- image.color = color;
- yield return null;
- }
- }
- break;
-
- case RendererType.sprite:
- SpriteRenderer spriteRenderer = targetObj.GetComponent();
-
- if (spriteRenderer == null)
- break;
-
- Sprite spriteImage = Sprite.Create(texture,
- new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
-
- spriteRenderer.sprite = spriteImage;
- color = spriteRenderer.color;
- maxAlpha = color.a;
-
- if (fadeTime > 0)
- {
- color.a = 0;
- spriteRenderer.color = color;
-
- float time = Time.time;
- while (color.a < maxAlpha)
- {
- color.a = Mathf.Lerp(0, maxAlpha, (Time.time - time) / fadeTime);
-
- if (spriteRenderer != null)
- spriteRenderer.color = color;
- yield return null;
- }
- }
- break;
- }
-
- if (OnLoadedAction != null)
- OnLoadedAction.Invoke();
-
- if (enableLog)
- Debug.Log("[Davinci] Image has been loaded.");
-
- success = true;
- finish();
- }
-
- public static string CreateMD5(string input)
- {
- // Use input string to calculate MD5 hash
- using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
+ else if (rendererType == RendererType.renderer && targetObj.TryGetComponent(out var rend))
{
- byte[] inputBytes = Encoding.ASCII.GetBytes(input);
- byte[] hashBytes = md5.ComputeHash(inputBytes);
-
- // Convert the byte array to hexadecimal string
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < hashBytes.Length; i++)
- {
- sb.Append(hashBytes[i].ToString("X2"));
- }
- return sb.ToString();
+ rend.material.mainTexture = tex;
+ onLoadedAction?.Invoke();
+ if (fadeTime > 0) yield return FadeEffect(rend);
}
- }
-
- private void error(string message)
- {
- success = false;
-
- if (enableLog)
- Debug.LogError("[Davinci] Error : " + message);
-
- if (onErrorAction != null)
- onErrorAction.Invoke(message);
-
- if (errorPlaceholder != null)
- StartCoroutine(ImageLoader(errorPlaceholder));
- else finish();
- }
-
- private void finish()
- {
- if (enableLog)
- Debug.Log("[Davinci] Operation has been finished.");
-
- if (!cached)
+ else
{
- try
- {
- File.Delete(filePath + uniqueHash);
- }
- catch (Exception ex)
- {
- if (enableLog)
- Debug.LogError($"[Davinci] Error while removing cached file: {ex.Message}");
- }
+ onLoadedAction?.Invoke();
}
- if (onEndAction != null)
- onEndAction.Invoke();
-
- Invoke("destroyer", 0.5f);
+ onEndAction?.Invoke();
}
- private void destroyer()
+ private string GetFileNameFromUrl(string url)
{
- Destroy(gameObject);
+ return Path.GetFileNameWithoutExtension(url);
}
-
- ///
- /// Clear a certain cached file with its url
- ///
- /// Cached file url.
- ///
- public static void ClearCache(string url)
+ private IEnumerator FadeEffect(object component)
{
- try
+ float elapsed = 0;
+ while (elapsed < fadeTime)
{
- File.Delete(filePath + CreateMD5(url));
+ if (targetObj == null) yield break;
+ elapsed += Time.deltaTime;
+ float alpha = Mathf.Lerp(0, 1, elapsed / fadeTime);
- if (ENABLE_GLOBAL_LOGS)
- Debug.Log($"[Davinci] Cached file has been cleared: {url}");
- }
- catch (Exception ex)
- {
- if (ENABLE_GLOBAL_LOGS)
- Debug.LogError($"[Davinci] Error while removing cached file: {ex.Message}");
+ if (component is Image img) { Color c = img.color; c.a = alpha; img.color = c; }
+ else if (component is Renderer rend) { Color c = rend.material.color; c.a = alpha; rend.material.color = c; }
+ yield return null;
}
}
- ///
- /// Clear all davinci cached files
- ///
- ///
- public static void ClearAllCachedFiles()
+ private void SetPlaceholder(Texture2D tex)
{
- try
- {
- Directory.Delete(filePath, true);
+ if (targetObj == null) return;
+ if (rendererType == RendererType.uiImage)
+ targetObj.GetComponent().sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
+ else if (rendererType == RendererType.renderer)
+ targetObj.GetComponent().material.mainTexture = tex;
+ }
- if (ENABLE_GLOBAL_LOGS)
- Debug.Log("[Davinci] All Davinci cached files has been cleared.");
- }
- catch (Exception ex)
- {
- if (ENABLE_GLOBAL_LOGS)
- Debug.LogError($"[Davinci] Error while removing cached file: {ex.Message}");
- }
+ private void Error(string msg)
+ {
+ if (enableLog) Debug.LogError($"[Davinci] {msg}");
+ onErrorAction?.Invoke(msg);
+ if (errorPlaceholder != null) SetPlaceholder(errorPlaceholder);
+ onEndAction?.Invoke();
}
-}
\ No newline at end of file
+}