2020-05-31 17:07:22 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
|
|
|
|
|
namespace SanAndreasUnity.Utilities
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
public class AsyncLoader<TKey, TObj>
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// All successfully loaded objects.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private readonly Dictionary<TKey, TObj> m_Loaded = new Dictionary<TKey, TObj>();
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Objects currently being loaded. Value represents list of subscribers which will be called when loading is finished.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private readonly Dictionary<TKey, List<System.Action<TObj>>> m_Loading = new Dictionary<TKey, List<System.Action<TObj>>> ();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public AsyncLoader ()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public AsyncLoader (IEqualityComparer<TKey> comparer)
|
|
|
|
|
{
|
|
|
|
|
m_Loaded = new Dictionary<TKey, TObj> (comparer);
|
|
|
|
|
m_Loading = new Dictionary<TKey, List<System.Action<TObj>>> (comparer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int GetNumObjectsLoaded ()
|
|
|
|
|
{
|
|
|
|
|
return m_Loaded.Count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int GetNumObjectsLoading ()
|
|
|
|
|
{
|
|
|
|
|
return m_Loading.Count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsObjectLoaded (TKey key)
|
|
|
|
|
{
|
|
|
|
|
return m_Loaded.ContainsKey (key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TObj GetLoadedObject (TKey key)
|
|
|
|
|
{
|
|
|
|
|
return m_Loaded [key];
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-18 04:03:43 +00:00
|
|
|
|
public bool TryLoadObject (TKey key, System.Action<TObj> onFinish)
|
2020-05-31 17:07:22 +00:00
|
|
|
|
{
|
2021-07-18 04:03:43 +00:00
|
|
|
|
ThreadHelper.ThrowIfNotOnMainThread(); // not needed, but to make sure
|
|
|
|
|
|
2020-05-31 17:07:22 +00:00
|
|
|
|
if (m_Loaded.ContainsKey(key))
|
|
|
|
|
{
|
2021-07-18 04:03:43 +00:00
|
|
|
|
onFinish(m_Loaded[key]);
|
|
|
|
|
return false;
|
2020-05-31 17:07:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-07-18 04:03:43 +00:00
|
|
|
|
if (m_Loading.ContainsKey(key))
|
2020-05-31 17:07:22 +00:00
|
|
|
|
{
|
|
|
|
|
// this object is loading
|
|
|
|
|
// subscribe to finish event
|
2021-07-18 04:03:43 +00:00
|
|
|
|
m_Loading[key].Add(onFinish);
|
2020-05-31 17:07:22 +00:00
|
|
|
|
return false;
|
2021-07-18 04:03:43 +00:00
|
|
|
|
}
|
2020-05-31 17:07:22 +00:00
|
|
|
|
|
|
|
|
|
// insert it into loading dict
|
2021-07-18 04:03:43 +00:00
|
|
|
|
m_Loading[key] = new List<System.Action<TObj>>() {onFinish};
|
2020-05-31 17:07:22 +00:00
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-18 04:03:43 +00:00
|
|
|
|
public bool TryGetLoadedObject(TKey key, out TObj loadedObject)
|
|
|
|
|
{
|
|
|
|
|
ThreadHelper.ThrowIfNotOnMainThread(); // not needed, but to make sure
|
|
|
|
|
|
|
|
|
|
return m_Loaded.TryGetValue(key, out loadedObject);
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-31 17:07:22 +00:00
|
|
|
|
public void OnObjectFinishedLoading (TKey key, TObj obj, bool bSuccess)
|
|
|
|
|
{
|
2021-07-18 04:03:43 +00:00
|
|
|
|
ThreadHelper.ThrowIfNotOnMainThread(); // not needed, but to make sure
|
2020-05-31 17:07:22 +00:00
|
|
|
|
|
|
|
|
|
if (bSuccess)
|
|
|
|
|
{
|
2021-07-18 04:03:43 +00:00
|
|
|
|
if (m_Loaded.ContainsKey(key))
|
2020-05-31 17:07:22 +00:00
|
|
|
|
{
|
|
|
|
|
// this object was loaded in the meantime
|
|
|
|
|
// this can happen if someone else is loading objects synchronously
|
2021-07-18 04:03:43 +00:00
|
|
|
|
Debug.LogErrorFormat("Redundant load of object ({0}): {1}", typeof(TObj), key);
|
2020-05-31 17:07:22 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2021-07-18 04:03:43 +00:00
|
|
|
|
m_Loaded.Add(key, obj);
|
2020-05-31 17:07:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-18 04:03:43 +00:00
|
|
|
|
if (m_Loading.TryGetValue(key, out var subscribersList))
|
|
|
|
|
{
|
|
|
|
|
// remove from loading dict
|
|
|
|
|
m_Loading.Remove(key);
|
2020-05-31 17:07:22 +00:00
|
|
|
|
|
2021-07-18 04:03:43 +00:00
|
|
|
|
// invoke subscribers
|
|
|
|
|
foreach (var action in subscribersList)
|
|
|
|
|
Utilities.F.RunExceptionSafe(() => action(obj));
|
|
|
|
|
}
|
2020-05-31 17:07:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|