forked from Shardstone/trail-into-darkness
added more utilty packges
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Author: Kaynn, Yeo Wen Qin
|
||||
// https://github.com/Kaynn-Cahya
|
||||
// Date: 26/02/2019
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Jovian.Utilities;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace InspectorToolkit {
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class ButtonMethodAttribute : PropertyAttribute {
|
||||
public readonly ButtonMethodDrawOrder DrawOrder;
|
||||
public readonly PlayModeVisibility Visibility;
|
||||
|
||||
public ButtonMethodAttribute(PlayModeVisibility visibility, ButtonMethodDrawOrder drawOrder = ButtonMethodDrawOrder.AfterInspector) {
|
||||
Visibility = visibility;
|
||||
DrawOrder = drawOrder;
|
||||
}
|
||||
|
||||
public ButtonMethodAttribute(ButtonMethodDrawOrder drawOrder = ButtonMethodDrawOrder.AfterInspector) {
|
||||
DrawOrder = drawOrder;
|
||||
Visibility = PlayModeVisibility.Always;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ButtonMethodDrawOrder {
|
||||
BeforeInspector,
|
||||
AfterInspector
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace InspectorToolkit.Internal {
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
|
||||
public class ButtonMethodHandler {
|
||||
|
||||
public class MethodData {
|
||||
public MethodInfo methodInfo;
|
||||
public ParameterData[] parameterDatas;
|
||||
public string niceName;
|
||||
public PlayModeVisibility visibility;
|
||||
public ButtonMethodDrawOrder order;
|
||||
}
|
||||
|
||||
public class ParameterData {
|
||||
public ParameterInfo parameterInfo;
|
||||
public string niceName;
|
||||
public object value;
|
||||
}
|
||||
|
||||
// TODO - replace with MethodDatas;
|
||||
public readonly List<(MethodInfo Method, string Name, PlayModeVisibility visibility, ButtonMethodDrawOrder order)> TargetMethods;
|
||||
public int Amount => TargetMethods?.Count ?? 0;
|
||||
|
||||
public readonly List<MethodData> MethodDatas;
|
||||
|
||||
public bool HasMethods => MethodDatas?.Count > 0;
|
||||
|
||||
private readonly Object _target;
|
||||
|
||||
public Object Target => _target;
|
||||
|
||||
public ButtonMethodHandler(Object target) {
|
||||
_target = target;
|
||||
|
||||
Type type = target.GetType();
|
||||
BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
IEnumerable<MemberInfo> members = type.GetMembers(bindings).Where(IsButtonMethod);
|
||||
|
||||
foreach(MemberInfo member in members) {
|
||||
MethodInfo method = member as MethodInfo;
|
||||
if(method == null) continue;
|
||||
|
||||
if(IsValidMember(method, member)) {
|
||||
ButtonMethodAttribute attribute = (ButtonMethodAttribute)Attribute.GetCustomAttribute(method, typeof(ButtonMethodAttribute));
|
||||
TargetMethods ??= new List<(MethodInfo, string, PlayModeVisibility, ButtonMethodDrawOrder)>();
|
||||
TargetMethods.Add((method, ObjectNames.NicifyVariableName(method.Name), attribute.Visibility, attribute.DrawOrder));
|
||||
MethodDatas ??= new();
|
||||
|
||||
ParameterInfo[] parameterInfos = method.GetParameters();
|
||||
ParameterData[] parameterDatas = new ParameterData[parameterInfos.Length];
|
||||
for(int i = 0; i < parameterInfos.Length; i++) {
|
||||
ParameterInfo info = parameterInfos[i];
|
||||
|
||||
object value;
|
||||
if(info.HasDefaultValue) {
|
||||
value = info.DefaultValue;
|
||||
}
|
||||
else if(info.ParameterType == typeof(string)) {
|
||||
value = "String";
|
||||
}
|
||||
else if(info.ParameterType == typeof(Object) || info.ParameterType.IsSubclassOf(typeof(Object))) {
|
||||
value = null;
|
||||
}
|
||||
else {
|
||||
value = Activator.CreateInstance(info.ParameterType);
|
||||
}
|
||||
|
||||
parameterDatas[i] = new ParameterData() {
|
||||
niceName = ObjectNames.NicifyVariableName(info.Name),
|
||||
parameterInfo = info,
|
||||
value = value
|
||||
};
|
||||
}
|
||||
|
||||
MethodData methodData = new MethodData() {
|
||||
methodInfo = method,
|
||||
niceName = ObjectNames.NicifyVariableName(method.Name),
|
||||
visibility = attribute.Visibility,
|
||||
order = attribute.DrawOrder,
|
||||
parameterDatas = parameterDatas
|
||||
};
|
||||
MethodDatas.Add(methodData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasAnyVisibleMethods() {
|
||||
if(MethodDatas == null || MethodDatas.Count == 0) return false;
|
||||
foreach (MethodData methodData in MethodDatas) {
|
||||
if (methodData.visibility.IsVisible()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnBeforeInspectorGUI() {
|
||||
if(MethodDatas == null || MethodDatas.Count == 0) return;
|
||||
|
||||
DrawButtonMethods(ButtonMethodDrawOrder.BeforeInspector);
|
||||
}
|
||||
|
||||
private void DrawButtonMethods(ButtonMethodDrawOrder drawOrder) {
|
||||
foreach(MethodData method in MethodDatas) {
|
||||
if(method.order != drawOrder) continue;
|
||||
if(!method.visibility.IsVisible()) continue;
|
||||
|
||||
if(method.parameterDatas.Length > 0) {
|
||||
GUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
}
|
||||
|
||||
if(GUILayout.Button(method.niceName)) {
|
||||
object result = method.methodInfo.Invoke(_target, method.parameterDatas.Select(p=>p.value).ToArray());
|
||||
if(result != null) {
|
||||
Debug.Log($"{method.niceName} => {result}");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ParameterData p in method.parameterDatas) {
|
||||
p.value = InspectorGUIUtility.DrawField(p.niceName, p.parameterInfo.ParameterType, p.value);
|
||||
}
|
||||
|
||||
if(method.parameterDatas.Length > 0) {
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnAfterInspectorGUI() {
|
||||
if(MethodDatas == null || MethodDatas.Count == 0) return;
|
||||
DrawButtonMethods(ButtonMethodDrawOrder.AfterInspector);
|
||||
}
|
||||
|
||||
public void Invoke(MethodInfo method) => InvokeMethod(_target, method);
|
||||
|
||||
|
||||
private void InvokeMethod(Object target, MethodInfo method) {
|
||||
object result = method.Invoke(target, null);
|
||||
|
||||
if(result != null) {
|
||||
string message = $"{result} \nResult of Method '{method.Name}' invocation on object {target.name}";
|
||||
Debug.Log(message, target);
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsButtonMethod(MemberInfo memberInfo) {
|
||||
return Attribute.IsDefined(memberInfo, typeof(ButtonMethodAttribute));
|
||||
}
|
||||
|
||||
private bool IsValidMember(MethodInfo method, MemberInfo member) {
|
||||
if(method == null) {
|
||||
Debug.LogWarning(
|
||||
$"Property <color=brown>{member.Name}</color>.Reason: Member is not a method but has EditorButtonAttribute!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user