1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00
Robert 9c117d2773 Nodes - Added gradient nodes
Nodes - Added color gradient pin type
Data bindings - Changed color gradient data bindings to now take a color gradient
2022-09-23 21:41:08 +02:00

164 lines
4.9 KiB
C#

using Artemis.Core;
using Artemis.Storage.Entities.Profile;
using Artemis.VisualScripting.Nodes.DataModel.Screens;
namespace Artemis.VisualScripting.Nodes.DataModel;
[Node("Data Model-Event", "Outputs the latest values of a data model event.", "Data Model", OutputType = typeof(object))]
public class DataModelEventNode : Node<DataModelPathEntity, DataModelEventNodeCustomViewModel>, IDisposable
{
private readonly ObjectOutputPins _objectOutputPins;
private IDataModelEvent? _dataModelEvent;
private DataModelPath? _dataModelPath;
private DateTime _lastTrigger;
private object? _lastValue;
private OutputPin? _newValuePin;
private OutputPin? _oldValuePin;
private int _valueChangeCount;
public DataModelEventNode() : base("Data Model-Event", "Outputs the latest values of a data model event.")
{
_objectOutputPins = new ObjectOutputPins(this);
TimeSinceLastTrigger = CreateOutputPin<Numeric>("Time since trigger");
TriggerCount = CreateOutputPin<Numeric>("Trigger count");
// Monitor storage for changes
StorageModified += (_, _) => UpdateDataModelPath();
}
public INodeScript? Script { get; set; }
public OutputPin<Numeric> TimeSinceLastTrigger { get; }
public OutputPin<Numeric> TriggerCount { get; }
public override void Initialize(INodeScript script)
{
Script = script;
if (Storage == null)
return;
UpdateDataModelPath();
}
public override void Evaluate()
{
object? pathValue = _dataModelPath?.GetValue();
// If the path is a data model event, evaluate the event
if (pathValue is IDataModelEvent dataModelEvent)
{
TimeSinceLastTrigger.Value = dataModelEvent.TimeSinceLastTrigger.TotalMilliseconds;
TriggerCount.Value = dataModelEvent.TriggerCount;
_objectOutputPins.SetCurrentValue(dataModelEvent.LastEventArgumentsUntyped);
}
// If the path is a regular value, evaluate the current value
else if (_oldValuePin != null && _newValuePin != null)
{
if (_newValuePin.IsNumeric)
pathValue = new Numeric(pathValue);
if (Equals(_lastValue, pathValue))
{
TimeSinceLastTrigger.Value = (DateTime.Now - _lastTrigger).TotalMilliseconds;
return;
}
_valueChangeCount++;
_lastTrigger = DateTime.Now;
_oldValuePin.Value = _lastValue;
_newValuePin.Value = pathValue;
_lastValue = pathValue;
TimeSinceLastTrigger.Value = 0;
TriggerCount.Value = _valueChangeCount;
}
}
private void UpdateDataModelPath()
{
DataModelPath? old = _dataModelPath;
_dataModelPath = Storage != null ? new DataModelPath(Storage) : null;
if (_dataModelPath != null)
_dataModelPath.PathValidated += DataModelPathOnPathValidated;
if (old != null)
{
old.PathValidated -= DataModelPathOnPathValidated;
old.Dispose();
}
UpdateOutputPins();
}
private void UpdateOutputPins()
{
object? pathValue = _dataModelPath?.GetValue();
if (pathValue is IDataModelEvent dataModelEvent)
CreateEventPins(dataModelEvent);
else
CreateValuePins();
}
private void CreateEventPins(IDataModelEvent dataModelEvent)
{
if (_dataModelEvent == dataModelEvent)
return;
ClearPins();
_dataModelEvent = dataModelEvent;
_objectOutputPins.ChangeType(dataModelEvent.ArgumentsType);
}
private void CreateValuePins()
{
ClearPins();
Type? propertyType = _dataModelPath?.GetPropertyType();
if (propertyType == null)
return;
if (Numeric.IsTypeCompatible(propertyType))
propertyType = typeof(Numeric);
_oldValuePin = CreateOrAddOutputPin(propertyType, "Old value");
_newValuePin = CreateOrAddOutputPin(propertyType, "New value");
_lastValue = null;
_valueChangeCount = 0;
}
private void ClearPins()
{
// Clear the output pins by changing the type to null
_objectOutputPins.ChangeType(null);
if (_oldValuePin != null)
{
RemovePin(_oldValuePin);
_oldValuePin = null;
}
if (_newValuePin != null)
{
RemovePin(_newValuePin);
_newValuePin = null;
}
}
private void DataModelPathOnPathValidated(object? sender, EventArgs e)
{
// Update the output pin now that the type is known and attempt to restore the connection that was likely missing
UpdateOutputPins();
Script?.LoadConnections();
}
/// <inheritdoc />
public void Dispose()
{
_dataModelPath?.Dispose();
}
}