Initial Commit

This commit is contained in:
Anton Zhernosek
2023-05-23 14:07:24 +02:00
committed by GitHub
parent 772a603c6f
commit 697d6fe98a
33 changed files with 2771 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 49fcc97bf68f1be43af4476942bfc60e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,130 @@
#if UNITY_EDITOR
using System;
using System.Linq.Expressions;
using System.Reflection;
using UnityEditor;
using UnityEngine.UIElements;
namespace Utilities.Extensions.UIToolkit
{
public static class DropdownFieldExtensions
{
private static Type genericOSMenuType;
private static Type iGenericMenuInterfaceType;
private const string CreateMenuCallback_Property_Name = "createMenuCallback";
private const string GenericOsMenu_Type_Name = "UnityEditor.UIElements.GenericOSMenu";
private const string IGenericMenu_Type_Name = "IGenericMenu";
private const string FormatSelectedValueCallback_Property_Name = "formatSelectedValueCallback";
#region Generic Menu Assigning
public static void AssignGenericMenu(this DropdownField dropdownField,
Func<GenericMenu> genericMenuBuildingFunc)
{
Func<object> genericOSMenuFunc = () =>
{
GenericMenu menu = genericMenuBuildingFunc();
return GetGenericOSMenu(menu);
};
object boxedfunc = ConvertFuncToDesiredType(genericOSMenuFunc);
FieldInfo createMenuCallbackFieldInfo = typeof(DropdownField)
.GetField(CreateMenuCallback_Property_Name, BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
createMenuCallbackFieldInfo.SetValue(dropdownField, boxedfunc);
}
#region Generic OS Menu Creation
private static object GetGenericOSMenu(GenericMenu menu)
{
Type type = GetGenericOSMenuType();
object[] args = new object[] { menu };
return Activator.CreateInstance(type, args);
}
#endregion
#region Type helpers
private static Type GetGenericOSMenuType()
{
if (genericOSMenuType == null)
{
genericOSMenuType = typeof(UnityEditor.UIElements.ColorField).Assembly.GetType(GenericOsMenu_Type_Name, false, true);
}
return genericOSMenuType;
}
private static Type GetIGenericMenuInterfaceType()
{
if (iGenericMenuInterfaceType == null)
{
Type genericOSType = GetGenericOSMenuType();
iGenericMenuInterfaceType = genericOSType.GetInterface(IGenericMenu_Type_Name);
}
return iGenericMenuInterfaceType;
}
#endregion
#region Func Conversion
private static Delegate ConvertFuncToDesiredType(Func<object> func)
{
Type interfaceType = GetIGenericMenuInterfaceType();
Type resultType = typeof(Func<>).MakeGenericType(interfaceType);
Expression<Func<object>> expressionFunc = FuncToExpression(func);
InvocationExpression invokedExpression = Expression.Invoke(expressionFunc);
UnaryExpression convertedReturnValue = Expression.Convert(invokedExpression, interfaceType);
LambdaExpression lambda = Expression.Lambda(delegateType: resultType, body: convertedReturnValue);
return lambda.Compile();
}
private static Expression<Func<T>> FuncToExpression<T>(Func<T> f)
{
return () => f();
}
#endregion
#endregion
#region Formatting Callback Assigning
public static void AssignFormattingCallback(this DropdownField dropdownField,
Func<string, string> formattingCallback)
{
#if UNITY_2022_2_OR_NEWER
dropdownField.formatSelectedValueCallback = formattingCallback;
#else
AssignFormattingCallbackViaReflection(dropdownField, formattingCallback);
#endif
}
private static void AssignFormattingCallbackViaReflection(this DropdownField functionDropdown,
Func<string, string> formattingCallback)
{
PropertyInfo propertyInfo = typeof(DropdownField)
.GetProperty(FormatSelectedValueCallback_Property_Name, BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
object[] args = new object[] { formattingCallback };
propertyInfo.SetMethod.Invoke(functionDropdown, args);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f923456164a309c4d81abab46ab3f8ca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4950e11fcaa85be40ba5df654ee71efb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,147 @@
#if UNITY_EDITOR
using System.Collections;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEditor;
namespace Utilities.SerializableData.SerializableFunc.UnityEditorUtilities
{
public static class SerializedPropertyExtensions
{
static readonly Regex rgx = new Regex(@"\[\d+\]", RegexOptions.Compiled);
public static object GetBoxedValue(this SerializedProperty property)
{
property.serializedObject.ApplyModifiedProperties();
#if UNITY_2023_2_OR_NEWER
return property.boxedValue;
#else
return GetValue<object>(property);
#endif
}
public static void SetBoxedValue(this SerializedProperty property, object value)
{
property.serializedObject.Update();
#if UNITY_2023_2_OR_NEWER
property.boxedValue = value;
#else
SetValue<object>(property, value);
#endif
property.serializedObject.ApplyModifiedProperties();
}
public static T GetValue<T>(this SerializedProperty property) where T : class
{
object obj = property.serializedObject.targetObject;
string path = property.propertyPath.Replace(".Array.data", string.Empty);
string[] fieldStructure = path.Split('.');
for (int i = 0; i < fieldStructure.Length; i++)
{
if (fieldStructure[i].Contains("["))
{
int index = System.Convert.ToInt32(new string(fieldStructure[i].Where(c => char.IsDigit(c)).ToArray()));
obj = GetFieldValueWithIndex(rgx.Replace(fieldStructure[i], string.Empty), obj, index);
}
else
{
obj = GetFieldValue(fieldStructure[i], obj);
}
}
return (T)obj;
}
public static bool SetValue<T>(this SerializedProperty property, T value) where T : class
{
object obj = property.serializedObject.targetObject;
string path = property.propertyPath.Replace(".Array.data", "");
string[] fieldStructure = path.Split('.');
for (int i = 0; i < fieldStructure.Length - 1; i++)
{
if (fieldStructure[i].Contains("["))
{
int index = System.Convert.ToInt32(new string(fieldStructure[i].Where(c => char.IsDigit(c)).ToArray()));
obj = GetFieldValueWithIndex(rgx.Replace(fieldStructure[i], ""), obj, index);
}
else
{
obj = GetFieldValue(fieldStructure[i], obj);
}
}
string fieldName = fieldStructure.Last();
if (fieldName.Contains("["))
{
int index = System.Convert.ToInt32(new string(fieldName.Where(c => char.IsDigit(c)).ToArray()));
return SetFieldValueWithIndex(rgx.Replace(fieldName, ""), obj, index, value);
}
else
{
return SetFieldValue(fieldName, obj, value);
}
}
private static object GetFieldValue(string fieldName, object obj, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
{
FieldInfo field = obj.GetType().GetField(fieldName, bindings);
if (field != null)
{
return field.GetValue(obj);
}
return default(object);
}
private static object GetFieldValueWithIndex(string fieldName, object obj, int index, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
{
FieldInfo field = obj.GetType().GetField(fieldName, bindings);
if (field != null)
{
object list = field.GetValue(obj);
if (list.GetType().IsArray)
{
return ((object[])list)[index];
}
else if (list is IEnumerable)
{
return ((IList)list)[index];
}
}
return default(object);
}
public static bool SetFieldValue(string fieldName, object obj, object value, bool includeAllBases = false, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
{
FieldInfo field = obj.GetType().GetField(fieldName, bindings);
if (field != null)
{
field.SetValue(obj, value);
return true;
}
return false;
}
public static bool SetFieldValueWithIndex(string fieldName, object obj, int index, object value, bool includeAllBases = false, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
{
FieldInfo field = obj.GetType().GetField(fieldName, bindings);
if (field != null)
{
object list = field.GetValue(obj);
if (list.GetType().IsArray)
{
((object[])list)[index] = value;
return true;
}
else if (list is IEnumerable)
{
((IList)list)[index] = value;
return true;
}
}
return false;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9092eebd24b0d8d4985c409afe2768d4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8bb44bb4f5e72344b87845ac17958288
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Utilities.Extensions.SystemExtensions
{
public static class TypeExtensions
{
private static Dictionary<Type, string> PrimitiveTypesLookup = new Dictionary<Type, string>
{
{ typeof(bool), "Bool" },
{ typeof(byte), "Byte" },
{ typeof(char), "Char" },
{ typeof(decimal), "Decimal" },
{ typeof(double), "Double" },
{ typeof(float), "Float" },
{ typeof(int), "Int" },
{ typeof(long), "Long" },
{ typeof(sbyte), "Sbyte" },
{ typeof(short), "Short" },
{ typeof(string), "String" },
{ typeof(uint), "Uint" },
{ typeof(ulong), "Ulong" },
{ typeof(ushort), "Ushort" },
};
public static string NicifyTypeName(this Type type)
{
if (type.IsArray)
{
Type elementType = type.GetElementType();
string elementTypeString = NicifyTypeName(elementType);
return $"{elementTypeString}[]";
}
if (!type.IsGenericType)
{
return GetSingleTypeName(type);
}
if (type.IsNested && type.DeclaringType.IsGenericType) return type.Name;
string genericTypeString = $"{type.Name[..type.Name.IndexOf('`')]}";
IEnumerable<string> genericArgumentNames = type.GetGenericArguments()
.Select(x => NicifyTypeName(x));
string genericArgumentsString = string.Join(", ", genericArgumentNames);
return $"{genericTypeString}<{genericArgumentsString}>";
}
private static string GetSingleTypeName(Type type)
{
if (PrimitiveTypesLookup.TryGetValue(type, out string result)) return result;
return type.Name;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 46fcb395397539e4f99e257852dcaaa7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: