// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Collections.Generic;
using System.Linq;
using Google.Android.AppBundle.Editor.Internal.Utils;
using UnityEngine;
namespace Google.Android.AppBundle.Editor.Internal.AssetPacks
{
///
/// Internal-only wrapper around s that are identical except for their
/// texture compression formats.
///
public class AssetBundlePack
{
///
/// The name of the asset pack, which is the same as the name of every included AssetBundle.
///
public readonly string Name;
///
/// Indicates whether this pack will be included in an Android App Bundle, and if so how it is delivered.
///
public AssetPackDeliveryMode DeliveryMode;
///
/// The AssetBundles, all with the same name but generated for different texture compression formats.
///
public IDictionary Variants { get; private set; }
///
/// If non-empty, these errors will prevent this AssetBundlePack from being packaged in an App Bundle.
///
public readonly HashSet Errors = new HashSet();
///
/// Constructor.
///
public AssetBundlePack(string name, AssetPackDeliveryMode deliveryMode)
{
Name = name;
DeliveryMode = deliveryMode;
Variants = new Dictionary();
}
///
/// Adds an to this asset pack.
/// true if the AssetBundle was added, false if another AssetBundle with the same compression
/// is already present.
///
public bool Add(TextureCompressionFormat textureCompressionFormat, AssetBundleVariant variant)
{
AssetBundleVariant existingVariant;
if (Variants.TryGetValue(textureCompressionFormat, out existingVariant))
{
Debug.LogErrorFormat("Multiple AssetBundles for texture format {0} are used for {1}.",
textureCompressionFormat.ToString(), Name);
existingVariant.Errors.Add(AssetPackError.DuplicateName);
return false;
}
Variants.Add(textureCompressionFormat, variant);
return true;
}
///
/// Adds the specified error to all children.
///
public void AddErrorToVariants(AssetPackError error)
{
foreach (var assetPack in Variants.Values)
{
assetPack.Errors.Add(error);
}
}
///
/// The names of any AssetBundles that the AssetBundles inside this AssetBundlePack directly depend on.
///
public IList DirectDependencies
{
get
{
var directDependencies =
Variants.Values.SelectMany(pack => pack.DirectDependencies).Distinct().ToList();
directDependencies.Sort();
return directDependencies;
}
}
///
/// A UI friendly way of displaying the error with this AssetBundlePack (if one) or the number of errors
/// (if more than one). If there are no errors, returns null.
///
public string ErrorSummary
{
get
{
switch (Errors.Count)
{
case 0:
return null;
case 1:
return NameAndDescriptionAttribute.GetAttribute(Errors.First()).Name;
default:
return Errors.Count + " Errors";
}
}
}
///
/// Delegate to find an AssetBundlePack when doing the dependencies check.
///
/// The name of the other AssetBundlePack.
/// If found, will contain the AssetBundlePack.
public delegate bool TryGetAssetBundlePack(string name, out AssetBundlePack assetBundlePack);
///
/// Evaluates whether to set any based on problems with the dependencies.
///
/// Function to get an given its name.
public void CheckDependencyErrors(TryGetAssetBundlePack tryGetAssetBundlePack)
{
if (DeliveryMode == AssetPackDeliveryMode.DoNotPackage)
{
return;
}
foreach (var variant in Variants)
{
var textureCompressionFormat = variant.Key;
var assetPack = variant.Value;
assetPack.CheckDependencyErrors(
DeliveryMode,
TryGetDependency(tryGetAssetBundlePack, textureCompressionFormat));
}
}
private static AssetBundleVariant.TryGetDependency TryGetDependency(
TryGetAssetBundlePack tryGetAssetBundlePack, TextureCompressionFormat textureCompressionFormat)
{
return (string name, out AssetBundleVariant dependency, out AssetPackDeliveryMode deliveryMode) =>
{
deliveryMode = AssetPackDeliveryMode.DoNotPackage;
dependency = null;
AssetBundlePack assetBundlePack;
if (tryGetAssetBundlePack(name, out assetBundlePack) &&
assetBundlePack.Variants.TryGetValue(textureCompressionFormat, out dependency))
{
deliveryMode = assetBundlePack.DeliveryMode;
return true;
}
return false;
};
}
}
}