mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Display conditions - Moved pridacte update logic from VM to model
This commit is contained in:
parent
f39e4d719c
commit
4dfc61ab7d
@ -10,12 +10,13 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
{
|
||||
Parent = parent;
|
||||
EntityId = Guid.NewGuid();
|
||||
DisplayConditionGroupEntity = new DisplayConditionGroupEntity();
|
||||
}
|
||||
|
||||
public DisplayConditionGroup(DisplayConditionPart parent, DisplayConditionGroupEntity entity)
|
||||
{
|
||||
DisplayConditionGroupEntity = entity;
|
||||
Parent = parent;
|
||||
DisplayConditionGroupEntity = entity;
|
||||
EntityId = DisplayConditionGroupEntity.Id;
|
||||
BooleanOperator = (BooleanOperator) DisplayConditionGroupEntity.BooleanOperator;
|
||||
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using Artemis.Core.Exceptions;
|
||||
using Artemis.Core.Extensions;
|
||||
using Artemis.Core.Models.Profile.Conditions.Abstract;
|
||||
using Artemis.Core.Plugins.Abstract.DataModels;
|
||||
using Artemis.Core.Services.Interfaces;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
|
||||
namespace Artemis.Core.Models.Profile.Conditions
|
||||
@ -13,12 +14,17 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
public DisplayConditionPredicate(DisplayConditionPart parent)
|
||||
{
|
||||
Parent = parent;
|
||||
DisplayConditionPredicateEntity = new DisplayConditionPredicateEntity();
|
||||
}
|
||||
|
||||
public DisplayConditionPredicate(DisplayConditionPart parent, DisplayConditionPredicateEntity entity)
|
||||
{
|
||||
Parent = parent;
|
||||
DisplayConditionPredicateEntity = entity;
|
||||
|
||||
// TODO: This has to be done from somewhere
|
||||
// LeftDataModel = dataModelService.GetPluginDataModelByGuid(DisplayConditionPredicateEntity.LeftDataModelGuid);
|
||||
// RightDataModel = dataModelService.GetPluginDataModelByGuid(DisplayConditionPredicateEntity.RightDataModelGuid);
|
||||
}
|
||||
|
||||
public DisplayConditionPredicateEntity DisplayConditionPredicateEntity { get; set; }
|
||||
@ -26,51 +32,122 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
public PredicateType PredicateType { get; set; }
|
||||
public DisplayConditionOperator Operator { get; set; }
|
||||
|
||||
public Guid LeftDataModelGuid { get; set; }
|
||||
public string LeftPropertyPath { get; set; }
|
||||
|
||||
public Guid RightDataModelGuid { get; set; }
|
||||
public string RightPropertyPath { get; set; }
|
||||
|
||||
// TODO: Implement type-checking or perhaps convert it here
|
||||
public object RightStaticValue { get; set; }
|
||||
public DataModel LeftDataModel { get; private set; }
|
||||
public string LeftPropertyPath { get; private set; }
|
||||
public DataModel RightDataModel { get; private set; }
|
||||
public string RightPropertyPath { get; private set; }
|
||||
public object RightStaticValue { get; private set; }
|
||||
|
||||
public Expression<Func<DataModel, DataModel, bool>> DynamicConditionLambda { get; private set; }
|
||||
public Func<DataModel, DataModel, bool> CompiledDynamicConditionLambda { get; private set; }
|
||||
public Expression<Func<DataModel, bool>> StaticConditionLambda { get; private set; }
|
||||
public Func<DataModel, bool> CompiledStaticConditionLambda { get; private set; }
|
||||
|
||||
public void CreateExpression(IDataModelService dataModelService)
|
||||
public void UpdateLeftSide(DataModel dataModel, string path)
|
||||
{
|
||||
if (PredicateType == PredicateType.Dynamic)
|
||||
CreateDynamicExpression(dataModelService);
|
||||
else
|
||||
CreateStaticExpression(dataModelService);
|
||||
if (!dataModel.ContainsPath(path))
|
||||
throw new ArtemisCoreException($"Data model of type {dataModel.GetType().Name} does not contain a property at path '{path}'");
|
||||
|
||||
LeftDataModel = dataModel;
|
||||
LeftPropertyPath = path;
|
||||
|
||||
ValidateRightSide();
|
||||
CreateExpression();
|
||||
}
|
||||
|
||||
private void CreateDynamicExpression(IDataModelService dataModelService)
|
||||
public void UpdateRightSide(DataModel dataModel, string path)
|
||||
{
|
||||
if (LeftDataModelGuid == Guid.Empty || string.IsNullOrWhiteSpace(LeftPropertyPath))
|
||||
return;
|
||||
if (RightDataModelGuid == Guid.Empty || string.IsNullOrWhiteSpace(RightPropertyPath))
|
||||
return;
|
||||
if (!dataModel.ContainsPath(path))
|
||||
throw new ArtemisCoreException($"Data model of type {dataModel.GetType().Name} does not contain a property at path '{path}'");
|
||||
|
||||
var leftDataModel = dataModelService.GetPluginDataModelByGuid(LeftDataModelGuid);
|
||||
if (leftDataModel == null)
|
||||
return;
|
||||
PredicateType = PredicateType.Dynamic;
|
||||
RightDataModel = dataModel;
|
||||
RightPropertyPath = path;
|
||||
|
||||
var rightDataModel = dataModelService.GetPluginDataModelByGuid(RightDataModelGuid);
|
||||
if (rightDataModel == null)
|
||||
CreateExpression();
|
||||
}
|
||||
|
||||
public void UpdateRightSide(object staticValue)
|
||||
{
|
||||
PredicateType = PredicateType.Static;
|
||||
RightDataModel = null;
|
||||
RightPropertyPath = null;
|
||||
|
||||
SetStaticValue(staticValue);
|
||||
CreateExpression();
|
||||
}
|
||||
|
||||
public void CreateExpression()
|
||||
{
|
||||
if (PredicateType == PredicateType.Dynamic)
|
||||
CreateDynamicExpression();
|
||||
else
|
||||
CreateStaticExpression();
|
||||
}
|
||||
|
||||
public override void ApplyToEntity()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the right side, ensuring it is still compatible with the current left side
|
||||
/// </summary>
|
||||
private void ValidateRightSide()
|
||||
{
|
||||
var leftSideType = LeftDataModel.GetTypeAtPath(LeftPropertyPath);
|
||||
if (PredicateType == PredicateType.Dynamic)
|
||||
{
|
||||
var rightSideType = RightDataModel.GetTypeAtPath(RightPropertyPath);
|
||||
if (!leftSideType.IsCastableFrom(rightSideType))
|
||||
UpdateRightSide(null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just update the value with itself, it'll validate :)
|
||||
UpdateRightSide(RightStaticValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the current static value, ensuring it is a valid type. This assumes the types are compatible if they
|
||||
/// differ.
|
||||
/// </summary>
|
||||
private void SetStaticValue(object staticValue)
|
||||
{
|
||||
// If the left side is empty simply apply the value, any validation will wait
|
||||
if (LeftDataModel == null)
|
||||
{
|
||||
RightStaticValue = staticValue;
|
||||
return;
|
||||
}
|
||||
|
||||
var leftSideType = LeftDataModel.GetTypeAtPath(LeftPropertyPath);
|
||||
|
||||
// If not null ensure the types match and if not, convert it
|
||||
if (staticValue != null && staticValue.GetType() == leftSideType)
|
||||
RightStaticValue = staticValue;
|
||||
else if (staticValue != null)
|
||||
RightStaticValue = Convert.ChangeType(staticValue, leftSideType);
|
||||
// If null create a default instance for value types or simply make it null for reference types
|
||||
else if (leftSideType.IsValueType)
|
||||
RightStaticValue = Activator.CreateInstance(leftSideType);
|
||||
else
|
||||
RightStaticValue = null;
|
||||
}
|
||||
|
||||
private void CreateDynamicExpression()
|
||||
{
|
||||
if (LeftDataModel == null || RightDataModel == null)
|
||||
return;
|
||||
|
||||
var leftSideParameter = Expression.Parameter(typeof(DataModel), "leftDataModel");
|
||||
var leftSideAccessor = LeftPropertyPath.Split('.').Aggregate<string, Expression>(
|
||||
Expression.Convert(leftSideParameter, leftDataModel.GetType()), // Cast to the appropriate type
|
||||
Expression.Convert(leftSideParameter, LeftDataModel.GetType()), // Cast to the appropriate type
|
||||
Expression.Property
|
||||
);
|
||||
var rightSideParameter = Expression.Parameter(typeof(DataModel), "rightDataModel");
|
||||
var rightSideAccessor = RightPropertyPath.Split('.').Aggregate<string, Expression>(
|
||||
Expression.Convert(rightSideParameter, rightDataModel.GetType()), // Cast to the appropriate type
|
||||
Expression.Convert(rightSideParameter, LeftDataModel.GetType()), // Cast to the appropriate type
|
||||
Expression.Property
|
||||
);
|
||||
|
||||
@ -85,18 +162,14 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
CompiledDynamicConditionLambda = DynamicConditionLambda.Compile();
|
||||
}
|
||||
|
||||
private void CreateStaticExpression(IDataModelService dataModelService)
|
||||
private void CreateStaticExpression()
|
||||
{
|
||||
if (LeftDataModelGuid == Guid.Empty || string.IsNullOrWhiteSpace(LeftPropertyPath))
|
||||
return;
|
||||
|
||||
var leftDataModel = dataModelService.GetPluginDataModelByGuid(LeftDataModelGuid);
|
||||
if (leftDataModel == null)
|
||||
if (LeftDataModel == null)
|
||||
return;
|
||||
|
||||
var leftSideParameter = Expression.Parameter(typeof(DataModel), "leftDataModel");
|
||||
var leftSideAccessor = LeftPropertyPath.Split('.').Aggregate<string, Expression>(
|
||||
Expression.Convert(leftSideParameter, leftDataModel.GetType()), // Cast to the appropriate type
|
||||
Expression.Convert(leftSideParameter, LeftDataModel.GetType()), // Cast to the appropriate type
|
||||
Expression.Property
|
||||
);
|
||||
|
||||
@ -110,11 +183,6 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
StaticConditionLambda = Expression.Lambda<Func<DataModel, bool>>(conditionExpression, leftSideParameter);
|
||||
CompiledStaticConditionLambda = StaticConditionLambda.Compile();
|
||||
}
|
||||
|
||||
public override void ApplyToEntity()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public enum PredicateType
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
|
||||
using System;
|
||||
using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
|
||||
using Artemis.Core.Plugins.Models;
|
||||
|
||||
namespace Artemis.Core.Plugins.Abstract.DataModels
|
||||
@ -16,5 +17,39 @@ namespace Artemis.Core.Plugins.Abstract.DataModels
|
||||
/// </summary>
|
||||
[DataModelIgnore]
|
||||
public DataModelPropertyAttribute DataModelDescription { get; internal set; }
|
||||
|
||||
public bool ContainsPath(string path)
|
||||
{
|
||||
var parts = path.Split('.');
|
||||
var current = GetType();
|
||||
foreach (var part in parts)
|
||||
{
|
||||
var property = current?.GetProperty(part);
|
||||
current = property?.PropertyType;
|
||||
if (property == null)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Type GetTypeAtPath(string path)
|
||||
{
|
||||
if (!ContainsPath(path))
|
||||
return null;
|
||||
|
||||
var parts = path.Split('.');
|
||||
var current = GetType();
|
||||
|
||||
Type result = null;
|
||||
foreach (var part in parts)
|
||||
{
|
||||
var property = current.GetProperty(part);
|
||||
current = property.PropertyType;
|
||||
result = property.PropertyType;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Artemis.Core.Extensions;
|
||||
using Artemis.Core.Models.Profile.Conditions;
|
||||
using Artemis.Core.Plugins.Abstract.DataModels;
|
||||
using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
|
||||
using Artemis.UI.Shared.Exceptions;
|
||||
@ -113,6 +114,11 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
IsMatchingFilteredTypes = filteredTypes.Any(t => t == PropertyInfo.PropertyType);
|
||||
}
|
||||
|
||||
public DataModelVisualizationViewModel GetChildForCondition(DisplayConditionPredicate predicate)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public DataModelVisualizationViewModel GetChildByPath(Guid dataModelGuid, string propertyPath)
|
||||
{
|
||||
var path = propertyPath.Split(".");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user