Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
## [2.1.0] - 2024-03-19
- Fix "Unable to verify target bucket for Remote Catalog: Not Found. Object could not be found" error
- Fixed caching to prevent unnecessary refreshing of bucket data.
- Sort collections on serialization to prevent unecessary merge conflicts
- Add warnings and documentation to make it clear you need to release the handle from LoadDependenciesAsync
  • Loading branch information
Unity Technologies committed Mar 19, 2024
1 parent 3c83867 commit 45b4451
Show file tree
Hide file tree
Showing 46 changed files with 1,607 additions and 125 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [2.1.0] - 2024-03-19
- Fix "Unable to verify target bucket for Remote Catalog: Not Found. Object could not be found" error
- Fixed caching to prevent unnecessary refreshing of bucket data.
- Sort collections on serialization to prevent unecessary merge conflicts
- Add warnings and documentation to make it clear you need to release the handle from LoadDependenciesAsync

## [2.0.8] - 2024-01-19
- Documents the behavior of using WaitForCompletion while a bundle is being unloaded.
- Prevent a KeyNotFoundException from being logged to the console.
Expand Down
3 changes: 3 additions & 0 deletions Editor/Build/AddressableAnalytics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ internal static class AddressableAnalytics

private const string UsageEvent = "addressablesUsageEvent";
private const string BuildEvent = "addressablesBuildEvent";

#if UNITY_2023_1_OR_NEWER
private static PackageManager.PackageInfo packageInfo = PackageManager.PackageInfo.FindForPackageName("com.unity.addressables");
#endif
private const string packageName = "com.unity.addressables";

#if UNITY_2023_3_OR_NEWER
Expand Down
42 changes: 31 additions & 11 deletions Editor/Build/CcdBuildEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,12 @@ internal async Task<bool> verifyTargetBucket(AddressableAssetSettings settings,
return true;
}

if (settings.m_CcdManagedData.IsConfigured())
{
// this has been configured by a previous run
return true;
}


// existing automatic bucket loaded from cache
var bucketIdVariable = dataSource
Expand All @@ -450,11 +456,15 @@ internal async Task<bool> verifyTargetBucket(AddressableAssetSettings settings,
}

// otherwise try to create
CcdManagement.SetEnvironmentId(settings.m_CcdManagedData.EnvironmentId);
await CreateManagedBucket(EditorUserBuildSettings.activeBuildTarget.ToString());
// we created a bucket so refresh our data sources so we ensure they're up to date
await RefreshDataSources();

var environmentId = ProfileDataSourceSettings.GetSettings().GetEnvironmentId(settings.profileSettings, settings.activeProfileId);
CcdManagement.SetEnvironmentId(environmentId); // this should be getting the value from the active profile
var ccdBucket = await CreateManagedBucket(EditorUserBuildSettings.activeBuildTarget.ToString());
if (ccdBucket == null) {
// the bucket already exists, we shouldn't be here if refresh was called
ccdBucket = await GetExistingManagedBucket();
}
var environmentName = ProfileDataSourceSettings.GetSettings().GetEnvironmentName(settings.profileSettings, settings.activeProfileId);
ProfileDataSourceSettings.AddGroupTypeForRemoteBucket(CloudProjectSettings.projectId, environmentId, environmentName, ccdBucket, new List<CcdBadge>());
PopulateCcdManagedData(settings, settings.activeProfileId);

// I should put this value into the data source list
Expand Down Expand Up @@ -735,12 +745,16 @@ internal ProfileGroupType GetDataSource(AddressableAssetSettings settings, strin
return groupType;
}

var groupTypes = ProfileDataSourceSettings.GetSettings().GetGroupTypesByPrefix(string.Join(
var environmentId = ProfileDataSourceSettings.GetSettings().GetEnvironmentId(settings.profileSettings, settings.activeProfileId);
// if we haven't setup an automatic group since refresh we do it here
IEnumerable<ProfileGroupType> groupTypes = ProfileDataSourceSettings.GetSettings().GetGroupTypesByPrefix(string.Join(
ProfileGroupType.k_PrefixSeparator.ToString(), "CCD", CloudProjectSettings.projectId,
ProfileDataSourceSettings.GetSettings().GetEnvironmentId(settings.profileSettings, settings.activeProfileId)));
// if we have setup an automatic group we load it here
groupTypes = groupTypes.Concat(ProfileDataSourceSettings.GetSettings().GetGroupTypesByPrefix(AddressableAssetSettings.CcdManagerGroupTypePrefix));
var automaticGroupType = groupTypes.FirstOrDefault(gt =>
gt.GetVariableBySuffix($"{nameof(CcdBucket)}{nameof(CcdBucket.Name)}").Value ==
EditorUserBuildSettings.activeBuildTarget.ToString());
gt.GetVariableBySuffix($"{nameof(CcdBucket)}{nameof(CcdBucket.Name)}")?.Value == EditorUserBuildSettings.activeBuildTarget.ToString()
&& gt.GetVariableBySuffix($"{nameof(ProfileDataSourceSettings.Environment)}{nameof(ProfileDataSourceSettings.Environment.id)}")?.Value == environmentId);
if (automaticGroupType == null)
{
// the bucket does not yet exist
Expand Down Expand Up @@ -826,9 +840,7 @@ async Task<CcdBucket> CreateManagedBucket(string bucketName)
{
if (e.ErrorCode == CcdManagementErrorCodes.AlreadyExists)
{
var buckets = await ProfileDataSourceSettings.GetAllBucketsAsync();
ccdBucket = buckets.First(bucket =>
bucket.Value.Name == EditorUserBuildSettings.activeBuildTarget.ToString()).Value;
return null;
}
else
{
Expand All @@ -838,6 +850,14 @@ async Task<CcdBucket> CreateManagedBucket(string bucketName)
return ccdBucket;
}

async Task<CcdBucket> GetExistingManagedBucket()
{
var buckets = await ProfileDataSourceSettings.GetAllBucketsAsync();
var ccdBucket = buckets.First(bucket =>
bucket.Value.Name == EditorUserBuildSettings.activeBuildTarget.ToString()).Value;
return ccdBucket;
}

async Task<CcdEntry> GetEntryByPath(ICcdManagementServiceSdk api, Guid bucketId, string path)
{
CcdEntry ccdEntry = null;
Expand Down
6 changes: 4 additions & 2 deletions Editor/Settings/AddressableAssetEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -642,17 +642,19 @@ string GetRelativePath(string file, string path)
}

/// <summary>
/// Implementation of ISerializationCallbackReceiver. Converts data to serializable form before serialization.
/// Implementation of ISerializationCallbackReceiver. Converts data to serializable form before serialization,
/// and sorts collections for deterministic ordering.
/// </summary>
public void OnBeforeSerialize()
{
m_SerializedLabels = new List<string>();
foreach (var t in m_Labels)
m_SerializedLabels.Add(t);
m_SerializedLabels.Sort(string.CompareOrdinal);
}

/// <summary>
/// Implementation of ISerializationCallbackReceiver. Converts data from serializable form after deserialization.
/// Implementation of ISerializationCallbackReceiver. Converts data from serializable form after deserialization.
/// </summary>
public void OnAfterDeserialize()
{
Expand Down
14 changes: 8 additions & 6 deletions Editor/Settings/AddressableAssetGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class AddressableAssetGroup : ScriptableObject, IComparer<AddressableAsse

[FormerlySerializedAs("m_serializeEntries")]
[SerializeField]
List<AddressableAssetEntry> m_SerializeEntries = new List<AddressableAssetEntry>();
internal List<AddressableAssetEntry> m_SerializeEntries = new List<AddressableAssetEntry>();

[FormerlySerializedAs("m_readOnly")]
[SerializeField]
Expand Down Expand Up @@ -395,7 +395,8 @@ internal Hash128 currentHash
}

/// <summary>
/// Converts data to serializable format.
/// Implementation of ISerializationCallbackReceiver. Converts data to serializable form before serialization,
/// and sorts collections for deterministic ordering.
/// </summary>
public void OnBeforeSerialize()
{
Expand All @@ -405,10 +406,11 @@ public void OnBeforeSerialize()
foreach (var e in entries)
m_SerializeEntries.Add(e);
}
m_SerializeEntries.Sort((a, b) => string.CompareOrdinal(a.guid, b.guid));
}

/// <summary>
/// Converts data from serializable format.
/// Implementation of ISerializationCallbackReceiver. Converts data from serializable format.
/// </summary>
public void OnAfterDeserialize()
{
Expand Down Expand Up @@ -478,14 +480,14 @@ internal void DedupeEnteries()
foreach (AddressableAssetEntry e in m_EntryMap.Values)
{
AddressableAssetEntry lookedUpEntry = m_Settings.FindAssetEntry(e.guid);
if (lookedUpEntry.parentGroup != this)
if (lookedUpEntry?.parentGroup != this)
{
Debug.LogWarning(e.address
+ " is already a member of group "
+ lookedUpEntry.parentGroup
+ lookedUpEntry?.parentGroup
+ " but group "
+ m_GroupName
+ " contained a reference to it. Removing referece.");
+ " contained a reference to it. Removing reference.");
removeEntries.Add(e);
}
}
Expand Down
11 changes: 11 additions & 0 deletions Editor/Settings/AddressableAssetGroupSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,16 @@ protected void ShowMixedValue(SerializedProperty property, List<AddressableAsset
}
}
}
public static int Compare(AddressableAssetGroupSchema x, AddressableAssetGroupSchema y)
{
if (x == null && y == null)
return 0;
if (x == null || x.SchemaSerializedObject == null || x.SchemaSerializedObject.targetObject == null)
return -1;
if (y == null || y.SchemaSerializedObject == null || y.SchemaSerializedObject.targetObject == null)
return 1;
// you can only have one schema of a given type in a set so using the name should be ok.
return string.CompareOrdinal(x.SchemaSerializedObject.targetObject.name, y.SchemaSerializedObject.targetObject.name);
}
}
}
17 changes: 16 additions & 1 deletion Editor/Settings/AddressableAssetGroupSchemaSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace UnityEditor.AddressableAssets.Settings
/// Collection of AddressableAssetGroupSchema objects
/// </summary>
[Serializable]
public class AddressableAssetGroupSchemaSet
public class AddressableAssetGroupSchemaSet : ISerializationCallbackReceiver
{
[FormerlySerializedAs("m_schemas")]
[SerializeField]
Expand Down Expand Up @@ -237,5 +237,20 @@ internal bool RenameSchemaAssets(Func<Type, string> pathFunc)

return result;
}

/// <summary>
/// Implementation of ISerializationCallbackReceiver. Sorts collections for deterministic ordering.
/// </summary>
public void OnBeforeSerialize()
{
m_Schemas.Sort(AddressableAssetGroupSchema.Compare);
}

/// <summary>
/// Implementation of ISerializationCallbackReceiver. Does nothing.
/// </summary>
public void OnAfterDeserialize()
{
}
}
}
17 changes: 16 additions & 1 deletion Editor/Settings/AddressableAssetGroupTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace UnityEditor.AddressableAssets.Settings
/// Used to create template groups to make it easier for the user to create new groups.
/// </summary>
[CreateAssetMenu(fileName = "AddressableAssetGroupTemplate.asset", menuName = "Addressables/Group Templates/Blank Group Template")]
public class AddressableAssetGroupTemplate : ScriptableObject, IGroupTemplate
public class AddressableAssetGroupTemplate : ScriptableObject, IGroupTemplate, ISerializationCallbackReceiver
{
[SerializeField]
private List<AddressableAssetGroupSchema> m_SchemaObjects = new List<AddressableAssetGroupSchema>();
Expand Down Expand Up @@ -272,5 +272,20 @@ public int FindSchema(Type type)

return -1;
}

/// <summary>
/// Implementation of ISerializationCallbackReceiver. Sorts collections for deterministic ordering.
/// </summary>
public void OnBeforeSerialize()
{
m_SchemaObjects.Sort(AddressableAssetGroupSchema.Compare);
}

/// <summary>
/// Implementation of ISerializationCallbackReceiver. Does nothing.
/// </summary>
public void OnAfterDeserialize()
{
}
}
}
31 changes: 27 additions & 4 deletions Editor/Settings/AddressableAssetProfileSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace UnityEditor.AddressableAssets.Settings
/// Contains user defined variables to control build parameters.
/// </summary>
[Serializable]
public class AddressableAssetProfileSettings
public class AddressableAssetProfileSettings : ISerializationCallbackReceiver
{
internal delegate string ProfileStringEvaluationDelegate(string key);

Expand All @@ -34,7 +34,7 @@ internal void UnregisterProfileStringEvaluationFunc(ProfileStringEvaluationDeleg
}

[Serializable]
internal class BuildProfile
internal class BuildProfile : ISerializationCallbackReceiver
{
[Serializable]
internal class ProfileEntry
Expand Down Expand Up @@ -197,6 +197,15 @@ internal void SetValueById(string variableId, string val)
values[i].value = val;
m_CurrentHash = default;
}

public void OnBeforeSerialize()
{
m_Values.Sort((a, b) => string.CompareOrdinal(a.id, b.id));
}

public void OnAfterDeserialize()
{
}
}

internal void OnAfterDeserialize(AddressableAssetSettings settings)
Expand Down Expand Up @@ -228,7 +237,7 @@ public class ProfileIdData
{
[FormerlySerializedAs("m_id")]
[SerializeField]
string m_Id;
internal string m_Id;

/// <summary>
/// The unique ID set to identify a specific profile.
Expand Down Expand Up @@ -307,7 +316,7 @@ internal ProfileIdData()
/// </summary>
/// <param name="entryId">The unique ID for this ProfileIdData</param>
/// <param name="entryName">The name of the ProfileIdData. ProfileIdData names should be unique in a given AddressableAssetProfileSettings.</param>
/// <param name="inline">False by default, this informs the BuildProifleSettingsEditor on if it should evaluate the ProfileIdData directly (true)
/// <param name="inline">False by default, this informs the BuildProifleSettingsEditor on if it should evaluate the ProfileIdData directly (true)
/// or get the value by Id first before evaluation (false).</param>
public ProfileIdData(string entryId, string entryName, bool inline)
{
Expand Down Expand Up @@ -891,5 +900,19 @@ internal void CreateDuplicateVariableWithNewName(AddressableAssetSettings addres
SetDirty(AddressableAssetSettings.ModificationEvent.ProfileModified, profile, true);
}
}
/// <summary>
/// Implementation of ISerializationCallbackReceiver. Sorts collections for deterministic ordering.
/// </summary>
public void OnBeforeSerialize()
{
m_ProfileEntryNames.Sort((a, b) => string.CompareOrdinal(a.Id, b.Id));
}

/// <summary>
/// Implementation of ISerializationCallbackReceiver. Does nothing.
/// </summary>
public void OnAfterDeserialize()
{
}
}
}
16 changes: 12 additions & 4 deletions Editor/Settings/AddressableAssetSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -930,13 +930,13 @@ public int SharedBundleSettingsCustomGroupIndex
}

/// <summary>
/// Retrieves the group whose settings are used for shared bundles (Built In and MonoScript bundles).
/// Retrieves the group whose settings are used for shared bundles (Built In and MonoScript bundles).
/// </summary>
/// <returns>The group whose settings are used.</returns>
public AddressableAssetGroup GetSharedBundleGroup()
{
if (SharedBundleSettings == SharedBundleSettings.CustomGroup &&
m_SharedBundleSettingsCustomGroupIndex >= 0 &&
m_SharedBundleSettingsCustomGroupIndex >= 0 &&
m_SharedBundleSettingsCustomGroupIndex < groups.Count)
return groups[m_SharedBundleSettingsCustomGroupIndex];
return DefaultGroup;
Expand Down Expand Up @@ -2309,6 +2309,11 @@ public AddressableAssetEntry FindAssetEntry(string guid, bool includeImplicit)
return null;
}

internal void ClearFindAssetEntryCache()
{
m_FindAssetEntryCache = null;
}

internal bool IsAssetPathInAddressableDirectory(string assetPath, out string assetName)
{
if (!string.IsNullOrEmpty(assetPath))
Expand Down Expand Up @@ -3253,14 +3258,17 @@ public static bool InvokeAssetGroupCommand(string cmdId, IEnumerable<Addressable


/// <summary>
/// Impementation of ISerializationCallbackReceiver, does nothing.
/// Impementation of ISerializationCallbackReceiver. Sorts collections for deterministic ordering
/// </summary>
public void OnBeforeSerialize()
{
// m_InitializationObjects, m_DataBuilders, and m_GroupTemplateObjects are serialized by array index
profileSettings.profiles.Sort((a, b) => string.CompareOrdinal(a.id, b.id));
m_GroupAssets.Sort((a, b) => string.CompareOrdinal(a.Guid, b.Guid));
}

/// <summary>
/// Impementation of ISerializationCallbackReceiver, used to set callbacks for ProfileValueReference changes.
/// Impementation of ISerializationCallbackReceiver. Used to set callbacks for ProfileValueReference changes.
/// </summary>
public void OnAfterDeserialize()
{
Expand Down
4 changes: 2 additions & 2 deletions Editor/Settings/GroupSchemas/BundledAssetGroupSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -743,14 +743,14 @@ internal string GetAssetLoadPath(string assetPath, HashSet<string> otherLoadPath
}

/// <summary>
/// Impementation of ISerializationCallbackReceiver, does nothing.
/// Implementation of ISerializationCallbackReceiver. Does nothing.
/// </summary>
public void OnBeforeSerialize()
{
}

/// <summary>
/// Impementation of ISerializationCallbackReceiver, used to set callbacks for ProfileValueReference changes.
/// Impementation of ISerializationCallbackReceiver. Used to set callbacks for ProfileValueReference changes.
/// </summary>
public void OnAfterDeserialize()
{
Expand Down
Loading

0 comments on commit 45b4451

Please sign in to comment.