Firstborn/Library/PackageCache/com.unity.addressables@1.19.19/Runtime/ResourceManager/ResourceProviders/TextDataProvider.cs
Schaken-Mods 7502018d20 Adding Mod Support
There is an asset in the store I grabbed. the coding is WAY above my head, I got about half of it and integrated and adapted what I can to it. im going as far as I can with it and ill come back in a few month when I understand t better.
2023-05-13 22:01:48 -05:00

198 lines
7.8 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.Exceptions;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.Util;
namespace UnityEngine.ResourceManagement.ResourceProviders
{
/// <summary>
/// Provides raw text from a local or remote URL.
/// </summary>
[DisplayName("Text Data Provider")]
public class TextDataProvider : ResourceProviderBase
{
/// <summary>
/// Controls whether errors are logged - this is disabled when trying to load from the local cache since failures are expected
/// </summary>
public bool IgnoreFailures { get; set; }
internal class InternalOp
{
TextDataProvider m_Provider;
UnityWebRequestAsyncOperation m_RequestOperation;
WebRequestQueueOperation m_RequestQueueOperation;
ProvideHandle m_PI;
bool m_IgnoreFailures;
private bool m_Complete = false;
private int m_Timeout = 0;
private float GetPercentComplete() { return m_RequestOperation != null ? m_RequestOperation.progress : 0.0f; }
public void Start(ProvideHandle provideHandle, TextDataProvider rawProvider)
{
m_PI = provideHandle;
m_PI.SetWaitForCompletionCallback(WaitForCompletionHandler);
provideHandle.SetProgressCallback(GetPercentComplete);
m_Provider = rawProvider;
// override input options with options from Location if included
if (m_PI.Location.Data is ProviderLoadRequestOptions providerData)
{
m_IgnoreFailures = providerData.IgnoreFailures;
m_Timeout = providerData.WebRequestTimeout;
}
else
{
m_IgnoreFailures = rawProvider.IgnoreFailures;
m_Timeout = 0;
}
var path = m_PI.ResourceManager.TransformInternalId(m_PI.Location);
if (ResourceManagerConfig.ShouldPathUseWebRequest(path))
{
SendWebRequest(path);
}
else if (File.Exists(path))
{
#if NET_4_6
if (path.Length >= 260)
path = @"\\?\" + path;
#endif
var text = File.ReadAllText(path);
object result = ConvertText(text);
m_PI.Complete(result, result != null, result == null ? new Exception($"Unable to load asset of type {m_PI.Type} from location {m_PI.Location}.") : null);
m_Complete = true;
}
else
{
Exception exception = null;
//Don't log errors when loading from the persistentDataPath since these files are expected to not exist until created
if (m_IgnoreFailures)
{
m_PI.Complete<object>(null, true, exception);
m_Complete = true;
}
else
{
exception = new Exception(string.Format("Invalid path in " + nameof(TextDataProvider) + " : '{0}'.", path));
m_PI.Complete<object>(null, false, exception);
m_Complete = true;
}
}
}
bool WaitForCompletionHandler()
{
if (m_Complete)
return true;
if (m_RequestOperation != null)
{
if (m_RequestOperation.isDone && !m_Complete)
RequestOperation_completed(m_RequestOperation);
else if (!m_RequestOperation.isDone)
return false;
}
return m_Complete;
}
private void RequestOperation_completed(AsyncOperation op)
{
if (m_Complete)
return;
var webOp = op as UnityWebRequestAsyncOperation;
string textResult = null;
Exception exception = null;
if (webOp != null)
{
var webReq = webOp.webRequest;
if (!UnityWebRequestUtilities.RequestHasErrors(webReq, out UnityWebRequestResult uwrResult))
textResult = webReq.downloadHandler.text;
else
exception = new RemoteProviderException($"{nameof(TextDataProvider)} : unable to load from url : {webReq.url}", m_PI.Location, uwrResult);
}
else
{
exception = new RemoteProviderException(nameof(TextDataProvider) + " unable to load from unknown url", m_PI.Location);
}
CompleteOperation(textResult, exception);
}
protected void CompleteOperation(string text, Exception exception)
{
object result = null;
if (!string.IsNullOrEmpty(text))
result = ConvertText(text);
m_PI.Complete(result, result != null || m_IgnoreFailures, exception);
m_Complete = true;
}
private object ConvertText(string text)
{
try
{
return m_Provider.Convert(m_PI.Type, text);
}
catch (Exception e)
{
if (!m_IgnoreFailures)
Debug.LogException(e);
return null;
}
}
protected virtual void SendWebRequest(string path)
{
UnityWebRequest request = new UnityWebRequest(path, UnityWebRequest.kHttpVerbGET, new DownloadHandlerBuffer(), null);
if (m_Timeout > 0)
request.timeout = m_Timeout;
m_PI.ResourceManager.WebRequestOverride?.Invoke(request);
m_RequestQueueOperation = WebRequestQueue.QueueRequest(request);
if (m_RequestQueueOperation.IsDone)
{
m_RequestOperation = m_RequestQueueOperation.Result;
if (m_RequestOperation.isDone)
RequestOperation_completed(m_RequestOperation);
else
m_RequestOperation.completed += RequestOperation_completed;
}
else
{
m_RequestQueueOperation.OnComplete += asyncOperation =>
{
m_RequestOperation = asyncOperation;
m_RequestOperation.completed += RequestOperation_completed;
};
}
}
}
/// <summary>
/// Method to convert the text into the object type requested. Usually the text contains a JSON formatted serialized object.
/// </summary>
/// <param name="type">The object type the text is converted to.</param>
/// <param name="text">The text to be converted.</param>
/// <returns>The converted object.</returns>
public virtual object Convert(Type type, string text) { return text; }
/// <summary>
/// Provides raw text data from the location.
/// </summary>
/// <param name="provideHandle">The data needed by the provider to perform the load.</param>
public override void Provide(ProvideHandle provideHandle)
{
new InternalOp().Start(provideHandle, this);
}
}
}