// Copyright (c) 2015 - 2023 Doozy Entertainment. All Rights Reserved. // This code can only be used under the standard Unity Asset Store End User License Agreement // A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Doozy.Runtime.Common.Extensions; using Doozy.Runtime.Reactor.Reflection.Enums; using UnityEngine; using UnityEngine.Events; using Object = UnityEngine.Object; namespace Doozy.Runtime.Reactor.Reflection.Internal { [Serializable] public abstract class ReflectedValue { [SerializeField] protected Object Target; /// Value target public Object target => Target; [SerializeField] protected string FieldName = ""; /// Target fieldName public string fieldName => FieldName; [SerializeField] protected string PropertyName = ""; /// Target propertyName public string propertyName => PropertyName; [SerializeField] protected ValueDetails ValueDetails = ValueDetails.None; /// Target value details public ValueDetails valueDetails => ValueDetails; protected FieldInfo targetField { get; set; } protected PropertyInfo targetProperty { get; set; } protected bool initialized { get; set; } protected HashSet searchItems { get; set; } /// Check if it's valid and get either the target FieldInfo or the target PropertyInfo public abstract bool Initialize(); public abstract bool IsValid(); public abstract List> GetSearchMenuItems(); protected void SetTarget(Object targetObject) { ClearValueDetails(); Target = targetObject; } protected void SetProperty(string nameOfProperty) { FieldName = string.Empty; PropertyName = nameOfProperty; ValueDetails = nameOfProperty.IsNullOrEmpty() ? ValueDetails.None : ValueDetails.IsProperty; } protected void SetField(string nameOfField) { FieldName = nameOfField; PropertyName = string.Empty; ValueDetails = nameOfField.IsNullOrEmpty() ? ValueDetails.None : ValueDetails.IsField; } protected void ClearValueDetails() { FieldName = string.Empty; PropertyName = string.Empty; ValueDetails = ValueDetails.None; targetField = null; targetProperty = null; } protected GameObject GetGameObject() => Target switch { GameObject go => go, Component co => co.gameObject, _ => null }; protected IEnumerable GetFieldInfos(IReflect targetType) => FieldInfos(targetType, typeof(T)); protected IEnumerable GetPropertyInfos(IReflect targetType) => PropertyInfos(targetType, typeof(T)); protected IEnumerable GetFieldInfos(Object targetObject) => GetFieldInfos(targetObject.GetType()); protected IEnumerable GetPropertyInfos(Object targetObject) => GetPropertyInfos(targetObject.GetType()); protected static IEnumerable FieldInfos(IReflect targetType, Type ofType) => targetType .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static) .Where(f => f.FieldType == ofType); protected static IEnumerable PropertyInfos(IReflect targetType, Type ofType) => targetType .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static) .Where(p => p.PropertyType == ofType && p.CanRead & p.CanWrite); [Serializable] public struct SearchItem { public Object target { get; } public List fields { get; } public List properties { get; } public UnityAction TargetSetter; public UnityAction FieldSetter; public UnityAction PropertySetter; private string typeName => target.GetType().Name; private string GetPath(string s) => $"{typeName}/{s}"; public List> GetSearchActions() { //why are you here? var list = new List>(); // ReSharper disable once ForCanBeConvertedToForeach // ReSharper disable once LoopCanBeConvertedToQuery for (int i = 0; i < fields.Count; i++) { string f = fields[i]; SearchItem tmpThis = this; list.Add(new KeyValuePair(tmpThis.GetPath(f), () => { tmpThis.TargetSetter.Invoke(tmpThis.target); tmpThis.FieldSetter.Invoke(f); })); } // ReSharper disable once ForCanBeConvertedToForeach // ReSharper disable once LoopCanBeConvertedToQuery for (int i = 0; i < properties.Count; i++) { string p = properties[i]; SearchItem tmpThis = this; list.Add(new KeyValuePair(tmpThis.GetPath(p), () => { tmpThis.TargetSetter.Invoke(tmpThis.target); tmpThis.PropertySetter.Invoke(p); })); } return list; } public SearchItem ( Object target, IEnumerable fields, IEnumerable properties, UnityAction targetSetter, UnityAction fieldSetter, UnityAction propertySetter ) { //what are you searching for? this.target = target; this.fields = fields.Select(f => f.Name).ToList(); this.properties = properties.Select(p => p.Name).ToList(); TargetSetter = targetSetter; FieldSetter = fieldSetter; PropertySetter = propertySetter; } } } }