// Copyright (c) 2021 homuler
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
using System;
using System.Collections;
using System.IO;
namespace Mediapipe
{
///
/// Class to manage assets that MediaPipe accesses.
///
///
/// There must not be more than one instance at the same time.
///
public abstract class ResourceManager
{
public delegate string PathResolver(string path);
internal delegate bool NativeResourceProvider(string path, IntPtr dest);
public delegate byte[] ResourceProvider(string path);
private static readonly object _InitLock = new object();
private static ResourceManager _Instance;
private readonly PathResolver _pathResolver;
private readonly ResourceProvider _resourceProvider;
public ResourceManager(PathResolver pathResolver, ResourceProvider resourceProvider)
{
lock (_InitLock)
{
if (_Instance != null)
{
throw new InvalidOperationException("ResourceManager can be initialized only once");
}
_pathResolver = pathResolver;
_resourceProvider = resourceProvider;
SafeNativeMethods.mp__SetCustomGlobalPathResolver__P(PathToResourceAsFile);
SafeNativeMethods.mp__SetCustomGlobalResourceProvider__P(GetResourceContents);
_Instance = this;
}
}
/// Asset name
///
/// Returns true if is already prepared (saved locally on the device).
///
public abstract bool IsPrepared(string name);
///
/// Saves as asynchronously.
///
///
/// Specifies whether will be overwritten if it already exists.
///
public abstract IEnumerator PrepareAssetAsync(string name, string uniqueKey, bool overwrite = true);
public IEnumerator PrepareAssetAsync(string name, bool overwrite = true)
{
return PrepareAssetAsync(name, name, overwrite);
}
[AOT.MonoPInvokeCallback(typeof(PathResolver))]
private static string PathToResourceAsFile(string assetPath)
{
try
{
return _Instance._pathResolver(assetPath);
}
catch (Exception e)
{
UnityEngine.Debug.LogException(e);
return "";
}
}
[AOT.MonoPInvokeCallback(typeof(ResourceProvider))]
private static bool GetResourceContents(string path, IntPtr dst)
{
try
{
var asset = _Instance._resourceProvider(path);
using (var srcStr = new StdString(asset))
{
srcStr.Swap(new StdString(dst, false));
}
return true;
}
catch (Exception e)
{
UnityEngine.Debug.LogException(e);
return false;
}
}
protected static string GetAssetNameFromPath(string assetPath)
{
var assetName = Path.GetFileNameWithoutExtension(assetPath);
var extension = Path.GetExtension(assetPath);
switch (extension)
{
case ".binarypb":
case ".tflite":
{
return $"{assetName}.bytes";
}
case ".pbtxt":
{
return $"{assetName}.txt";
}
default:
{
return $"{assetName}{extension}";
}
}
}
}
}