Files
DeviantMobile-Rohan/Assets/GooglePlayPlugins/com.google.android.appbundle/Editor/Scripts/Internal/AssetPacks/AssetBundleVariant.cs

206 lines
8.4 KiB
C#

// 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;
namespace Google.Android.AppBundle.Editor.Internal.AssetPacks
{
/// <summary>
/// Internal-only wrapper around an AssetBundle that by virtue of its texture compression format is a
/// variant of the other AssetBundles contained in an <see cref="AssetBundlePack"/>.
/// </summary>
public class AssetBundleVariant
{
/// <summary>
/// Special value for <see cref="FileSizeBytes"/> indicating the AssetBundle file does not exist.
/// </summary>
public const long FileSizeIfMissing = -1L;
// Visible for testing.
public const string FileMissingText = "file missing";
// Visible for testing.
public const string NoneText = "none";
private static readonly string[] EmptyStringArray = new string[0];
/// <summary>
/// Constructor. Prefer <see cref="CreateVariant"/> for all cases except deserialization and testing.
/// </summary>
public AssetBundleVariant()
{
DirectDependencies = EmptyStringArray;
AllDependencies = EmptyStringArray;
}
/// <summary>
/// If non-empty, these errors will prevent this AssetBundle from being packaged in an app bundle.
/// </summary>
public readonly HashSet<AssetPackError> Errors = new HashSet<AssetPackError>();
/// <summary>
/// The names of any AssetBundles that this one directly depends on.
/// </summary>
public string[] DirectDependencies { get; private set; }
/// <summary>
/// The names of any AssetBundles that this one directly or transitively depends on.
/// </summary>
public string[] AllDependencies { get; private set; }
/// <summary>
/// The size of the file in bytes, or -1L if the file doesn't exist.
/// </summary>
public long FileSizeBytes { get; private set; }
/// <summary>
/// The path to the AssetBundle represented by this wrapper.
/// </summary>
public string Path { get; private set; }
/// <summary>
/// A UI friendly way of displaying dependency info.
/// </summary>
public string DependenciesText
{
// TODO: consider how to handle an extra long string in the UI.
get { return DirectDependencies.Length == 0 ? NoneText : string.Join(", ", DirectDependencies); }
}
/// <summary>
/// A UI friendly way of displaying file size or that the file doesn't exist on disk.
/// </summary>
public string FileSizeText
{
get
{
// Display file size in Kibibytes using "JEDEC" standard. See https://en.wikipedia.org/wiki/Kilobyte
return FileSizeBytes == FileSizeIfMissing ? FileMissingText : (FileSizeBytes / 1024) + " KB";
}
}
/// <summary>
/// A UI friendly way of displaying the error with this AssetBundle (if there is one) or the number of errors
/// (if there is more than one). If there are no errors, this is null.
/// </summary>
public string ErrorSummary
{
get
{
switch (Errors.Count)
{
case 0:
return null;
case 1:
return NameAndDescriptionAttribute.GetAttribute(Errors.First()).Name;
default:
return Errors.Count + " Errors";
}
}
}
/// <summary>
/// Delegate to find a variant when doing the dependencies check.
/// See <see cref="AssetBundleVariant.CheckDependencyErrors"/>.
/// </summary>
/// <param name="name">The asset pack to search.</param>
/// <param name="dependencyVariant">If found, will contain the searched asset pack.</param>
/// <param name="dependencyDeliveryMode">If found, will contain the delivery mode of the searched asset pack.</param>
/// <returns>true if the asset pack was found, false otherwise.</returns>
public delegate bool TryGetDependency(string name, out AssetBundleVariant dependencyVariant,
out AssetPackDeliveryMode dependencyDeliveryMode);
/// <summary>
/// Evaluates whether to set any <see cref="Errors"/> based on problems with this variant's dependencies.
/// </summary>
/// <param name="deliveryMode">The delivery mode of this asset pack.</param>
/// <param name="tryGetDependency">A function returning the asset pack for the given dependency name,
/// along with the delivery mode of the asset pack.</param>
public void CheckDependencyErrors(AssetPackDeliveryMode deliveryMode, TryGetDependency tryGetDependency)
{
if (deliveryMode == AssetPackDeliveryMode.DoNotPackage)
{
return;
}
foreach (var dependencyName in AllDependencies)
{
AssetBundleVariant dependencyVariant;
AssetPackDeliveryMode dependencyDeliveryMode;
if (!tryGetDependency(dependencyName, out dependencyVariant, out dependencyDeliveryMode))
{
Errors.Add(AssetPackError.DependencyMissing);
continue;
}
if (dependencyVariant.Errors.Count > 0)
{
Errors.Add(AssetPackError.DependencyError);
}
// If this asset pack is marked for delivery, all of its dependencies must be packaged for delivery.
if (dependencyDeliveryMode == AssetPackDeliveryMode.DoNotPackage)
{
Errors.Add(AssetPackError.DependencyNotPackaged);
continue;
}
// An asset pack cannot have dependencies on asset packs with later delivery modes,
// e.g. A FastFollow asset pack cannot depend on an OnDemand asset pack.
if (deliveryMode < dependencyDeliveryMode)
{
Errors.Add(AssetPackError.DependencyIncompatibleDelivery);
}
}
}
/// <summary>
/// Creates a new <see cref="AssetBundleVariant"/>. Evaluates some conditions and may set <see cref="Errors"/>.
/// </summary>
/// <param name="assetBundleName">Name of the AssetBundle represented by this variant.</param>
/// <param name="fileSizeBytes">Size of the file in bytes, or <see cref="FileSizeIfMissing"/>.</param>
/// <param name="directDependencies">AssetBundles that are direct dependencies of this one.</param>
/// <param name="allDependencies">AssetBundles that are direct or transitive dependencies of this one.</param>
/// <param name="path">The path to the AssetBundle represented by this variant.</param>
public static AssetBundleVariant CreateVariant(
string assetBundleName,
long fileSizeBytes,
string[] directDependencies,
string[] allDependencies,
string path)
{
var variant = new AssetBundleVariant
{
DirectDependencies = directDependencies ?? EmptyStringArray,
AllDependencies = allDependencies ?? EmptyStringArray,
FileSizeBytes = fileSizeBytes,
Path = path,
};
if (fileSizeBytes == FileSizeIfMissing)
{
variant.Errors.Add(AssetPackError.FileMissing);
}
if (!AndroidAppBundle.IsValidModuleName(assetBundleName))
{
variant.Errors.Add(AssetPackError.InvalidName);
}
return variant;
}
}
}