1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-12 13:28:33 +00:00

NumberBox - Fixed values getting coerced between 0 and 100

Data model event cycle node - Listen to the event directly, avoiding race conditions
This commit is contained in:
Robert 2023-05-26 00:16:26 +02:00
parent dc8147d5a7
commit c24e57e556
2 changed files with 76 additions and 80 deletions

View File

@ -3,27 +3,30 @@
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:attachedProperties="clr-namespace:Artemis.UI.Shared.AttachedProperties"
xmlns:system="clr-namespace:System;assembly=System.Runtime">
<Design.PreviewWith>
<Border Padding="20">
<StackPanel Spacing="20">
<!-- Add Controls for Previewer Here -->
<controls:NumberBox Value="99999999"
<Design.PreviewWith>
<Border Padding="20">
<StackPanel Spacing="20">
<!-- Add Controls for Previewer Here -->
<controls:NumberBox Value="99999999"
attachedProperties:NumberBoxAssist.PrefixText="%"
attachedProperties:NumberBoxAssist.SuffixText="%"/>
<controls:NumberBox Classes="condensed"
Value="9999999"
attachedProperties:NumberBoxAssist.PrefixText="%"
attachedProperties:NumberBoxAssist.SuffixText="%">
attachedProperties:NumberBoxAssist.SuffixText="%" />
<controls:NumberBox Classes="condensed"
Value="9999999"
attachedProperties:NumberBoxAssist.PrefixText="%"
attachedProperties:NumberBoxAssist.SuffixText="%">
<DataValidationErrors.Error>
<system:Exception/>
<system:Exception />
</DataValidationErrors.Error>
</controls:NumberBox>
</StackPanel>
</Border>
</Design.PreviewWith>
</Border>
</Design.PreviewWith>
<!-- Add Styles Here -->
<Style Selector="controls|NumberBox">
<Setter Property="Maximum" Value="{x:Static system:Double.MaxValue}"></Setter>
<Setter Property="Minimum" Value="{x:Static system:Double.MinValue}"></Setter>
</Style>
<Style Selector="controls|NumberBox /template/ TextBox.NumberBoxTextBoxStyle /template/ TextBlock#PART_Prefix">
<Setter Property="Foreground" Value="{DynamicResource TextControlForegroundDisabled}"></Setter>
<Setter Property="Margin" Value="-4 0 -12 0"></Setter>
@ -39,9 +42,7 @@
<Style Selector="controls|NumberBox.condensed /template/ TextBox.NumberBoxTextBoxStyle /template/ TextBlock#PART_Suffix">
<Setter Property="Margin" Value="-4 0 0 0"></Setter>
</Style>
<Style Selector="controls|NumberBox /template/ TextBox.NumberBoxTextBoxStyle">
<Style Selector="controls|NumberBox /template/ TextBox.NumberBoxTextBoxStyle">
<Setter Property="attachedProperties:TextBoxAssist.PrefixText" Value="{TemplateBinding attachedProperties:NumberBoxAssist.PrefixText}"></Setter>
<Setter Property="attachedProperties:TextBoxAssist.SuffixText" Value="{TemplateBinding attachedProperties:NumberBoxAssist.SuffixText}"></Setter>
</Style>

View File

@ -12,7 +12,6 @@ public class DataModelEventCycleNode : Node<DataModelPathEntity, DataModelEventC
private Type _currentType;
private DataModelPath? _dataModelPath;
private object? _lastPathValue;
private DateTime _lastTrigger;
private bool _updating;
public DataModelEventCycleNode()
@ -22,8 +21,8 @@ public class DataModelEventCycleNode : Node<DataModelPathEntity, DataModelEventC
CycleValues = CreateInputPinCollection(typeof(object), "", 0);
Output = CreateOutputPin(typeof(object));
CycleValues.PinAdded += CycleValuesOnPinAdded;
CycleValues.PinRemoved += CycleValuesOnPinRemoved;
CycleValues.PinAdded += OnCycleValuesOnPinAdded;
CycleValues.PinRemoved += OnCycleValuesOnPinRemoved;
CycleValues.Add(CycleValues.CreatePin());
// Monitor storage for changes
@ -39,24 +38,15 @@ public class DataModelEventCycleNode : Node<DataModelPathEntity, DataModelEventC
{
Script = script;
if (Storage == null)
return;
UpdateDataModelPath();
if (Storage != null)
UpdateDataModelPath();
}
public override void Evaluate()
{
object? pathValue = _dataModelPath?.GetValue();
bool hasTriggered = pathValue is IDataModelEvent dataModelEvent ? EvaluateEvent(dataModelEvent) : EvaluateValue(pathValue);
if (hasTriggered)
{
_currentIndex++;
if (_currentIndex >= CycleValues.Count())
_currentIndex = 0;
}
if (pathValue is not IDataModelEvent && EvaluateValue(pathValue))
Cycle();
object? outputValue = CycleValues.ElementAt(_currentIndex).PinValue;
if (Output.Type.IsInstanceOfType(outputValue))
@ -65,15 +55,6 @@ public class DataModelEventCycleNode : Node<DataModelPathEntity, DataModelEventC
Output.Value = Output.Type.GetDefault()!;
}
private bool EvaluateEvent(IDataModelEvent dataModelEvent)
{
if (dataModelEvent.LastTrigger <= _lastTrigger)
return false;
_lastTrigger = dataModelEvent.LastTrigger;
return true;
}
private bool EvaluateValue(object? pathValue)
{
if (Equals(pathValue, _lastPathValue))
@ -83,51 +64,26 @@ public class DataModelEventCycleNode : Node<DataModelPathEntity, DataModelEventC
return true;
}
private void CycleValuesOnPinAdded(object? sender, SingleValueEventArgs<IPin> e)
private void Cycle()
{
e.Value.PinConnected += OnPinConnected;
e.Value.PinDisconnected += OnPinDisconnected;
}
_currentIndex++;
private void CycleValuesOnPinRemoved(object? sender, SingleValueEventArgs<IPin> e)
{
e.Value.PinConnected -= OnPinConnected;
e.Value.PinDisconnected -= OnPinDisconnected;
}
private void OnPinDisconnected(object? sender, SingleValueEventArgs<IPin> e)
{
ProcessPinDisconnected();
}
private void OnPinConnected(object? sender, SingleValueEventArgs<IPin> e)
{
ProcessPinConnected(e.Value);
}
private void ProcessPinConnected(IPin source)
{
if (_updating)
return;
try
{
_updating = true;
// No need to change anything if the types haven't changed
if (_currentType != source.Type)
ChangeCurrentType(source.Type);
}
finally
{
_updating = false;
}
if (_currentIndex >= CycleValues.Count())
_currentIndex = 0;
}
private void UpdateDataModelPath()
{
DataModelPath? old = _dataModelPath;
if (old?.GetValue() is IDataModelEvent oldEvent)
oldEvent.EventTriggered -= OnEventTriggered;
_dataModelPath = Storage != null ? new DataModelPath(Storage) : null;
if (_dataModelPath?.GetValue() is IDataModelEvent newEvent)
newEvent.EventTriggered += OnEventTriggered;
old?.Dispose();
}
@ -139,10 +95,28 @@ public class DataModelEventCycleNode : Node<DataModelPathEntity, DataModelEventC
_currentType = type;
}
private void ProcessPinDisconnected()
private void OnEventTriggered(object? sender, EventArgs e)
{
Cycle();
}
private void OnCycleValuesOnPinAdded(object? sender, SingleValueEventArgs<IPin> e)
{
e.Value.PinConnected += OnPinConnected;
e.Value.PinDisconnected += OnPinDisconnected;
}
private void OnCycleValuesOnPinRemoved(object? sender, SingleValueEventArgs<IPin> e)
{
e.Value.PinConnected -= OnPinConnected;
e.Value.PinDisconnected -= OnPinDisconnected;
}
private void OnPinDisconnected(object? sender, SingleValueEventArgs<IPin> e)
{
if (_updating)
return;
try
{
// If there's still a connected pin, stick to the current type
@ -157,9 +131,30 @@ public class DataModelEventCycleNode : Node<DataModelPathEntity, DataModelEventC
}
}
private void OnPinConnected(object? sender, SingleValueEventArgs<IPin> e)
{
if (_updating)
return;
try
{
_updating = true;
// No need to change anything if the types haven't changed
if (_currentType != e.Value.Type)
ChangeCurrentType(e.Value.Type);
}
finally
{
_updating = false;
}
}
/// <inheritdoc />
public void Dispose()
{
if (_dataModelPath?.GetValue() is IDataModelEvent newEvent)
newEvent.EventTriggered -= OnEventTriggered;
_dataModelPath?.Dispose();
}
}