hellbound/Assets/Sources/Feel/MMTools/Tools/MMAttributes/MMExecutionOrderAttribute.cs

160 lines
6.1 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
/// <summary>
/// Add this attribute to a class and its Execution Order will be changed to the value specified in parameters
/// Usage : [ExecutionOrder(66)]
/// </summary>
public class MMExecutionOrderAttribute : Attribute
{
#if UNITY_EDITOR
/// the execution order you want for the class this attribute is applied to
public int ExecutionOrder = 0;
protected static Dictionary<MonoScript, MMExecutionOrderAttribute> _monoScripts;
protected static Type _executionOrderAttributeType;
protected static Assembly _typeAssembly;
protected static Type[] _assemblyTypes;
/// <summary>
/// Attribute method
/// </summary>
/// <param name="newExecutionOrder"></param>
public MMExecutionOrderAttribute(int newExecutionOrder)
{
ExecutionOrder = newExecutionOrder;
}
/// <summary>
/// When Unity loads, modifies the execution orders of monos with an ExecutionOrder attribute, if needed
/// </summary>
[InitializeOnLoadMethod]
protected static void ModifyExecutionOrder()
{
Initialization();
FindExecutionOrderAttributes();
if (ExecutionOrderHasChanged())
{
UpdateExecutionOrders();
}
}
/// <summary>
/// Initialization method
/// </summary>
protected static void Initialization()
{
_monoScripts = new Dictionary<MonoScript, MMExecutionOrderAttribute>();
_executionOrderAttributeType = typeof(MMExecutionOrderAttribute);
_typeAssembly = _executionOrderAttributeType.Assembly;
_assemblyTypes = _typeAssembly.GetTypes();
}
/// <summary>
/// Goes through all assembly types and stores execution order attributes when found
/// </summary>
protected static void FindExecutionOrderAttributes()
{
foreach (Type assemblyType in _assemblyTypes)
{
if (!HasExecutionOrderAttribute(assemblyType))
{
continue;
}
object[] attributes = assemblyType.GetCustomAttributes(_executionOrderAttributeType, false);
MMExecutionOrderAttribute attribute = attributes[0] as MMExecutionOrderAttribute;
string asset = "";
string[] guids = AssetDatabase.FindAssets(assemblyType.Name + " t:script");
if (guids.Length != 0)
{
foreach (string guid in guids)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
string filename = Path.GetFileNameWithoutExtension(assetPath);
if (filename == assemblyType.Name)
{
asset = guid;
break;
}
}
}
else
{
Debug.LogError("MMTools' ExecutionOrderAttribute : Can't change "+ assemblyType.Name + "'s execution order");
return;
}
MonoScript monoScript = AssetDatabase.LoadAssetAtPath<MonoScript>(AssetDatabase.GUIDToAssetPath(asset));
_monoScripts.Add(monoScript, attribute);
}
}
/// <summary>
/// Returns true if the class in parameters has the ExecutionOrder attribute, false otherwise
/// </summary>
/// <param name="assemblyType"></param>
/// <returns></returns>
protected static bool HasExecutionOrderAttribute(Type assemblyType)
{
object[] attributes = assemblyType.GetCustomAttributes(_executionOrderAttributeType, false);
return (attributes.Length == 1);
}
/// <summary>
/// Returns true if the execution order has changed since last time
/// </summary>
/// <returns></returns>
protected static bool ExecutionOrderHasChanged()
{
bool executionOrderHasChanged = false;
foreach (KeyValuePair<MonoScript, MMExecutionOrderAttribute> monoScript in _monoScripts)
{
if (monoScript.Key != null)
{
if (MonoImporter.GetExecutionOrder(monoScript.Key) != monoScript.Value.ExecutionOrder)
{
executionOrderHasChanged = true;
break;
}
}
}
return executionOrderHasChanged;
}
/// <summary>
/// Updates the execution orders for all pairs found by FindExecutionOrderAttributes()
/// </summary>
protected static void UpdateExecutionOrders()
{
foreach (KeyValuePair<MonoScript, MMExecutionOrderAttribute> monoScript in _monoScripts)
{
if (monoScript.Key != null)
{
if (MonoImporter.GetExecutionOrder(monoScript.Key) != monoScript.Value.ExecutionOrder)
{
MonoImporter.SetExecutionOrder(monoScript.Key, monoScript.Value.ExecutionOrder);
}
}
}
}
#endif
}
}