using System; using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; namespace PepperDash.Essentials.Core { public abstract class BoolFeedbackLogic { /// /// Output representing the "and" value of all connected inputs /// public BoolFeedback Output { get; private set; } /// /// List of all connected outputs /// protected List OutputsIn = new List(); protected bool ComputedValue; public BoolFeedbackLogic() { Output = new BoolFeedback(() => ComputedValue); } public void AddOutputIn(BoolFeedback output) { // Don't double up outputs if(OutputsIn.Contains(output)) return; OutputsIn.Add(output); output.OutputChange += AnyInput_OutputChange; Evaluate(); } public void AddOutputsIn(List outputs) { foreach (var o in outputs) { // skip existing if (OutputsIn.Contains(o)) continue; OutputsIn.Add(o); o.OutputChange += AnyInput_OutputChange; } Evaluate(); } public void RemoveOutputIn(BoolFeedback output) { // Don't double up outputs if (OutputsIn.Contains(output)) return; OutputsIn.Remove(output); output.OutputChange -= AnyInput_OutputChange; Evaluate(); } public void RemoveOutputsIn(List outputs) { foreach (var o in outputs) { OutputsIn.Remove(o); o.OutputChange -= AnyInput_OutputChange; } Evaluate(); } void AnyInput_OutputChange(object sender, EventArgs e) { Evaluate(); } protected abstract void Evaluate(); } public class BoolFeedbackAnd : BoolFeedbackLogic { protected override void Evaluate() { var prevValue = ComputedValue; var newValue = OutputsIn.All(o => o.BoolValue); if (newValue != prevValue) { ComputedValue = newValue; Output.FireUpdate(); } } } public class BoolFeedbackOr : BoolFeedbackLogic { protected override void Evaluate() { var prevValue = ComputedValue; var newValue = OutputsIn.Any(o => o.BoolValue); if (newValue != prevValue) { ComputedValue = newValue; Output.FireUpdate(); } } } public class BoolFeedbackLinq : BoolFeedbackLogic { Func, bool> Predicate; public BoolFeedbackLinq(Func, bool> predicate) : base() { Predicate = predicate; } protected override void Evaluate() { var prevValue = ComputedValue; var newValue = Predicate(OutputsIn); if (newValue != prevValue) { ComputedValue = newValue; Output.FireUpdate(); } } } }