From a053363e76a0b37caee439e8d841123330a8a706 Mon Sep 17 00:00:00 2001 From: Will Bennion Date: Sat, 6 Jun 2020 22:07:02 +0100 Subject: [PATCH 1/2] Added boolean change detector. --- .../Project-Aurora/Project-Aurora.csproj | 2 +- ...eDetector.cs => Boolean_ChangeDetector.cs} | 51 +++++++++++++++++-- 2 files changed, 47 insertions(+), 6 deletions(-) rename Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/{Boolean_NumericChangeDetector.cs => Boolean_ChangeDetector.cs} (55%) diff --git a/Project-Aurora/Project-Aurora/Project-Aurora.csproj b/Project-Aurora/Project-Aurora/Project-Aurora.csproj index ad8c646dd..fbbd15b40 100644 --- a/Project-Aurora/Project-Aurora/Project-Aurora.csproj +++ b/Project-Aurora/Project-Aurora/Project-Aurora.csproj @@ -594,7 +594,7 @@ Control_BinaryCounterLayer.xaml - + diff --git a/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_NumericChangeDetector.cs b/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_ChangeDetector.cs similarity index 55% rename from Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_NumericChangeDetector.cs rename to Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_ChangeDetector.cs index 40079b25e..49db76d76 100644 --- a/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_NumericChangeDetector.cs +++ b/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_ChangeDetector.cs @@ -25,22 +25,22 @@ public NumericChangeDetector(Evaluatable eval, bool detectRising = true, DetectionThreshold = threshold; } - public Evaluatable Evaluatable { get; set; } = new NumberConstant(); + public Evaluatable Evaluatable { get; set; } = EvaluatableDefaults.Get(); public bool DetectRising { get; set; } = true; public bool DetectFalling { get; set; } = true; public double DetectionThreshold { get; set; } = 0; public override Visual GetControl() => new StackPanel() .WithChild(new Control_EvaluatablePresenter { EvalType = typeof(double) } - .WithBinding(Control_EvaluatablePresenter.ExpressionProperty, this, "Evaluatable", BindingMode.TwoWay)) + .WithBinding(Control_EvaluatablePresenter.ExpressionProperty, this, nameof(Evaluatable), BindingMode.TwoWay)) .WithChild(new CheckBox { Content = "Trigger on increase" } - .WithBinding(CheckBox.IsCheckedProperty, this, "DetectRising")) + .WithBinding(CheckBox.IsCheckedProperty, this, nameof(DetectRising))) .WithChild(new CheckBox { Content = "Trigger on decrease" } - .WithBinding(CheckBox.IsCheckedProperty, this, "DetectFalling")) + .WithBinding(CheckBox.IsCheckedProperty, this, nameof(DetectFalling))) .WithChild(new DockPanel { LastChildFill = true } .WithChild(new Label { Content = "Change required", VerticalAlignment = System.Windows.VerticalAlignment.Center }, Dock.Left) .WithChild(new DoubleUpDown { Minimum = 0 } - .WithBinding(DoubleUpDown.ValueProperty, this, "DetectionThreshold"))); + .WithBinding(DoubleUpDown.ValueProperty, this, nameof(DetectionThreshold)))); protected override bool Execute(IGameState gameState) { var val = Evaluatable.Evaluate(gameState); @@ -59,4 +59,45 @@ protected override bool Execute(IGameState gameState) { public override Evaluatable Clone() => new NumericChangeDetector { Evaluatable = Evaluatable.Clone(), DetectRising = DetectRising, DetectFalling = DetectFalling, DetectionThreshold = DetectionThreshold }; } + + + + /// + /// Evaluatable that detects when a boolean value changes. + /// + [Evaluatable("Boolean Change Detector", category: EvaluatableCategory.Logic)] + public class BooleanChangeDetector : Evaluatable { + + private bool? lastValue; + + public BooleanChangeDetector() { } + public BooleanChangeDetector(Evaluatable eval) : this(eval, true, true) { } + public BooleanChangeDetector(Evaluatable eval, bool detectTrue = true, bool detectFalse = true) { + Evaluatable = eval; + DetectTrue = detectTrue; + DetectFalse = detectFalse; + } + + public Evaluatable Evaluatable { get; set; } = EvaluatableDefaults.Get(); + public bool DetectTrue { get; set; } = true; + public bool DetectFalse { get; set; } = true; + + public override Visual GetControl() => new StackPanel() + .WithChild(new Control_EvaluatablePresenter { EvalType = typeof(bool) } + .WithBinding(Control_EvaluatablePresenter.ExpressionProperty, this, nameof(Evaluatable), BindingMode.TwoWay)) + .WithChild(new CheckBox { Content = "Trigger on become true" } + .WithBinding(CheckBox.IsCheckedProperty, this, nameof(DetectTrue))) + .WithChild(new CheckBox { Content = "Trigger on become false" } + .WithBinding(CheckBox.IsCheckedProperty, this, nameof(DetectFalse))); + + protected override bool Execute(IGameState gameState) { + var val = Evaluatable.Evaluate(gameState); + var result = (val && lastValue == false && DetectTrue) // Result is true if: the next value is true, the old value was false and we are detecting true + || (!val && lastValue == true && DetectFalse); // Or the next value is false, the old value was true and we are detecting false + lastValue = val; + return result; + } + + public override Evaluatable Clone() => new BooleanChangeDetector { Evaluatable = Evaluatable.Clone(), DetectTrue = DetectTrue, DetectFalse = DetectFalse }; + } } From 78dbd18630d1afe8d0342edad0be49ccb7f75903 Mon Sep 17 00:00:00 2001 From: Will Bennion Date: Sat, 6 Jun 2020 22:16:17 +0100 Subject: [PATCH 2/2] Added a new toggle flip-flop that takes a single bool value and toggles the state if that boolean is true. Renamed `Boolean_Latch` to `Boolean_FlipFlopSR`. --- .../Project-Aurora/Project-Aurora.csproj | 2 +- .../Logic/Boolean/Boolean_FlipFlop.cs | 77 +++++++++++++++++++ .../Overrides/Logic/Boolean/Boolean_Latch.cs | 46 ----------- .../Project-Aurora/Utils/JSONUtils.cs | 2 + 4 files changed, 80 insertions(+), 47 deletions(-) create mode 100644 Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_FlipFlop.cs delete mode 100644 Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_Latch.cs diff --git a/Project-Aurora/Project-Aurora/Project-Aurora.csproj b/Project-Aurora/Project-Aurora/Project-Aurora.csproj index fbbd15b40..e0b45ea4a 100644 --- a/Project-Aurora/Project-Aurora/Project-Aurora.csproj +++ b/Project-Aurora/Project-Aurora/Project-Aurora.csproj @@ -593,7 +593,7 @@ Control_BinaryCounterLayer.xaml - + diff --git a/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_FlipFlop.cs b/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_FlipFlop.cs new file mode 100644 index 000000000..a22bbf8c5 --- /dev/null +++ b/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_FlipFlop.cs @@ -0,0 +1,77 @@ +using Aurora.Profiles; +using Aurora.Utils; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Media; + +namespace Aurora.Settings.Overrides.Logic.Boolean { + + /// + /// A simple memory gate that can be used for storing a boolean state. + /// While the given input is true, the state of the flip-flop is toggled. + /// + [Evaluatable("Flip-flop (Toggle)", category: EvaluatableCategory.Logic)] + public class Boolean_FlipFlopT : Evaluatable { + + private bool state = false; + + public Evaluatable Toggle { get; set; } + + public Boolean_FlipFlopT() : this(EvaluatableDefaults.Get()) { } + public Boolean_FlipFlopT(Evaluatable toggle) => Toggle = toggle; + + protected override bool Execute(IGameState gameState) { + if (Toggle.Evaluate(gameState)) + state = !state; + return state; + } + + public override Visual GetControl() => new StackPanel() + .WithChild(new TextBlock { Text = "Flip-Flop (Toggle)", FontWeight = FontWeights.Bold }) + .WithChild(new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 4, 0, 4) } + .WithChild(new Label { Content = "Toggle" }) + .WithChild(new Control_EvaluatablePresenter { EvalType = typeof(bool) } + .WithBinding(Control_EvaluatablePresenter.ExpressionProperty, new Binding(nameof(Toggle)) { Source = this, Mode = BindingMode.TwoWay }))); + + public override Evaluatable Clone() => new Boolean_FlipFlopT(Toggle.Clone()); + } + + + /// + /// A simple memory gate that can be used for storing a boolean state. + /// When 'Set' is true, the gate will start outputting true until 'Reset' becomes true. + /// + [Evaluatable("Flip-flop (Set-Reset)", category: EvaluatableCategory.Logic)] + public class Boolean_FlipFlopSR : Evaluatable { + + private bool state = false; + + public Evaluatable Set { get; set; } + public Evaluatable Reset { get; set; } + + public Boolean_FlipFlopSR() : this(EvaluatableDefaults.Get(),EvaluatableDefaults.Get()) { } + public Boolean_FlipFlopSR(Evaluatable set, Evaluatable reset) { Set = set; Reset = reset; } + + protected override bool Execute(IGameState gameState) { + if (Reset.Evaluate(gameState)) + state = false; + if (Set.Evaluate(gameState)) + state = true; + return state; + } + + public override Visual GetControl() => new StackPanel() + .WithChild(new TextBlock { Text = "Flip-Flop (Set-Reset)", FontWeight = FontWeights.Bold }) + .WithChild(new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 4, 0, 4) } + .WithChild(new Label { Content = "Set" }) + .WithChild(new Control_EvaluatablePresenter { EvalType = typeof(bool) } + .WithBinding(Control_EvaluatablePresenter.ExpressionProperty, new Binding(nameof(Set)) { Source = this, Mode = BindingMode.TwoWay }))) + .WithChild(new StackPanel { Orientation = Orientation.Horizontal } + .WithChild(new Label { Content = "Reset" }) + .WithChild(new Control_EvaluatablePresenter { EvalType = typeof(bool) } + .WithBinding(Control_EvaluatablePresenter.ExpressionProperty, new Binding(nameof(Reset)) { Source = this, Mode = BindingMode.TwoWay }))); + + public override Evaluatable Clone() => new Boolean_FlipFlopSR(Set.Clone(), Reset.Clone()); + } +} diff --git a/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_Latch.cs b/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_Latch.cs deleted file mode 100644 index d88cb1dfb..000000000 --- a/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_Latch.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Aurora.Profiles; -using Aurora.Utils; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Media; - -namespace Aurora.Settings.Overrides.Logic.Boolean { - - /// - /// A simple memory gate that can be used for storing a boolean state. - /// When 'Set' is true, the gate will start outputting true until 'Reset' becomes true. - /// - [Evaluatable("Flip-flop", category: EvaluatableCategory.Logic)] - public class Boolean_Latch : Evaluatable { - - private bool state = false; - - public Evaluatable Set { get; set; } - public Evaluatable Reset { get; set; } - - public Boolean_Latch() : this(EvaluatableDefaults.Get(),EvaluatableDefaults.Get()) { } - public Boolean_Latch(Evaluatable set, Evaluatable reset) { Set = set; Reset = reset; } - - protected override bool Execute(IGameState gameState) { - if (Reset.Evaluate(gameState)) - state = false; - if (Set.Evaluate(gameState)) - state = true; - return state; - } - - public override Visual GetControl() => new StackPanel() - .WithChild(new TextBlock { Text = "Flip-Flop", FontWeight = FontWeights.Bold }) - .WithChild(new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 4, 0, 4) } - .WithChild(new Label { Content = "Set" }) - .WithChild(new Control_EvaluatablePresenter { EvalType = typeof(bool) } - .WithBinding(Control_EvaluatablePresenter.ExpressionProperty, new Binding(nameof(Set)) { Source = this, Mode = BindingMode.TwoWay }))) - .WithChild(new StackPanel { Orientation = Orientation.Horizontal } - .WithChild(new Label { Content = "Reset" }) - .WithChild(new Control_EvaluatablePresenter { EvalType = typeof(bool) } - .WithBinding(Control_EvaluatablePresenter.ExpressionProperty, new Binding(nameof(Reset)) { Source = this, Mode = BindingMode.TwoWay }))); - - public override Evaluatable Clone() => new Boolean_Latch(Set.Clone(), Reset.Clone()); - } -} diff --git a/Project-Aurora/Project-Aurora/Utils/JSONUtils.cs b/Project-Aurora/Project-Aurora/Utils/JSONUtils.cs index 88b7cf8da..e1471be3d 100755 --- a/Project-Aurora/Project-Aurora/Utils/JSONUtils.cs +++ b/Project-Aurora/Project-Aurora/Utils/JSONUtils.cs @@ -66,6 +66,8 @@ public override Type BindToType(string assemblyName, string typeName) case "System.Collections.ObjectModel.ObservableCollection`1[[Aurora.Settings.Overrides.Logic.IEvaluatableString, Aurora]]": case "System.Collections.ObjectModel.ObservableCollection`1[[Aurora.Settings.Overrides.Logic.IEvaluatable`1[[System.String, mscorlib]], Aurora]]": return typeof(ObservableCollection>); + case "Aurora.Settings.Overrides.Logic.Boolean.Boolean_Latch": + return typeof(Settings.Overrides.Logic.Boolean.Boolean_FlipFlopSR); default: if (!typeName.Contains("Overlays") && new Regex(@"Aurora.Profiles.\w+.\w+Settings").IsMatch(typeName)) return base.BindToType(assemblyName, typeName.Replace("Settings", "Profile"));