228 lines
6.9 KiB
C#
228 lines
6.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text.RegularExpressions;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.Networking;
|
|
|
|
namespace WeChatWASM.MDV
|
|
{
|
|
public class HandlerImages
|
|
{
|
|
public string CurrentPath;
|
|
|
|
Texture mPlaceholder = null;
|
|
List<ImageRequest> mActiveRequests = new List<ImageRequest>();
|
|
Dictionary<string,Texture> mTextureCache = new Dictionary<string, Texture>();
|
|
List<AnimatedTexture> mAnimatedTextures = new List<AnimatedTexture>();
|
|
|
|
class AnimatedTexture
|
|
{
|
|
public string URL = string.Empty;
|
|
public int CurrentFrame = 0;
|
|
public double FrameTime = 0.0f;
|
|
public List<Texture2D> Textures = new List<Texture2D>();
|
|
public List<float> Times = new List<float>();
|
|
|
|
public AnimatedTexture( string url )
|
|
{
|
|
URL = url;
|
|
FrameTime = EditorApplication.timeSinceStartup;
|
|
}
|
|
|
|
public void Add( Texture2D tex, float delay )
|
|
{
|
|
Textures.Add( tex );
|
|
Times.Add( delay );
|
|
}
|
|
|
|
public bool Update()
|
|
{
|
|
var span = EditorApplication.timeSinceStartup - FrameTime;
|
|
|
|
if( span < Times[ CurrentFrame ] )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
FrameTime = EditorApplication.timeSinceStartup;
|
|
CurrentFrame = ( CurrentFrame + 1 ) % Textures.Count;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
class ImageRequest
|
|
{
|
|
public string URL; // original url
|
|
public UnityWebRequest Request;
|
|
public bool IsGif;
|
|
|
|
public ImageRequest( string url )
|
|
{
|
|
URL = url;
|
|
|
|
if( url.EndsWith( ".gif", System.StringComparison.OrdinalIgnoreCase ) )
|
|
{
|
|
IsGif = true;
|
|
Request = UnityWebRequest.Get( url );
|
|
}
|
|
else
|
|
{
|
|
IsGif = false;
|
|
Request = UnityWebRequestTexture.GetTexture( url );
|
|
}
|
|
|
|
Request.SendWebRequest();
|
|
}
|
|
|
|
public AnimatedTexture GetAnimatedTexture()
|
|
{
|
|
var decoder = new MG.GIF.Decoder( Request.downloadHandler.data );
|
|
var img = decoder.NextImage();
|
|
var anim = new AnimatedTexture( URL );
|
|
|
|
while( img != null )
|
|
{
|
|
anim.Add( img.CreateTexture(), img.Delay / 1000.0f );
|
|
img = decoder.NextImage();
|
|
}
|
|
|
|
return anim;
|
|
}
|
|
|
|
public Texture GetTexture()
|
|
{
|
|
var handler = Request.downloadHandler as DownloadHandlerTexture;
|
|
return handler != null ? handler.texture : null;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
private string RemapURL( string url )
|
|
{
|
|
if( Regex.IsMatch( url, @"^\w+:", RegexOptions.Singleline ) )
|
|
{
|
|
return url;
|
|
}
|
|
|
|
var projectDir = Path.GetDirectoryName( Application.dataPath );
|
|
|
|
if( url.StartsWith( "/" ) )
|
|
{
|
|
return string.Format( "file:///{0}{1}", projectDir, url );
|
|
}
|
|
|
|
var assetDir = Path.GetDirectoryName( CurrentPath );
|
|
return "file:///" + Utils.PathNormalise( string.Format( "{0}/{1}/{2}", projectDir, assetDir, url ) );
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
public Texture FetchImage( string url )
|
|
{
|
|
url = RemapURL( url );
|
|
|
|
Texture tex;
|
|
|
|
if( mTextureCache.TryGetValue( url, out tex ) )
|
|
{
|
|
return tex;
|
|
}
|
|
|
|
if( mPlaceholder == null )
|
|
{
|
|
var style = GUI.skin.GetStyle( "btnPlaceholder" );
|
|
mPlaceholder = style != null ? style.normal.background : null;
|
|
}
|
|
|
|
mActiveRequests.Add( new ImageRequest( url ) );
|
|
mTextureCache[ url ] = mPlaceholder;
|
|
|
|
return mPlaceholder;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
public bool UpdateRequests()
|
|
{
|
|
var req = mActiveRequests.Find( r => r.Request.isDone );
|
|
|
|
if( req == null )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#if UNITY_2020_2_OR_NEWER
|
|
if( req.Request.result == UnityWebRequest.Result.ProtocolError )
|
|
#else
|
|
if( req.Request.isHttpError )
|
|
#endif
|
|
{
|
|
Debug.LogError( string.Format( "HTTP Error: {0} - {1} {2}", req.URL, req.Request.responseCode, req.Request.error ) );
|
|
mTextureCache[ req.URL ] = null;
|
|
}
|
|
#if UNITY_2020_2_OR_NEWER
|
|
else if( req.Request.result == UnityWebRequest.Result.ConnectionError )
|
|
#else
|
|
else if( req.Request.isNetworkError )
|
|
#endif
|
|
{
|
|
Debug.LogError( string.Format( "Network Error: {0} - {1}", req.URL, req.Request.error ) );
|
|
mTextureCache[ req.URL ] = null;
|
|
}
|
|
else if( req.IsGif )
|
|
{
|
|
var anim = req.GetAnimatedTexture();
|
|
|
|
if( anim != null && anim.Textures.Count > 0 )
|
|
{
|
|
mTextureCache[ req.URL ] = anim.Textures[ 0 ];
|
|
|
|
if( anim.Textures.Count > 1 )
|
|
{
|
|
mAnimatedTextures.Add( anim );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mTextureCache[ req.URL ] = req.GetTexture();
|
|
}
|
|
|
|
mActiveRequests.Remove( req );
|
|
return true;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
public bool UpdateAnimations()
|
|
{
|
|
var update = false;
|
|
|
|
foreach( var anim in mAnimatedTextures )
|
|
{
|
|
if( anim.Update() )
|
|
{
|
|
mTextureCache[ anim.URL ] = anim.Textures[ anim.CurrentFrame ];
|
|
update = true;
|
|
}
|
|
}
|
|
|
|
return update;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
public bool Update()
|
|
{
|
|
return UpdateRequests() || UpdateAnimations();
|
|
}
|
|
}
|
|
}
|