using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Serialization;
namespace UnityEditor.AddressableAssets.Settings
{
using Object = UnityEngine.Object;
///
/// Collection of AddressableAssetGroupSchema objects
///
[Serializable]
public class AddressableAssetGroupSchemaSet
{
[FormerlySerializedAs("m_schemas")]
[SerializeField]
List m_Schemas = new List();
///
/// List of schemas for this group.
///
public List Schemas
{
get { return m_Schemas; }
}
///
/// Get the list of schema types.
///
public List Types
{
get
{
var types = new List(m_Schemas.Count);
foreach (var s in m_Schemas)
types.Add(s.GetType());
return types;
}
}
///
/// Adds a copy of the provided schema object.
///
/// The schema to copy.
/// A function that returns the path where this method can save the schema asset. Set to null to not create an in-project asset.
/// The created schema object.
public AddressableAssetGroupSchema AddSchema(AddressableAssetGroupSchema schema, Func pathFunc)
{
if (schema == null)
{
Debug.LogWarning("Cannot add null Schema object.");
return null;
}
var type = schema.GetType();
if (GetSchema(type) != null)
{
Debug.LogWarningFormat("Cannot add multiple schemas of the same type: {0}.", type.FullName);
return null;
}
if (pathFunc == null)
{
m_Schemas.Add(schema);
return schema;
}
var assetName = pathFunc(type);
if (File.Exists(assetName))
{
Debug.LogWarningFormat("Schema asset already exists at path {0}, relinking.", assetName);
var existingSchema = AssetDatabase.LoadAssetAtPath(assetName, type) as AddressableAssetGroupSchema;
m_Schemas.Add(existingSchema);
return existingSchema;
}
var newSchema = Object.Instantiate(schema);
if (!string.IsNullOrEmpty(assetName))
{
var dir = Path.GetDirectoryName(assetName);
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
Directory.CreateDirectory(dir);
AssetDatabase.CreateAsset(newSchema, assetName);
}
m_Schemas.Add(newSchema);
return newSchema;
}
///
/// Creates and adds a schema of a given type to this group. The schema asset will be created in the GroupSchemas directory relative to the settings asset.
///
/// The schema type. This type must not already be added.
/// A function that returns the path where this method can save the schema asset. Set to null to not create an in-project asset.
/// The created schema object.
public AddressableAssetGroupSchema AddSchema(Type type, Func pathFunc)
{
if (type == null)
{
Debug.LogWarning("Cannot add null Schema type.");
return null;
}
if (!typeof(AddressableAssetGroupSchema).IsAssignableFrom(type))
{
Debug.LogWarningFormat("Invalid Schema type {0}. Schemas must inherit from AddressableAssetGroupSchema.", type.FullName);
return null;
}
var existing = GetSchema(type);
if (existing != null)
{
Debug.LogWarningFormat("Cannot add multiple schemas of the same type: {0}.", existing.GetType().FullName);
return existing;
}
var assetName = pathFunc(type);
if (File.Exists(assetName))
{
Debug.LogWarningFormat("Schema asset already exists at path {0}, relinking.", assetName);
var existingSchema = AssetDatabase.LoadAssetAtPath(assetName, type) as AddressableAssetGroupSchema;
m_Schemas.Add(existingSchema);
return existingSchema;
}
var schema = ScriptableObject.CreateInstance(type) as AddressableAssetGroupSchema;
if (!string.IsNullOrEmpty(assetName))
{
var dir = Path.GetDirectoryName(assetName);
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
Directory.CreateDirectory(dir);
AssetDatabase.CreateAsset(schema, assetName);
}
m_Schemas.Add(schema);
return schema;
}
///
/// Remove a given schema from this group.
///
/// The schema type.
/// True if the schema was found and removed, false otherwise.
public bool RemoveSchema(Type type)
{
for (int i = 0; i < m_Schemas.Count; i++)
{
var s = m_Schemas[i];
if (s.GetType() == type)
{
m_Schemas.RemoveAt(i);
string guid;
long lfid;
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(s, out guid, out lfid))
AssetDatabase.DeleteAsset(AssetDatabase.GUIDToAssetPath(guid));
return true;
}
}
return false;
}
///
/// Gets an added schema of the specified type.
///
/// The schema type.
/// The schema if found, otherwise null.
public AddressableAssetGroupSchema GetSchema(Type type)
{
if (type == null)
{
Debug.LogWarning("Cannot get schema with null type.");
return null;
}
if (!typeof(AddressableAssetGroupSchema).IsAssignableFrom(type))
{
Debug.LogWarningFormat("Invalid Schema type {0}. Schemas must inherit from AddressableAssetGroupSchema.", type.FullName);
return null;
}
foreach (var s in m_Schemas)
if (type == s.GetType())
return s;
return null;
}
///
/// Removes all schemas and optionally deletes the assets associated with them.
///
/// If true, the schema assets will also be deleted.
public void ClearSchemas(bool deleteAssets)
{
if (deleteAssets)
{
for (int i = 0; i < m_Schemas.Count; i++)
{
var s = m_Schemas[i];
string guid;
long lfid;
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(s, out guid, out lfid))
{
var path = AssetDatabase.GUIDToAssetPath(guid);
if (File.Exists(path))
AssetDatabase.DeleteAsset(path);
}
}
}
m_Schemas.Clear();
}
internal bool RenameSchemaAssets(Func pathFunc)
{
bool result = true;
foreach (var schema in m_Schemas)
{
string guid;
if (!AssetDatabase.TryGetGUIDAndLocalFileIdentifier(schema, out guid, out long lfid))
continue;
string path = AssetDatabase.GUIDToAssetPath(guid);
if (string.IsNullOrEmpty(path))
continue;
string newPath = pathFunc(schema.GetType());
if (path == newPath)
continue;
string setPath = AssetDatabase.MoveAsset(path, newPath);
if (!string.IsNullOrEmpty(setPath))
result = false;
}
return result;
}
}
}