using System; using System.Linq; using System.Reflection; using UnityEngine; namespace Unity.VisualScripting { public sealed class IndexerMetadata : Metadata { public IndexerMetadata(object indexer, Metadata parent) : base(indexer, parent) { if (indexer == null) { throw new ArgumentNullException(nameof(indexer)); } this.indexer = indexer; indexers = new[] { indexer }; Reflect(true); } private readonly object[] indexers; public object indexer { get; private set; } public PropertyInfo indexerProperty { get; private set; } protected override object rawValue { get { return indexerProperty.GetValue(parent.value, indexers); } set { indexerProperty.SetValue(parent.value, value, indexers); } } protected override void OnParentValueChange(object previousValue) { base.OnParentValueChange(previousValue); Reflect(false); } private void Reflect(bool throwOnFail) { indexerProperty = parent.valueType.GetProperties().FirstOrDefault(property => { var indexParameters = property.GetIndexParameters(); if (indexParameters.Length != 1) { return false; } if (property.Name != "Item") { return false; } if (indexParameters[0].ParameterType.IsInstanceOfType(indexer)) { return true; } return false; }); if (indexerProperty == null) { if (throwOnFail) { throw new InvalidOperationException("Parent of reflected indexer is does not have a matching indexer property:\n" + this); } else { Unlink(); return; } } definedType = indexerProperty.PropertyType; label = new GUIContent(parent.label); } public override Attribute[] GetCustomAttributes(bool inherit = true) { return parent.GetCustomAttributes(inherit); } } }