Profiles - Split conditions into different types

Profile configurations - Added broken state (not yet shown in UI)
This commit is contained in:
Robert committed 2021-09-14 22:17:31 +02:00
1 parent 8ac1431a2f
commit d657e7844e
18 files changed
+694 -375

No files matched your search

@@ -1,4 +1,6 @@
using System;
using System.Linq;
using Artemis.Core.Internal;
using Artemis.Storage.Entities.Profile.Conditions;
namespace Artemis.Core
@@ -8,7 +10,7 @@ namespace Artemis.Core
private readonly string _displayName;
private readonly object? _context;
private DateTime _lastProcessedTrigger;
private DataModelPath _eventPath;
private DataModelPath? _eventPath;
internal EventCondition(string displayName, object? context)
{
@@ -17,6 +19,7 @@ namespace Artemis.Core
Entity = new EventConditionEntity();
Script = new NodeScript<bool>($"Activate {displayName}", $"Whether or not the event should activate the {displayName}", context);
UpdateEventNode();
}
internal EventCondition(EventConditionEntity entity, string displayName, object? context)
@@ -38,7 +41,7 @@ namespace Artemis.Core
/// <summary>
/// Gets or sets the path to the event that drives this event condition
/// </summary>
public DataModelPath EventPath
public DataModelPath? EventPath
{
set => SetAndNotify(ref _eventPath, value);
get => _eventPath;
@@ -48,7 +51,7 @@ namespace Artemis.Core
internal bool Evaluate()
{
if (EventPath.GetValue() is not DataModelEvent dataModelEvent || dataModelEvent.LastTrigger <= _lastProcessedTrigger)
if (EventPath?.GetValue() is not IDataModelEvent dataModelEvent || dataModelEvent.LastTrigger <= _lastProcessedTrigger)
return false;
// TODO: Place dataModelEvent.LastEventArgumentsUntyped; in the start node
@@ -65,7 +68,7 @@ namespace Artemis.Core
public void Dispose()
{
Script.Dispose();
EventPath.Dispose();
EventPath?.Dispose();
}
#endregion
@@ -73,6 +76,25 @@ namespace Artemis.Core
internal void LoadNodeScript()
{
Script.Load();
UpdateEventNode();
}
/// <summary>
/// Updates the event node, applying the selected event
/// </summary>
public void UpdateEventNode()
{
if (EventPath?.GetValue() is not IDataModelEvent dataModelEvent)
return;
if (Script.Nodes.FirstOrDefault(n => n is EventStartNode) is EventStartNode existing)
existing.UpdateDataModelEvent(dataModelEvent);
else
{
EventStartNode node = new();
node.UpdateDataModelEvent(dataModelEvent);
Script.AddNode(node);
}
}
#region Implementation of IStorageModel
@@ -82,13 +104,14 @@ namespace Artemis.Core
{
EventPath = new DataModelPath(null, Entity.EventPath);
Script = new NodeScript<bool>($"Activate {_displayName}", $"Whether or not the event should activate the {_displayName}", Entity.Script, _context);
UpdateEventNode();
}
/// <inheritdoc />
public void Save()
{
EventPath.Save();
Entity.EventPath = EventPath.Entity;
EventPath?.Save();
Entity.EventPath = EventPath?.Entity;
Script.Save();
Entity.Script = Script.Entity;
}
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions;
@@ -18,7 +19,7 @@ namespace Artemis.Core
_eventsList = new List<EventCondition>();
ProfileElement = profileElement;
Events = new List<EventCondition>(_eventsList);
Events = new ReadOnlyCollection<EventCondition>(_eventsList);
}
internal EventsCondition(EventsConditionEntity entity, ProfileElement profileElement)
@@ -27,7 +28,7 @@ namespace Artemis.Core
_eventsList = new List<EventCondition>();
ProfileElement = profileElement;
Events = new List<EventCondition>(_eventsList);
Events = new ReadOnlyCollection<EventCondition>(_eventsList);
Load();
}
@@ -9,7 +9,7 @@ namespace Artemis.Core
/// <summary>
/// Represents the configuration of a profile, contained in a <see cref="ProfileCategory" />
/// </summary>
public class ProfileConfiguration : CorePropertyChanged, IStorageModel, IDisposable
public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable
{
private ProfileCategory _category;
private bool _disposed;
@@ -277,6 +277,13 @@ namespace Artemis.Core
}
#endregion
#region Overrides of BreakableModel
/// <inheritdoc />
public override string BrokenDisplayName => "Profile Configuration";
#endregion
}
/// <summary>
@@ -221,8 +221,8 @@ namespace Artemis.Core.Services
try
{
// Make sure the profile is active or inactive according to the parameters above
if (shouldBeActive && profileConfiguration.Profile == null)
ActivateProfile(profileConfiguration);
if (shouldBeActive && profileConfiguration.Profile == null && profileConfiguration.BrokenState != "Failed to activate profile")
profileConfiguration.TryOrBreak(() => ActivateProfile(profileConfiguration), "Failed to activate profile");
else if (!shouldBeActive && profileConfiguration.Profile != null)
DeactivateProfile(profileConfiguration);
@@ -597,9 +597,9 @@ namespace Artemis.Core.Services
profile.Save();
foreach (RenderProfileElement renderProfileElement in profile.GetAllRenderElements())
foreach (RenderProfileElement renderProfileElement in profile.GetAllRenderElements())
renderProfileElement.Save();
_logger.Debug("Adapt profile - Saving " + profile);
profile.RedoStack.Clear();
profile.UndoStack.Push(memento);
@@ -10,6 +10,7 @@ namespace Artemis.Core
string Name { get; }
string Description { get; }
bool IsExitNode { get; }
bool IsDefaultNode { get; }
public double X { get; set; }
public double Y { get; set; }
@@ -0,0 +1,49 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Humanizer;
namespace Artemis.Core.Internal
{
internal class EventStartNode : Node
{
private IDataModelEvent? _dataModelEvent;
private readonly Dictionary<PropertyInfo, OutputPin> _propertyPins;
public EventStartNode() : base("Event Arguments", "Contains the event arguments that triggered the evaluation")
{
_propertyPins = new Dictionary<PropertyInfo, OutputPin>();
}
public void UpdateDataModelEvent(IDataModelEvent dataModelEvent)
{
if (_dataModelEvent == dataModelEvent)
return;
foreach (var (_, outputPin) in _propertyPins)
RemovePin(outputPin);
_propertyPins.Clear();
_dataModelEvent = dataModelEvent;
foreach (PropertyInfo propertyInfo in dataModelEvent.ArgumentsType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
_propertyPins.Add(propertyInfo, CreateOutputPin(propertyInfo.PropertyType, propertyInfo.Name.Humanize()));
}
#region Overrides of Node
/// <inheritdoc />
public override void Evaluate()
{
if (_dataModelEvent?.LastEventArgumentsUntyped == null)
return;
foreach (var (propertyInfo, outputPin) in _propertyPins)
{
if (outputPin.ConnectedTo.Any())
outputPin.Value = propertyInfo.GetValue(_dataModelEvent.LastEventArgumentsUntyped) ?? outputPin.Type.GetDefault()!;
}
}
#endregion
}
}
+2
View File
@@ -25,6 +25,7 @@ namespace Artemis.Core
}
private double _x;
public double X
{
get => _x;
@@ -46,6 +47,7 @@ namespace Artemis.Core
}
public virtual bool IsExitNode => false;
public virtual bool IsDefaultNode => false;
private readonly List<IPin> _pins = new();
public IReadOnlyCollection<IPin> Pins => new ReadOnlyCollection<IPin>(_pins);