183 lines
6.5 KiB
C#
183 lines
6.5 KiB
C#
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
using UnityEngine.ResourceManagement;
|
||
|
using UnityEngine.ResourceManagement.ResourceLocations;
|
||
|
|
||
|
namespace UnityEngine.AddressableAssets.ResourceLocators
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Simple implementation of an IResourceLocator
|
||
|
/// </summary>
|
||
|
public class ResourceLocationMap : IResourceLocator
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Construct a new ResourceLocationMap object.
|
||
|
/// </summary>
|
||
|
/// <param name="id">The locator id.</param>
|
||
|
/// <param name="capacity">The expected number of items.</param>
|
||
|
public ResourceLocationMap(string id, int capacity = 0)
|
||
|
{
|
||
|
LocatorId = id;
|
||
|
locations = new Dictionary<object, IList<IResourceLocation>>(capacity == 0 ? 100 : capacity);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Stores the resource locator id.
|
||
|
/// </summary>
|
||
|
public string LocatorId { get; private set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Construct a new ResourceLocationMap object with a list of locations.
|
||
|
/// </summary>
|
||
|
/// <param name="id">The locator id.</param>
|
||
|
/// <param name="locations">The list of locations to initialize with.</param>
|
||
|
public ResourceLocationMap(string id, IList<ResourceLocationData> locations)
|
||
|
{
|
||
|
LocatorId = id;
|
||
|
if (locations == null)
|
||
|
return;
|
||
|
this.locations = new Dictionary<object, IList<IResourceLocation>>(locations.Count * 2);
|
||
|
var locMap = new Dictionary<string, ResourceLocationBase>();
|
||
|
var dataMap = new Dictionary<string, ResourceLocationData>();
|
||
|
//create and collect locations
|
||
|
for (int i = 0; i < locations.Count; i++)
|
||
|
{
|
||
|
var rlData = locations[i];
|
||
|
if (rlData.Keys == null || rlData.Keys.Length < 1)
|
||
|
{
|
||
|
Addressables.LogErrorFormat("Address with id '{0}' does not have any valid keys, skipping...", rlData.InternalId);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (locMap.ContainsKey(rlData.Keys[0]))
|
||
|
{
|
||
|
Addressables.LogErrorFormat("Duplicate address '{0}' with id '{1}' found, skipping...", rlData.Keys[0], rlData.InternalId);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
var loc = new ResourceLocationBase(rlData.Keys[0], Addressables.ResolveInternalId(rlData.InternalId), rlData.Provider, rlData.ResourceType);
|
||
|
loc.Data = rlData.Data;
|
||
|
locMap.Add(rlData.Keys[0], loc);
|
||
|
dataMap.Add(rlData.Keys[0], rlData);
|
||
|
}
|
||
|
|
||
|
//fix up dependencies between them
|
||
|
foreach (var kvp in locMap)
|
||
|
{
|
||
|
var data = dataMap[kvp.Key];
|
||
|
if (data.Dependencies != null)
|
||
|
{
|
||
|
foreach (var d in data.Dependencies)
|
||
|
kvp.Value.Dependencies.Add(locMap[d]);
|
||
|
kvp.Value.ComputeDependencyHash();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
foreach (KeyValuePair<string, ResourceLocationBase> kvp in locMap)
|
||
|
{
|
||
|
ResourceLocationData rlData = dataMap[kvp.Key];
|
||
|
foreach (var k in rlData.Keys)
|
||
|
Add(k, kvp.Value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The mapping of key to location lists.
|
||
|
/// </summary>
|
||
|
Dictionary<object, IList<IResourceLocation>> locations;
|
||
|
|
||
|
#if ENABLE_BINARY_CATALOG
|
||
|
/// <summary>
|
||
|
/// Enumeration of all locations for this locator.
|
||
|
/// </summary>
|
||
|
public IEnumerable<IResourceLocation> AllLocations => locations.SelectMany(k => k.Value);
|
||
|
#endif
|
||
|
|
||
|
/// <summary>
|
||
|
/// Map of all locations for this locator.
|
||
|
/// </summary>
|
||
|
public Dictionary<object, IList<IResourceLocation>> Locations => locations;
|
||
|
|
||
|
/// <summary>
|
||
|
/// The keys available in this locator.
|
||
|
/// </summary>
|
||
|
public IEnumerable<object> Keys
|
||
|
{
|
||
|
get { return locations.Keys; }
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Locate all of the locations that match the given key.
|
||
|
/// </summary>
|
||
|
/// <param name="key">The key used to locate the locations.</param>
|
||
|
/// <param name="type">The resource type.</param>
|
||
|
/// <param name="locations">The list of found locations. This list is shared so it should not be modified.</param>
|
||
|
/// <returns>Returns true if a location was found. Returns false otherwise.</returns>
|
||
|
public bool Locate(object key, Type type, out IList<IResourceLocation> locations)
|
||
|
{
|
||
|
IList<IResourceLocation> locs = null;
|
||
|
if (!this.locations.TryGetValue(key, out locs))
|
||
|
{
|
||
|
locations = null;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (type == null)
|
||
|
{
|
||
|
locations = locs;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
var validTypeCount = 0;
|
||
|
foreach (var l in locs)
|
||
|
if (type.IsAssignableFrom(l.ResourceType))
|
||
|
validTypeCount++;
|
||
|
|
||
|
if (validTypeCount == 0)
|
||
|
{
|
||
|
locations = null;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (validTypeCount == locs.Count)
|
||
|
{
|
||
|
locations = locs;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
locations = new List<IResourceLocation>();
|
||
|
foreach (var l in locs)
|
||
|
{
|
||
|
if (type.IsAssignableFrom(l.ResourceType))
|
||
|
locations.Add(l);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Add a new location.
|
||
|
/// </summary>
|
||
|
/// <param name="key">The key to reference the location.</param>
|
||
|
/// <param name="location">The location to add.</param>
|
||
|
public void Add(object key, IResourceLocation location)
|
||
|
{
|
||
|
IList<IResourceLocation> locations;
|
||
|
if (!this.locations.TryGetValue(key, out locations))
|
||
|
this.locations.Add(key, locations = new List<IResourceLocation>());
|
||
|
locations.Add(location);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Add a list of locations.
|
||
|
/// </summary>
|
||
|
/// <param name="key">The key to reference the locations with.</param>
|
||
|
/// <param name="locations">The list of locations to store at the given key.</param>
|
||
|
public void Add(object key, IList<IResourceLocation> locations)
|
||
|
{
|
||
|
this.locations.Add(key, locations);
|
||
|
}
|
||
|
}
|
||
|
}
|