using System; using System.Collections.Generic; using System.Linq; namespace Pf2e.WPF.EntityViewer.EntityViewStructure; /// /// Класс для построения структуры данных класса. /// internal class StructureBuilder { /// /// Список обработанных объектов. /// private readonly List _processedObjects = []; /// /// Создание поля структуры. /// /// Название поля. /// Значение поля. /// Глубина, на котором поле отображается. /// Поле структуры. public StructureFieldComplex Create(string name, object value, int depth = 0) { _ = RegisterProcessed(value); StructureFieldComplex field = new(this, value, name, depth); CompleteProcessed(value, field); return field; } /// /// Регистрация обработанного объекта. /// /// Регистрируемый объект. /// `true`, если объект был добавлен; `false`, если объект был добавлен ранее. public bool RegisterProcessed(object value) { if (_processedObjects.Any(p => p.Value == value)) { return false; } StructureProcessedObject processed = new(value); _processedObjects.Add(processed); return true; } /// /// Дополнить обработанный объект. /// /// Значение. /// Поле объекта. public void CompleteProcessed(object value, StructureFieldComplex field) { StructureProcessedObject? q = _processedObjects.FirstOrDefault(p => p.Value == value); if (q == null) { return; } q.Field = field; } /// /// Выбор поля структуры по значению. /// /// Название поля. /// Значение поля. /// Глубина, на котором поле отображается. /// public StructureField Resolve(string name, object? value, int depth) { switch (GetFieldType(value)) { case StructureFieldType.Null: return new StructureFieldNull(this, name, depth); case StructureFieldType.Primitive: return new StructureFieldPrimitive(this, value!, name, depth); case StructureFieldType.Enum: return new StructureFieldEnum(this, value!, name, depth); case StructureFieldType.Reference: break; case StructureFieldType.Complex: default: StructureProcessedObject? processed = _processedObjects.FirstOrDefault(p => p.Value == value ); if (processed is null) { return Create(name, value!, depth); } StructureFieldReference reference = new(this, name, null, depth); processed.AddReference(reference); return reference; } throw new("Impossible"); } /// /// Получить тип поля структуры по значению. /// /// Значение поля. /// Тип поля структуры. public static StructureFieldType GetFieldType(object? value) { if (value is null) { return StructureFieldType.Null; } Type type = value.GetType(); if (type.IsEnum) { return StructureFieldType.Enum; } if (type.IsPrimitive || type == typeof(string)) { return StructureFieldType.Primitive; } return StructureFieldType.Complex; } }