Editor/TypeLibraryFixes/ActionBasedSerializedPropertyFixed.cs
using Facepunch.ActionGraphs;
using Sandbox;
using Sandbox.Internal;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ExtendedEditor.TypeLibraryFixes;

public class ActionBasedSerializedPropertyFixed : SerializedProperty
{
    public Func<SerializedProperty, SerializedObject>? PropertyToObject;

    public override SerializedObject Parent => _parent!;
    public override bool IsMethod => false;
    public override string Name => _name;
    public override string DisplayName => _title;
    public override string Description => _description;
    public override string GroupName => _groupName!;
    public override bool IsEditable => true;
    public override int Order => 0;
    public override Type PropertyType => _propertyType;
    public override string SourceFile => _sourceFile!;
    public override int SourceLine => _sourceLine;
    public override bool HasChanges => false;

    public override ref AsAccessor As => ref base.As;

    private readonly Type _propertyType;

    private readonly string _name;
    private readonly string _title;
    private readonly string _description;
    private readonly string? _groupName;
    private readonly string? _sourceFile;
    private readonly int _sourceLine;
    private readonly Func<object> _get;
    private readonly Action<object> _set;
    private readonly List<Attribute> _attributes;
    private readonly SerializedObject? _parent;


    public ActionBasedSerializedPropertyFixed(Type propertyType, string name, string title, string description,
        Func<object> get, Action<object> set, IEnumerable<Attribute>? attributes = null, SerializedObject? parent = null)
    {
        _propertyType = propertyType;

        _name = name;
        _title = title;
        _description = description;
        _get = get;
        _set = set;
        _attributes = [.. attributes ?? []];
        _parent = parent;

        _groupName = _attributes.OfType<IGroupAttribute>().FirstOrDefault()?.Value ?? _groupName;
        _groupName = _attributes.OfType<ICategoryProvider>().FirstOrDefault()?.Value ?? _groupName;
        _description = _attributes.OfType<IDescriptionAttribute>().FirstOrDefault()?.Value ?? _description;
        _title = _attributes.OfType<ITitleProvider>().FirstOrDefault()?.Value ?? _title;
        _sourceFile = _attributes.OfType<ISourcePathProvider>().FirstOrDefault()?.Path ?? _sourceFile;
        _sourceLine = _attributes.OfType<ISourceLineProvider>().FirstOrDefault()?.Line ?? _sourceLine;
    }

    public override U GetValue<U>(U defaultValue = default!) => SerializedProperty.ValueToTypeFixed((U)_get(), defaultValue)!;
    public override void SetValue<U>(U value) => _set(SerializedProperty.ValueToTypeFixed(_propertyType, value)!);
    public override IEnumerable<Attribute> GetAttributes() => _attributes;

    public override bool TryGetAsObject(out SerializedObject obj)
    {
        obj = (PropertyToObject?.Invoke(this) ?? null)!;
        return obj is not null;
    }
}