113 lines
5.1 KiB
C#
113 lines
5.1 KiB
C#
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
using UnityEditor.Build.Content;
|
||
|
using UnityEditor.Build.Pipeline.Interfaces;
|
||
|
using UnityEditor.Build.Player;
|
||
|
|
||
|
namespace UnityEditor.Build.Pipeline.Utilities
|
||
|
{
|
||
|
[Serializable]
|
||
|
struct ObjectTypes
|
||
|
{
|
||
|
public ObjectIdentifier ObjectID;
|
||
|
public Type[] Types;
|
||
|
|
||
|
public ObjectTypes(ObjectIdentifier objectID, Type[] types)
|
||
|
{
|
||
|
ObjectID = objectID;
|
||
|
Types = types;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static class ExtensionMethods
|
||
|
{
|
||
|
public static bool IsNullOrEmpty<T>(this ICollection<T> collection)
|
||
|
{
|
||
|
return collection == null || collection.Count == 0;
|
||
|
}
|
||
|
|
||
|
public static void GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, out TValue value) where TValue : new()
|
||
|
{
|
||
|
if (dictionary.TryGetValue(key, out value))
|
||
|
return;
|
||
|
|
||
|
value = new TValue();
|
||
|
dictionary.Add(key, value);
|
||
|
}
|
||
|
|
||
|
public static void Swap<T>(this IList<T> list, int first, int second)
|
||
|
{
|
||
|
T temp = list[second];
|
||
|
list[second] = list[first];
|
||
|
list[first] = temp;
|
||
|
}
|
||
|
|
||
|
public static void GatherSerializedObjectCacheEntries(this WriteCommand command, HashSet<CacheEntry> cacheEntries)
|
||
|
{
|
||
|
if (command.serializeObjects != null)
|
||
|
{
|
||
|
var objectIds = command.serializeObjects.Select(x => x.serializationObject);
|
||
|
var types = BuildCacheUtility.GetSortedUniqueTypesForObjects(objectIds);
|
||
|
cacheEntries.UnionWith(types.Select(BuildCacheUtility.GetCacheEntry));
|
||
|
cacheEntries.UnionWith(objectIds.Select(BuildCacheUtility.GetCacheEntry));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void ExtractCommonCacheData(IBuildCache cache, IEnumerable<ObjectIdentifier> includedObjects, IEnumerable<ObjectIdentifier> referencedObjects, HashSet<Type> uniqueTypes, List<ObjectTypes> objectTypes, HashSet<CacheEntry> dependencies)
|
||
|
{
|
||
|
if (includedObjects != null)
|
||
|
{
|
||
|
foreach (var objectId in includedObjects)
|
||
|
{
|
||
|
var types = BuildCacheUtility.GetSortedUniqueTypesForObject(objectId);
|
||
|
objectTypes.Add(new ObjectTypes(objectId, types));
|
||
|
uniqueTypes.UnionWith(types);
|
||
|
}
|
||
|
}
|
||
|
if (referencedObjects != null)
|
||
|
{
|
||
|
foreach (var objectId in referencedObjects)
|
||
|
{
|
||
|
var types = BuildCacheUtility.GetSortedUniqueTypesForObject(objectId);
|
||
|
objectTypes.Add(new ObjectTypes(objectId, types));
|
||
|
uniqueTypes.UnionWith(types);
|
||
|
dependencies.Add(cache.GetCacheEntry(objectId));
|
||
|
}
|
||
|
}
|
||
|
dependencies.UnionWith(uniqueTypes.Select(cache.GetCacheEntry));
|
||
|
}
|
||
|
|
||
|
#if NONRECURSIVE_DEPENDENCY_DATA
|
||
|
public static ObjectIdentifier[] FilterReferencedObjectIDs(GUID asset, ObjectIdentifier[] references, BuildTarget target, TypeDB typeDB, HashSet<GUID> dependencies)
|
||
|
{
|
||
|
// Expectation: references is populated with DependencyType.ValidReferences only for the given asset
|
||
|
var collectedImmediateReferences = new HashSet<ObjectIdentifier>();
|
||
|
var encounteredDependencies = new HashSet<ObjectIdentifier>();
|
||
|
while (references.Length > 0)
|
||
|
{
|
||
|
// Track which roots we encounter to do dependency pruning
|
||
|
encounteredDependencies.UnionWith(references.Where(x => x.guid != asset && dependencies.Contains(x.guid)));
|
||
|
// We only want to recursively grab references for objects being pulled in and won't go to another bundle
|
||
|
ObjectIdentifier[] immediateReferencesNotInOtherBundles = references.Where(x => !dependencies.Contains(x.guid) && !collectedImmediateReferences.Contains(x)).ToArray();
|
||
|
collectedImmediateReferences.UnionWith(immediateReferencesNotInOtherBundles);
|
||
|
// Grab next set of valid references and loop
|
||
|
references = ContentBuildInterface.GetPlayerDependenciesForObjects(immediateReferencesNotInOtherBundles, target, typeDB, DependencyType.ValidReferences);
|
||
|
}
|
||
|
|
||
|
// We need to ensure that we have a reference to a visible representation so our runtime dependency appending process
|
||
|
// can find something that can be appended, otherwise the necessary data will fail to load correctly in all cases. (EX: prefab A has reference to component on prefab B)
|
||
|
foreach (var dependency in encounteredDependencies)
|
||
|
{
|
||
|
// For each dependency, add just the main representation as a reference
|
||
|
var representations = ContentBuildInterface.GetPlayerAssetRepresentations(dependency.guid, target);
|
||
|
collectedImmediateReferences.Add(representations.First());
|
||
|
}
|
||
|
collectedImmediateReferences.UnionWith(encounteredDependencies);
|
||
|
return collectedImmediateReferences.ToArray();
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
}
|