using System.Collections; namespace Sandbox; /// /// An object (or data) that can be accessed as an object /// public abstract class SerializedObject : IEnumerable, IValid { public SerializedProperty ParentProperty { get; set; } public virtual string TypeIcon { get => ""; } public virtual string TypeName { get => ""; } public virtual string TypeTitle { get => ""; } public virtual bool IsValid => true; protected List PropertyList; public delegate void PropertyChangedDelegate( SerializedProperty property ); public delegate void PropertyPreChangeDelegate( SerializedProperty property ); public delegate void PropertyStartEditDelegate( SerializedProperty property ); public delegate void PropertyFinishEditDelegate( SerializedProperty property ); public PropertyPreChangeDelegate OnPropertyPreChange { get; set; } public PropertyChangedDelegate OnPropertyChanged { get; set; } public PropertyStartEditDelegate OnPropertyStartEdit { get; set; } public PropertyFinishEditDelegate OnPropertyFinishEdit { get; set; } public virtual SerializedProperty GetProperty( string v ) { return PropertyList?.FirstOrDefault( x => x.Name == v ); } public virtual bool TryGetProperty( string v, out SerializedProperty prop ) { prop = GetProperty( v ); return prop != null; } public IEnumerator GetEnumerator() { PrepareEnumerator(); return PropertyList.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { PrepareEnumerator(); return ((IEnumerable)PropertyList).GetEnumerator(); } /// /// It's good manners for a changed SerializedProperty to tell its parent /// on set. That way the parent can cascade changes up the tree. This is /// particularly important if the tree includes struct types - because those /// values will need to be re-set on any ParentProperty's. /// public virtual void NoteChanged( SerializedProperty childProperty ) { OnPropertyChanged?.Invoke( childProperty ); if ( ParentProperty is not null ) { ParentProperty.NoteChanged( childProperty ); } } internal void NoteChanged() { OnPropertyChanged?.Invoke( null ); if ( ParentProperty is not null ) { ParentProperty.NoteChanged( ParentProperty ); } } public virtual void NotePreChange( SerializedProperty childProperty ) { OnPropertyPreChange?.Invoke( childProperty ); if ( ParentProperty is not null ) { ParentProperty.NotePreChange( childProperty ); } } internal void NotePreChange() { OnPropertyPreChange?.Invoke( null ); if ( ParentProperty is not null ) { ParentProperty.NotePreChange( ParentProperty ); } } public virtual void NoteStartEdit( SerializedProperty childProperty ) { OnPropertyStartEdit?.Invoke( childProperty ); if ( ParentProperty is not null ) { ParentProperty.NoteStartEdit( childProperty ); } } internal void NoteStartEdit() { OnPropertyStartEdit?.Invoke( null ); if ( ParentProperty is not null ) { ParentProperty.NoteStartEdit( ParentProperty ); } } public virtual void NoteFinishEdit( SerializedProperty childProperty ) { OnPropertyFinishEdit?.Invoke( childProperty ); if ( ParentProperty is not null ) { ParentProperty.NoteFinishEdit( childProperty ); } } internal void NoteFinishEdit() { OnPropertyFinishEdit?.Invoke( null ); if ( ParentProperty is not null ) { ParentProperty.NoteFinishEdit( ParentProperty ); } } /// /// Called right before enumeration, to allow derivitives react to changes /// protected virtual void PrepareEnumerator() { } /// /// True if the target is multiple objects /// public virtual bool IsMultipleTargets => false; /// /// A list of actual target objects - if applicable /// public virtual IEnumerable Targets => Enumerable.Empty(); }