1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00
Artemis/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionGroup.cs
Robert c07ea09c9d Core - Streamlined public parts of profile creation
UI - Started adjusting the VMs for the layer refactor
2020-09-10 19:56:39 +02:00

144 lines
4.9 KiB
C#

using System;
using System.Linq;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions;
namespace Artemis.Core
{
/// <summary>
/// A group containing zero to many <see cref="DisplayConditionPart" />s which it evaluates using a boolean specific
/// operator
/// </summary>
public class DisplayConditionGroup : DisplayConditionPart
{
private bool _disposed;
/// <summary>
/// Creates a new instance of the <see cref="DisplayConditionGroup" /> class
/// </summary>
/// <param name="parent"></param>
public DisplayConditionGroup(DisplayConditionPart parent)
{
Parent = parent;
Entity = new DisplayConditionGroupEntity();
}
/// <summary>
/// Creates a new instance of the <see cref="DisplayConditionGroup" /> class
/// </summary>
/// <param name="parent"></param>
/// <param name="entity"></param>
public DisplayConditionGroup(DisplayConditionPart parent, DisplayConditionGroupEntity entity)
{
Parent = parent;
Entity = entity;
BooleanOperator = (BooleanOperator) Entity.BooleanOperator;
foreach (var childEntity in Entity.Children)
{
if (childEntity is DisplayConditionGroupEntity groupEntity)
AddChild(new DisplayConditionGroup(this, groupEntity));
else if (childEntity is DisplayConditionListEntity listEntity)
AddChild(new DisplayConditionList(this, listEntity));
else if (childEntity is DisplayConditionPredicateEntity predicateEntity)
AddChild(new DisplayConditionPredicate(this, predicateEntity));
else if (childEntity is DisplayConditionListPredicateEntity listPredicateEntity)
AddChild(new DisplayConditionListPredicate(this, listPredicateEntity));
}
}
/// <summary>
/// Gets or sets the boolean operator of this group
/// </summary>
public BooleanOperator BooleanOperator { get; set; }
internal DisplayConditionGroupEntity Entity { get; set; }
/// <inheritdoc />
public override bool Evaluate()
{
if (_disposed)
throw new ObjectDisposedException("DisplayConditionGroup");
// Empty groups are always true
if (Children.Count == 0)
return true;
// Groups with only one child ignore the boolean operator
if (Children.Count == 1)
return Children[0].Evaluate();
switch (BooleanOperator)
{
case BooleanOperator.And:
return Children.All(c => c.Evaluate());
case BooleanOperator.Or:
return Children.Any(c => c.Evaluate());
case BooleanOperator.AndNot:
return Children.All(c => !c.Evaluate());
case BooleanOperator.OrNot:
return Children.Any(c => !c.Evaluate());
default:
throw new ArgumentOutOfRangeException();
}
}
/// <inheritdoc />
public override bool EvaluateObject(object target)
{
if (_disposed)
throw new ObjectDisposedException("DisplayConditionGroup");
// Empty groups are always true
if (Children.Count == 0)
return true;
// Groups with only one child ignore the boolean operator
if (Children.Count == 1)
return Children[0].EvaluateObject(target);
return BooleanOperator switch
{
BooleanOperator.And => Children.All(c => c.EvaluateObject(target)),
BooleanOperator.Or => Children.Any(c => c.EvaluateObject(target)),
BooleanOperator.AndNot => Children.All(c => !c.EvaluateObject(target)),
BooleanOperator.OrNot => Children.Any(c => !c.EvaluateObject(target)),
_ => throw new ArgumentOutOfRangeException()
};
}
internal override void Save()
{
Entity.BooleanOperator = (int) BooleanOperator;
Entity.Children.Clear();
Entity.Children.AddRange(Children.Select(c => c.GetEntity()));
foreach (var child in Children)
child.Save();
}
internal override DisplayConditionPartEntity GetEntity()
{
return Entity;
}
#region IDisposable
protected override void Dispose(bool disposing)
{
_disposed = true;
foreach (var child in Children)
child.Dispose();
base.Dispose(disposing);
}
#endregion
}
public enum BooleanOperator
{
And,
Or,
AndNot,
OrNot
}
}