Skip to content

Commit

Permalink
Disable file-backed caching on webGL platform (#37)
Browse files Browse the repository at this point in the history
Hey @StephenHodgson,

as mentioned on discord the current implementation of the DownloadCache
was running into trouble on the webGL platform.

With the changes I implemented here I tried to separate the caching so
that the DownloadCache can be replaced depending on the platforms needs.

I originally wanted the DownloadCache to already return the assets
instead of just returning the URLs to load, so that on webGL there could
be a runtime-cache for the textures and audioClips. I decided against
that for now, because I would have needed to change more of your
existing code which I don't wanna do without your consent.

Would be glad if these changes will go live promptly.

---------

Co-authored-by: Andreas Herbig <[email protected]>
Co-authored-by: Stephen Hodgson <[email protected]>
  • Loading branch information
3 people authored Aug 4, 2023
1 parent 5fb5f00 commit 8e0da2f
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 109 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
using Utilities.Async;
using Utilities.WebRequestRest.Interfaces;

namespace Utilities.WebRequestRest
{
internal class DiskDownloadCache : IDownloadCache
{
/// <summary>
/// Generates a <see cref="Guid"/> based on the string.
/// </summary>
/// <param name="string">The string to generate the <see cref="Guid"/>.</param>
/// <returns>A new <see cref="Guid"/> that represents the string.</returns>
private static Guid GenerateGuid(string @string)
{
using MD5 md5 = MD5.Create();
return new Guid(md5.ComputeHash(Encoding.Default.GetBytes(@string)));
}

public void ValidateCacheDirectory()
{
if (!Directory.Exists(Rest.DownloadCacheDirectory))
{
Directory.CreateDirectory(Rest.DownloadCacheDirectory);
}
}

public async Task ValidateCacheDirectoryAsync()
{
await Awaiters.UnityMainThread;
ValidateCacheDirectory();
}

public bool TryGetDownloadCacheItem(string uri, out string filePath)
{
ValidateCacheDirectory();
bool exists;

if (uri.Contains(Rest.FileUriPrefix))
{
filePath = uri;
return File.Exists(uri.Replace(Rest.FileUriPrefix, string.Empty));
}

if (Rest.TryGetFileNameFromUrl(uri, out var fileName))
{
filePath = Path.Combine(Rest.DownloadCacheDirectory, fileName);
exists = File.Exists(filePath);
}
else
{
filePath = Path.Combine(Rest.DownloadCacheDirectory, GenerateGuid(uri).ToString());
exists = File.Exists(filePath);
}

if (exists)
{
filePath = $"{Rest.FileUriPrefix}{Path.GetFullPath(filePath)}";
}

return exists;
}

public bool TryDeleteCacheItem(string uri)
{
if (!TryGetDownloadCacheItem(uri, out var filePath))
{
return false;
}

try
{
File.Delete(filePath);
}
catch (Exception e)
{
Debug.LogError(e);
}

return !File.Exists(filePath);
}

public void DeleteDownloadCache()
{
if (Directory.Exists(Rest.DownloadCacheDirectory))
{
Directory.Delete(Rest.DownloadCacheDirectory, true);
}
}

public async Task WriteCacheItemAsync(byte[] data, string cachePath, CancellationToken cancellationToken)
{
if (File.Exists(cachePath))
{
return;
}

var fileStream = File.OpenWrite(cachePath);

try
{
await fileStream.WriteAsync(data, 0, data.Length, cancellationToken);
}
catch (Exception e)
{
Debug.LogError($"Failed to write asset to disk! {e}");
}
finally
{
await fileStream.DisposeAsync();
}
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System.Threading;
using System.Threading.Tasks;

namespace Utilities.WebRequestRest.Interfaces
{
internal interface IDownloadCache
{
void ValidateCacheDirectory();

Task ValidateCacheDirectoryAsync();

bool TryGetDownloadCacheItem(string uri, out string filePath);

bool TryDeleteCacheItem(string uri);

void DeleteDownloadCache();

Task WriteCacheItemAsync(byte[] data, string cachePath, CancellationToken cancellationToken);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System.Threading;
using System.Threading.Tasks;
using Utilities.WebRequestRest.Interfaces;

namespace Utilities.Rest
{
internal class NoOpDownloadCache : IDownloadCache
{
public void ValidateCacheDirectory() { }

public Task ValidateCacheDirectoryAsync() => Task.CompletedTask;

public bool TryGetDownloadCacheItem(string uri, out string filePath)
{
filePath = uri;
return false;
}

public bool TryDeleteCacheItem(string uri) => true;

public void DeleteDownloadCache() { }

public Task WriteCacheItemAsync(byte[] data, string cachePath, CancellationToken cancellationToken) => Task.CompletedTask;
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8e0da2f

Please sign in to comment.