using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using Golems.Attributes;
using Object = UnityEngine.Object;
namespace Golems
{
public partial class AttributesEditor
{
private const BindingFlags k_ButtonBindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public |
BindingFlags.NonPublic;
///
/// Map between Method names and parameters for Methods
///
private Dictionary m_Parameters = new Dictionary();
private void OnInspectorGUIButtonAttribute ()
{
var methods = target.GetType().GetMethods(k_ButtonBindingFlags);
//
// Search for Button Attribute within Each Method on this Object
//
for (int i = 0, counti = methods.Length; i < counti; ++i)
{
var method = methods[i];
var buttonAttribute = method.GetCustomAttribute(false);
if (buttonAttribute == null)
continue;
var name = string.IsNullOrEmpty(buttonAttribute.Ident) ? method.Name : buttonAttribute.Ident;
//
// Invoke Method with parms on button pressed
//
if (GUILayout.Button(name))
{
m_Parameters.TryGetValue(name, out var parms);
if (parms != null)
{
var p = new List();
for (int j = 0, countj = parms.Length; j < countj; ++j)
{
p.Add(parms[j]);
//
// Skip over array size
//
if (parms[j].GetType().IsArray) ++j;
}
method.Invoke(target, p.ToArray());
} else method.Invoke(target, parms);
}
EditorGUI.indentLevel++;
SetUpParameters(name, method);
EditorGUI.indentLevel--;
}
}
///
/// Set up Parameters for use on Method Invocation
///
private void SetUpParameters(string name, MethodInfo method)
{
var parameterInfo = method.GetParameters();
if (parameterInfo.Length <= 0) return;
//
// Check if Method has already has its parameters setup.
// If not create a new array and add to dict.
//
if (!m_Parameters.TryGetValue(name, out var parameters))
{
var p = new List(parameterInfo.Length);
for (int i = 0, counti = parameterInfo.Length; i < counti; ++i)
{
p.Add(default);
//
// If we have an Array add an additional parameter for size
//
if (parameterInfo[i].ParameterType.IsArray)
{
p.Add(default);
}
}
m_Parameters.Add(name, p.ToArray());
}
if (parameters == null) return;
//
// Iterate over each parameter and set up relevant display Field.
//
for (int i = 0, counti = parameters.Length, pi = 0; i < counti; ++i, ++pi)
{
var paramName = parameterInfo[pi].Name;
if (parameterInfo[pi].ParameterType == typeof(int))
{
int val = parameters[i] == null ? 0 : (int)parameters[i];
parameters[i] = EditorGUILayout.IntField(paramName, val);
}
else if (parameterInfo[pi].ParameterType == typeof(float))
{
float val = parameters[i] == null ? 0 : (float)parameters[i];
parameters[i] = EditorGUILayout.FloatField(paramName, val);
}
else if (parameterInfo[pi].ParameterType == typeof(string))
{
string val = String.IsNullOrEmpty((string)parameters[i]) ? "" : (string)parameters[i];
parameters[i] = EditorGUILayout.TextField(paramName, val);
}
else if (parameterInfo[pi].ParameterType == typeof(bool))
{
bool val = parameters[i] != null && (bool)parameters[i];
parameters[i] = EditorGUILayout.Toggle(paramName, val);
}
else if (parameterInfo[pi].ParameterType == typeof(char))
{
string val = "";
if (parameters[i] != null)
{
val = ((char)parameters[i]).ToString();
}
val = EditorGUILayout.TextField(paramName, val);
if (!String.IsNullOrEmpty(val))
{
parameters[i] = val[0];
}
}
else if (parameterInfo[pi].ParameterType == typeof(Sprite))
{
Sprite val = parameters[i] != null ? (Sprite)parameters[i] : default;
parameters[i] = EditorGUILayout.ObjectField(paramName, val, typeof(Sprite), false) as Sprite;
}
else
{
//
// GameObject Array support - copy me around if we want more Inspector Button Arrays
//
if (parameterInfo[pi].ParameterType.IsArray)
{
//
// We can Safely assume next item is index
//
var arraySizeIndex = i + 1;
int size = parameters[arraySizeIndex] == null ? 0 : (int)parameters[arraySizeIndex];
parameters[arraySizeIndex] = EditorGUILayout.IntField($"{paramName} Size: ", size);
var arrayParameter = (GameObject[]) parameters[i] ?? new GameObject[0];
if (arrayParameter.Length != size)
{
Array.Resize(ref arrayParameter, size);
}
EditorGUI.indentLevel++;
for (int j = 0, countj = size; j < countj; ++j)
{
GameObject val = arrayParameter[j] == null ? default : arrayParameter[j];
arrayParameter[j] = EditorGUILayout.ObjectField($"{paramName} - {j}", val, typeof(UnityEngine.GameObject), true) as GameObject;
}
EditorGUI.indentLevel--;
parameters[i] = arrayParameter;
//
// Advance an extra step to skip Array size
//
++i;
}
else
{
GameObject val = (UnityEngine.GameObject) parameters[i];
parameters[i] = EditorGUILayout.ObjectField(paramName, val, parameterInfo[pi].ParameterType, true);
}
}
}
}
}
}