PO/Library/PackageCache/com.unity.2d.tilemap@1.0.0/Editor/GridPaletteBrushes.cs

238 lines
8.5 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEditorInternal;
namespace UnityEditor.Tilemaps
{
internal class GridPaletteBrushes : ScriptableSingleton<GridPaletteBrushes>
{
internal static readonly string s_SessionStateLastUsedBrush = "GridPaletteBrushes.LastUsedBrush";
private static readonly string s_LibraryPath = "Library/GridBrush";
private static readonly string s_GridBrushExtension = ".asset";
private static bool s_RefreshCache;
[SerializeField] private List<GridBrushBase> m_Brushes;
public static List<GridBrushBase> brushes
{
get
{
if (instance.m_Brushes == null || instance.m_Brushes.Count == 0 || s_RefreshCache)
{
instance.RefreshBrushesCache();
s_RefreshCache = false;
}
return instance.m_Brushes;
}
}
private string[] m_BrushNames;
public static string[] brushNames
{
get
{
return instance.m_BrushNames;
}
}
public GridBrushBase GetLastUsedBrush()
{
var sessionIndex = SessionState.GetInt(s_SessionStateLastUsedBrush, -1);
if (sessionIndex >= 0 && brushes.Count > sessionIndex)
return brushes[sessionIndex];
return brushes[0];
}
public void StoreLastUsedBrush(GridBrushBase brush)
{
int index = brushes.IndexOf(brush);
SessionState.SetInt(s_SessionStateLastUsedBrush, index);
}
public static Type GetDefaultBrushType()
{
Type defaultType = typeof(GridBrush);
int count = 0;
foreach (var type in TypeCache.GetTypesWithAttribute<CustomGridBrushAttribute>())
{
var attrs = type.GetCustomAttributes(typeof(CustomGridBrushAttribute), false) as CustomGridBrushAttribute[];
if (attrs != null && attrs.Length > 0)
{
if (attrs[0].defaultBrush)
{
defaultType = type;
count++;
}
}
}
if (count > 1)
{
Debug.LogWarning("Multiple occurrences of defaultBrush == true found. It should only be declared once.");
}
return defaultType;
}
public static void ActiveGridBrushAssetChanged()
{
if (GridPaintingState.gridBrush == null)
return;
if (IsLibraryBrush(GridPaintingState.gridBrush))
{
instance.SaveLibraryGridBrushAsset(GridPaintingState.gridBrush);
}
}
private void RefreshBrushesCache()
{
if (m_Brushes == null)
m_Brushes = new List<GridBrushBase>();
if (m_Brushes.Count == 0 || !(m_Brushes[0] is GridBrush))
{
Type defaultType = GetDefaultBrushType();
GridBrushBase defaultBrush = LoadOrCreateLibraryGridBrushAsset(defaultType);
m_Brushes.Insert(0, defaultBrush);
m_Brushes[0].name = GetBrushDropdownName(m_Brushes[0]);
}
var brushTypes = TypeCache.GetTypesDerivedFrom<GridBrushBase>().Where(t => t != typeof(GridBrush));
foreach (var brushType in brushTypes)
{
if (IsDefaultInstanceVisibleGridBrushType(brushType))
{
var brush = LoadOrCreateLibraryGridBrushAsset(brushType);
if (brush != null)
m_Brushes.Add(brush);
}
}
string[] guids = AssetDatabase.FindAssets("t:GridBrushBase");
foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
var brush = AssetDatabase.LoadAssetAtPath(path, typeof(GridBrushBase)) as GridBrushBase;
if (brush != null && IsAssetVisibleGridBrushType(brush.GetType()))
m_Brushes.Add(brush);
}
m_BrushNames = new string[m_Brushes.Count];
for (int i = 0; i < m_Brushes.Count; i++)
{
m_BrushNames[i] = m_Brushes[i].name;
}
}
private bool IsDefaultInstanceVisibleGridBrushType(Type brushType)
{
CustomGridBrushAttribute[] customBrushes = brushType.GetCustomAttributes(typeof(CustomGridBrushAttribute), false) as CustomGridBrushAttribute[];
if (customBrushes != null && customBrushes.Length > 0)
{
return !customBrushes[0].hideDefaultInstance;
}
return false;
}
private bool IsAssetVisibleGridBrushType(Type brushType)
{
CustomGridBrushAttribute[] customBrushes = brushType.GetCustomAttributes(typeof(CustomGridBrushAttribute), false) as CustomGridBrushAttribute[];
if (customBrushes != null && customBrushes.Length > 0)
{
return !customBrushes[0].hideAssetInstances;
}
return false;
}
private void SaveLibraryGridBrushAsset(GridBrushBase brush)
{
var gridBrushPath = GenerateGridBrushInstanceLibraryPath(brush.GetType());
string folderPath = Path.GetDirectoryName(gridBrushPath);
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
InternalEditorUtility.SaveToSerializedFileAndForget(new[] { brush }, gridBrushPath, true);
}
private GridBrushBase LoadOrCreateLibraryGridBrushAsset(Type brushType)
{
var serializedObjects = InternalEditorUtility.LoadSerializedFileAndForget(GenerateGridBrushInstanceLibraryPath(brushType));
if (serializedObjects != null && serializedObjects.Length > 0)
{
GridBrushBase brush = serializedObjects[0] as GridBrushBase;
if (brush != null && brush.GetType() == brushType)
return brush;
}
return CreateLibraryGridBrushAsset(brushType);
}
private GridBrushBase CreateLibraryGridBrushAsset(Type brushType)
{
GridBrushBase brush = ScriptableObject.CreateInstance(brushType) as GridBrushBase;
brush.hideFlags = HideFlags.DontSave;
brush.name = GetBrushDropdownName(brush);
SaveLibraryGridBrushAsset(brush);
return brush;
}
private string GenerateGridBrushInstanceLibraryPath(Type brushType)
{
var path = FileUtil.CombinePaths(s_LibraryPath, brushType.ToString() + s_GridBrushExtension);
path = FileUtil.NiceWinPath(path);
return path;
}
private string GetBrushDropdownName(GridBrushBase brush)
{
// Asset Brushes use the asset name
if (!IsLibraryBrush(brush))
return brush.name;
// Library Brushes
CustomGridBrushAttribute[] customBrushes = brush.GetType().GetCustomAttributes(typeof(CustomGridBrushAttribute), false) as CustomGridBrushAttribute[];
if (customBrushes != null && customBrushes.Length > 0 && customBrushes[0].defaultName.Length > 0)
return customBrushes[0].defaultName;
if (brush.GetType() == typeof(GridBrush))
return "Default Brush";
return brush.GetType().Name;
}
private static bool IsLibraryBrush(GridBrushBase brush)
{
return !AssetDatabase.Contains(brush);
}
// TODO: Better way of clearing caches than AssetPostprocessor
public class AssetProcessor : AssetPostprocessor
{
public override int GetPostprocessOrder()
{
return 1;
}
private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromPath)
{
if (!GridPaintingState.savingPalette)
FlushCache();
}
}
internal static void FlushCache()
{
s_RefreshCache = true;
if (instance.m_Brushes != null)
{
instance.m_Brushes.Clear();
GridPaintingState.FlushCache();
}
}
}
}