using Expressive; using System; using System.Dynamic; using System.Linq; namespace InABox.Core { public interface IEntityLink : ISubObject { Guid ID { get; set; } Guid Deleted { get; set; } bool Synchronise(object entity); bool Clear(); bool IsValid(); } public interface IEntityLink : IEntityLink { } public abstract class EntityLink : BaseObject, IEntityLink where T : Entity, new() { /* private Func? _linkedentity; [DoNotSerialize] protected BaseObject? LinkedEntity() => _linkedentity?.Invoke();*/ private BaseObject _linkedParent; private string _linkedPath; public void SetLinkedParent(BaseObject parent) { _linkedParent = parent; } public void SetLinkedPath(string path) { _linkedPath = path; } public BaseObject GetLinkedParent() => _linkedParent; public string GetLinkedPath() => _linkedPath; /* [Obsolete("Please supply linked Entity")] public EntityLink() { } public EntityLink(Func? entity, string name) { _linkedentity = entity; }*/ [NullEditor] public abstract Guid ID { get; set; } [NullEditor] [Obsolete] public Guid Deleted { get; set; } /// /// Basically do the same as , but also copy the . /// /// The link to copy data from. public void CopyFrom(IEntityLink other) { ID = other.ID; Synchronise(other); } /// /// Basically do the same as , but also copy the . /// /// The link to copy data from. public void CopyFrom(T other) { ID = other.ID; Synchronise(other); } public virtual bool Synchronise(object Entity) { var result = false; foreach (var prop in DatabaseSchema.Properties(GetType())) { if (prop.Name == "ID" || !(prop is StandardProperty stdProp) || stdProp.Property.DeclaringType.Equals(typeof(BaseObject))) continue; var entityProp = DatabaseSchema.Property(Entity.GetType(), prop.Name); if(entityProp != null) { prop.Setter()(this, entityProp.Getter()(Entity)); } } foreach (var link in LinkedProperties.Find(this, out var parent)) { link.Update(this, parent); result = true; } return result; } public bool Clear() { var result = false; var props = CoreUtils.PropertyList(GetType(), x => !x.Name.Equals("ID"), false); foreach (var prop in DatabaseSchema.Properties(GetType())) { if (prop.Name == "ID" || !(prop is StandardProperty stdProp) || stdProp.Property.DeclaringType.Equals(typeof(BaseObject))) continue; var entityProp = DatabaseSchema.Property(typeof(T), prop.Name); if(entityProp != null && entityProp.PropertyType == stdProp.PropertyType) { var oldValue = prop.Getter()(this); var newValue = CoreUtils.GetDefault(prop.PropertyType); if(!object.Equals(oldValue, newValue)) { result = true; prop.Setter()(this, newValue); } } } return result; } protected override void DoPropertyChanged(string name, object? before, object? after) { if (IsObserving()) { if(LinkedProperties.Find(this, name, out var link, out var parent)) { link.Update(this, parent); } } } public bool IsValid() => !ID.Equals(Guid.Empty) && Deleted.Equals(Guid.Empty); } }