mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Data model events - WIP commit
This commit is contained in:
parent
b8112601df
commit
03b0e83ed8
@ -20,13 +20,23 @@ namespace Artemis.Core
|
|||||||
// TODO: Can we avoid boxing/unboxing?
|
// TODO: Can we avoid boxing/unboxing?
|
||||||
TLeftSide leftSide;
|
TLeftSide leftSide;
|
||||||
if (leftSideValue != null)
|
if (leftSideValue != null)
|
||||||
|
{
|
||||||
|
if (leftSideValue.GetType() != typeof(TLeftSide))
|
||||||
leftSide = (TLeftSide) Convert.ChangeType(leftSideValue, typeof(TLeftSide));
|
leftSide = (TLeftSide) Convert.ChangeType(leftSideValue, typeof(TLeftSide));
|
||||||
|
else
|
||||||
|
leftSide = (TLeftSide) leftSideValue;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
leftSide = default;
|
leftSide = default;
|
||||||
|
|
||||||
TRightSide rightSide;
|
TRightSide rightSide;
|
||||||
if (rightSideValue != null)
|
if (rightSideValue != null)
|
||||||
|
{
|
||||||
|
if (rightSideValue.GetType() != typeof(TRightSide))
|
||||||
rightSide = (TRightSide) Convert.ChangeType(rightSideValue, typeof(TRightSide));
|
rightSide = (TRightSide) Convert.ChangeType(rightSideValue, typeof(TRightSide));
|
||||||
|
else
|
||||||
|
rightSide = (TRightSide) rightSideValue;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
rightSide = default;
|
rightSide = default;
|
||||||
|
|
||||||
@ -57,7 +67,12 @@ namespace Artemis.Core
|
|||||||
// TODO: Can we avoid boxing/unboxing?
|
// TODO: Can we avoid boxing/unboxing?
|
||||||
TLeftSide leftSide;
|
TLeftSide leftSide;
|
||||||
if (leftSideValue != null)
|
if (leftSideValue != null)
|
||||||
leftSide = (TLeftSide) Convert.ChangeType(leftSideValue, typeof(TLeftSide));
|
{
|
||||||
|
if (leftSideValue.GetType() != typeof(TLeftSide))
|
||||||
|
leftSide = (TLeftSide)Convert.ChangeType(leftSideValue, typeof(TLeftSide));
|
||||||
|
else
|
||||||
|
leftSide = (TLeftSide)leftSideValue;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
leftSide = default;
|
leftSide = default;
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,189 @@
|
|||||||
|
using System;
|
||||||
|
using Artemis.Storage.Entities.Profile.Abstract;
|
||||||
|
using Artemis.Storage.Entities.Profile.Conditions;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A condition that evaluates to true when an event is triggered
|
||||||
|
/// </summary>
|
||||||
|
public class DataModelConditionEvent : DataModelConditionPart
|
||||||
|
{
|
||||||
|
private bool _disposed;
|
||||||
|
private bool _reinitializing;
|
||||||
|
private IDataModelEvent? _event;
|
||||||
|
private bool _eventTriggered;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="DataModelConditionEvent" /> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent"></param>
|
||||||
|
public DataModelConditionEvent(DataModelConditionPart parent)
|
||||||
|
{
|
||||||
|
Parent = parent;
|
||||||
|
Entity = new DataModelConditionEventEntity();
|
||||||
|
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal DataModelConditionEvent(DataModelConditionPart parent, DataModelConditionEventEntity entity)
|
||||||
|
{
|
||||||
|
Parent = parent;
|
||||||
|
Entity = entity;
|
||||||
|
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the path of the event property
|
||||||
|
/// </summary>
|
||||||
|
public DataModelPath? EventPath { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
|
internal DataModelConditionEventEntity Entity { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool Evaluate()
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
throw new ObjectDisposedException("DataModelConditionEvent");
|
||||||
|
|
||||||
|
// Ensure the event has not been replaced
|
||||||
|
if (EventPath?.GetValue() is IDataModelEvent dataModelEvent && _event != dataModelEvent)
|
||||||
|
SubscribeToDataModelEvent(dataModelEvent);
|
||||||
|
|
||||||
|
// Only evaluate to true once every time the event has been triggered
|
||||||
|
if (!_eventTriggered)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_eventTriggered = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubscribeToDataModelEvent(IDataModelEvent dataModelEvent)
|
||||||
|
{
|
||||||
|
if (_event != null)
|
||||||
|
_event.EventTriggered -= OnEventTriggered;
|
||||||
|
|
||||||
|
_event = dataModelEvent;
|
||||||
|
if (_event != null)
|
||||||
|
_event.EventTriggered += OnEventTriggered;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the event the condition is triggered by
|
||||||
|
/// </summary>
|
||||||
|
public void UpdateEvent(DataModelPath? path)
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
throw new ObjectDisposedException("DataModelConditionEvent");
|
||||||
|
|
||||||
|
if (path != null && !path.IsValid)
|
||||||
|
throw new ArtemisCoreException("Cannot update event to an invalid path");
|
||||||
|
|
||||||
|
EventPath?.Dispose();
|
||||||
|
EventPath = path != null ? new DataModelPath(path) : null;
|
||||||
|
SubscribeToEventPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
_disposed = true;
|
||||||
|
|
||||||
|
EventPath?.Dispose();
|
||||||
|
|
||||||
|
foreach (DataModelConditionPart child in Children)
|
||||||
|
child.Dispose();
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
internal override bool EvaluateObject(object target)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override void Save()
|
||||||
|
{
|
||||||
|
// Don't save an invalid state
|
||||||
|
if (EventPath != null && !EventPath.IsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Target list
|
||||||
|
EventPath?.Save();
|
||||||
|
Entity.EventPath = EventPath?.Entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override DataModelConditionPartEntity GetEntity()
|
||||||
|
{
|
||||||
|
return Entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Initialize()
|
||||||
|
{
|
||||||
|
if (Entity.EventPath == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Ensure the list path is valid and points to a list
|
||||||
|
DataModelPath eventPath = new DataModelPath(null, Entity.EventPath);
|
||||||
|
// Can't check this on an invalid list, if it becomes valid later lets hope for the best
|
||||||
|
if (eventPath.IsValid && !PointsToEvent(eventPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
EventPath = eventPath;
|
||||||
|
SubscribeToEventPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool PointsToEvent(DataModelPath dataModelPath)
|
||||||
|
{
|
||||||
|
Type? type = dataModelPath.GetPropertyType();
|
||||||
|
if (type == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return typeof(IDataModelEvent).IsAssignableFrom(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubscribeToEventPath()
|
||||||
|
{
|
||||||
|
if (EventPath == null) return;
|
||||||
|
EventPath.PathValidated += EventPathOnPathValidated;
|
||||||
|
EventPath.PathInvalidated += EventPathOnPathInvalidated;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Event handlers
|
||||||
|
|
||||||
|
private void OnEventTriggered(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
_eventTriggered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EventPathOnPathValidated(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (_reinitializing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_reinitializing = true;
|
||||||
|
EventPath?.Dispose();
|
||||||
|
Initialize();
|
||||||
|
_reinitializing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EventPathOnPathInvalidated(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (_reinitializing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_reinitializing = true;
|
||||||
|
EventPath?.Dispose();
|
||||||
|
Initialize();
|
||||||
|
_reinitializing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -180,7 +180,7 @@ namespace Artemis.Core
|
|||||||
DataModelPath listPath = new DataModelPath(null, Entity.ListPath);
|
DataModelPath listPath = new DataModelPath(null, Entity.ListPath);
|
||||||
Type listType = listPath.GetPropertyType()!;
|
Type listType = listPath.GetPropertyType()!;
|
||||||
// Can't check this on an invalid list, if it becomes valid later lets hope for the best
|
// Can't check this on an invalid list, if it becomes valid later lets hope for the best
|
||||||
if (listPath.IsValid && !listPath.PointsToList)
|
if (listPath.IsValid && !PointsToList(listPath))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ListPath = listPath;
|
ListPath = listPath;
|
||||||
@ -208,6 +208,12 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool PointsToList(DataModelPath dataModelPath)
|
||||||
|
{
|
||||||
|
Type? type = dataModelPath.GetPropertyType();
|
||||||
|
return type?.IsGenericEnumerable() ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
private void SubscribeToListPath()
|
private void SubscribeToListPath()
|
||||||
{
|
{
|
||||||
if (ListPath == null) return;
|
if (ListPath == null) return;
|
||||||
|
|||||||
85
src/Artemis.Core/Models/Profile/DataModel/DataModelEvent.cs
Normal file
85
src/Artemis.Core/Models/Profile/DataModel/DataModelEvent.cs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
using System;
|
||||||
|
using Artemis.Core.DataModelExpansions;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a data model event with event arguments of type <typeparamref name="T" />
|
||||||
|
/// </summary>
|
||||||
|
public class DataModelEvent<T> : IDataModelEvent where T : DataModelEventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Trigger the event with the given <paramref name="eventArgs" />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs">The event argument to pass to the event</param>
|
||||||
|
public void Trigger(T eventArgs)
|
||||||
|
{
|
||||||
|
if (eventArgs == null) throw new ArgumentNullException(nameof(eventArgs));
|
||||||
|
eventArgs.TriggerTime = DateTime.Now;
|
||||||
|
|
||||||
|
LastEventArguments = eventArgs;
|
||||||
|
LastTrigger = DateTime.Now;
|
||||||
|
TriggerCount++;
|
||||||
|
|
||||||
|
OnEventTriggered();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal virtual void OnEventTriggered()
|
||||||
|
{
|
||||||
|
EventTriggered?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DateTime LastTrigger { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public int TriggerCount { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the event arguments of the last time the event was triggered
|
||||||
|
/// </summary>
|
||||||
|
public T? LastEventArguments { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[DataModelIgnore]
|
||||||
|
public Type ArgumentsType => typeof(T);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public event EventHandler? EventTriggered;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a data model event without event arguments
|
||||||
|
/// </summary>
|
||||||
|
public class DataModelEvent : IDataModelEvent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Trigger the event
|
||||||
|
/// </summary>
|
||||||
|
public void Trigger()
|
||||||
|
{
|
||||||
|
LastTrigger = DateTime.Now;
|
||||||
|
TriggerCount++;
|
||||||
|
|
||||||
|
OnEventTriggered();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal virtual void OnEventTriggered()
|
||||||
|
{
|
||||||
|
EventTriggered?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DateTime LastTrigger { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public int TriggerCount { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[DataModelIgnore]
|
||||||
|
public Type? ArgumentsType => null;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public event EventHandler? EventTriggered;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the base class for data model events that contain event data
|
||||||
|
/// </summary>
|
||||||
|
public class DataModelEventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time at which the event with these arguments was triggered
|
||||||
|
/// </summary>
|
||||||
|
public DateTime TriggerTime { get; internal set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -111,18 +111,6 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyCollection<DataModelPathSegment> Segments => _segments.ToList().AsReadOnly();
|
public IReadOnlyCollection<DataModelPathSegment> Segments => _segments.ToList().AsReadOnly();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a boolean indicating whether this data model path points to a list
|
|
||||||
/// </summary>
|
|
||||||
public bool PointsToList
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
Type? type = GetPropertyType();
|
|
||||||
return type?.IsGenericEnumerable() ?? false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal DataModelPathEntity Entity { get; }
|
internal DataModelPathEntity Entity { get; }
|
||||||
|
|
||||||
internal Func<object, object>? Accessor { get; private set; }
|
internal Func<object, object>? Accessor { get; private set; }
|
||||||
|
|||||||
27
src/Artemis.Core/Models/Profile/DataModel/IDataModelEvent.cs
Normal file
27
src/Artemis.Core/Models/Profile/DataModel/IDataModelEvent.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
internal interface IDataModelEvent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the last time the event was triggered
|
||||||
|
/// </summary>
|
||||||
|
DateTime LastTrigger { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of times the event was triggered
|
||||||
|
/// </summary>
|
||||||
|
int TriggerCount { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type of arguments this event contains
|
||||||
|
/// </summary>
|
||||||
|
Type? ArgumentsType { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires when the event is triggered
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler EventTriggered;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
using Artemis.Storage.Entities.Profile.Abstract;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Entities.Profile.Conditions
|
||||||
|
{
|
||||||
|
public class DataModelConditionEventEntity : DataModelConditionPartEntity
|
||||||
|
{
|
||||||
|
public DataModelConditionEventEntity()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataModelPathEntity EventPath { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.Storage.Entities.Profile.Abstract;
|
using Artemis.Storage.Entities.Profile.Abstract;
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.Profile.Conditions
|
namespace Artemis.Storage.Entities.Profile.Conditions
|
||||||
|
|||||||
@ -1,2 +1,14 @@
|
|||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=behaviors/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=controls/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=converters/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=datamodelvisualization/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=datamodelvisualization_005Cshared/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=dependencyproperties/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=events/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=exceptions/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=propertyinput/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdatamodelvisualization/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdialog/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cinterfaces/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=utilities/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=utilities/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.Core.DataModelExpansions;
|
||||||
|
using Artemis.UI.Shared.Services;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Shared
|
||||||
|
{
|
||||||
|
public class DataModelEventViewModel : DataModelVisualizationViewModel
|
||||||
|
{
|
||||||
|
internal DataModelEventViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, DataModelPath dataModelPath) : base(dataModel, parent, dataModelPath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(IDataModelUIService dataModelUIService)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object GetCurrentValue()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return DisplayPath ?? Path;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override int GetChildDepth()
|
||||||
|
{
|
||||||
|
return PropertyDescription != null && !PropertyDescription.ResetsDepth ? Depth + 1 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,8 +7,8 @@ namespace Artemis.UI.Shared
|
|||||||
{
|
{
|
||||||
public class DataModelPropertiesViewModel : DataModelVisualizationViewModel
|
public class DataModelPropertiesViewModel : DataModelVisualizationViewModel
|
||||||
{
|
{
|
||||||
private Type _displayValueType;
|
|
||||||
private object _displayValue;
|
private object _displayValue;
|
||||||
|
private Type _displayValueType;
|
||||||
|
|
||||||
internal DataModelPropertiesViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, DataModelPath dataModelPath) : base(dataModel, parent, dataModelPath)
|
internal DataModelPropertiesViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, DataModelPath dataModelPath) : base(dataModel, parent, dataModelPath)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -137,7 +136,8 @@ namespace Artemis.UI.Shared
|
|||||||
if (looseMatch)
|
if (looseMatch)
|
||||||
IsMatchingFilteredTypes = filteredTypes.Any(t => t.IsCastableFrom(type) ||
|
IsMatchingFilteredTypes = filteredTypes.Any(t => t.IsCastableFrom(type) ||
|
||||||
t == typeof(Enum) && type.IsEnum ||
|
t == typeof(Enum) && type.IsEnum ||
|
||||||
t == typeof(IEnumerable<>) && type.IsGenericEnumerable());
|
t == typeof(IEnumerable<>) && type.IsGenericEnumerable() ||
|
||||||
|
type.IsGenericType && t == type.GetGenericTypeDefinition());
|
||||||
else
|
else
|
||||||
IsMatchingFilteredTypes = filteredTypes.Any(t => t == type || t == typeof(Enum) && type.IsEnum);
|
IsMatchingFilteredTypes = filteredTypes.Any(t => t == type || t == typeof(Enum) && type.IsEnum);
|
||||||
}
|
}
|
||||||
@ -219,7 +219,6 @@ namespace Artemis.UI.Shared
|
|||||||
// Add missing dynamic children
|
// Add missing dynamic children
|
||||||
object value = Parent == null || Parent.IsRootViewModel ? DataModel : DataModelPath.GetValue();
|
object value = Parent == null || Parent.IsRootViewModel ? DataModel : DataModelPath.GetValue();
|
||||||
if (value is DataModel dataModel)
|
if (value is DataModel dataModel)
|
||||||
{
|
|
||||||
foreach (KeyValuePair<string, DataModel> kvp in dataModel.DynamicDataModels)
|
foreach (KeyValuePair<string, DataModel> kvp in dataModel.DynamicDataModels)
|
||||||
{
|
{
|
||||||
string childPath = AppendToPath(kvp.Key);
|
string childPath = AppendToPath(kvp.Key);
|
||||||
@ -230,7 +229,6 @@ namespace Artemis.UI.Shared
|
|||||||
if (child != null)
|
if (child != null)
|
||||||
Children.Add(child);
|
Children.Add(child);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Remove dynamic children that have been removed from the data model
|
// Remove dynamic children that have been removed from the data model
|
||||||
List<DataModelVisualizationViewModel> toRemoveDynamic = Children.Where(c => !c.DataModelPath.IsValid).ToList();
|
List<DataModelVisualizationViewModel> toRemoveDynamic = Children.Where(c => !c.DataModelPath.IsValid).ToList();
|
||||||
@ -266,6 +264,8 @@ namespace Artemis.UI.Shared
|
|||||||
return new DataModelPropertyViewModel(DataModel, this, dataModelPath) {Depth = depth};
|
return new DataModelPropertyViewModel(DataModel, this, dataModelPath) {Depth = depth};
|
||||||
if (propertyType.IsGenericEnumerable())
|
if (propertyType.IsGenericEnumerable())
|
||||||
return new DataModelListViewModel(DataModel, this, dataModelPath) {Depth = depth};
|
return new DataModelListViewModel(DataModel, this, dataModelPath) {Depth = depth};
|
||||||
|
if (propertyType == typeof(DataModelEvent) || propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(DataModelEvent<>))
|
||||||
|
return new DataModelEventViewModel(DataModel, this, dataModelPath) { Depth = depth };
|
||||||
// For other value types create a child view model
|
// For other value types create a child view model
|
||||||
if (propertyType.IsClass || propertyType.IsStruct())
|
if (propertyType.IsClass || propertyType.IsStruct())
|
||||||
return new DataModelPropertiesViewModel(DataModel, this, dataModelPath) {Depth = depth};
|
return new DataModelPropertiesViewModel(DataModel, this, dataModelPath) {Depth = depth};
|
||||||
|
|||||||
@ -39,6 +39,12 @@
|
|||||||
<TextBlock Text="{Binding PropertyDescription.Name}" ToolTip="{Binding PropertyDescription.Description}" ToolTipService.ShowOnDisabled="True" VerticalAlignment="Center" />
|
<TextBlock Text="{Binding PropertyDescription.Name}" ToolTip="{Binding PropertyDescription.Description}" ToolTipService.ShowOnDisabled="True" VerticalAlignment="Center" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
<DataTemplate DataType="{x:Type dataModel:DataModelEventViewModel}">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<materialDesign:PackIcon Kind="LightningBolt" VerticalAlignment="Center" Margin="0 0 5 0" />
|
||||||
|
<TextBlock Text="{Binding PropertyDescription.Name}" ToolTip="Trigger layer on event" ToolTipService.ShowOnDisabled="True" VerticalAlignment="Center" />
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
<DataTemplate DataType="{x:Type dataModel:DataModelPropertyViewModel}">
|
<DataTemplate DataType="{x:Type dataModel:DataModelPropertyViewModel}">
|
||||||
<Grid>
|
<Grid>
|
||||||
<!-- Value description -->
|
<!-- Value description -->
|
||||||
@ -73,6 +79,12 @@
|
|||||||
<TextBlock Text="{Binding PropertyDescription.Name}" ToolTip="{Binding PropertyDescription.Description}" ToolTipService.ShowOnDisabled="True" VerticalAlignment="Center"/>
|
<TextBlock Text="{Binding PropertyDescription.Name}" ToolTip="{Binding PropertyDescription.Description}" ToolTipService.ShowOnDisabled="True" VerticalAlignment="Center"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
<DataTemplate DataType="{x:Type dataModel:DataModelEventViewModel}">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<materialDesign:PackIcon Kind="LightningBolt" VerticalAlignment="Center" Margin="0 0 5 0" />
|
||||||
|
<TextBlock Text="{Binding PropertyDescription.Name}" ToolTip="{Binding PropertyDescription.Description}" ToolTipService.ShowOnDisabled="True" VerticalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
<DataTemplate DataType="{x:Type dataModel:DataModelPropertyViewModel}">
|
<DataTemplate DataType="{x:Type dataModel:DataModelPropertyViewModel}">
|
||||||
<Grid ToolTip="{Binding PropertyDescription.Description}">
|
<Grid ToolTip="{Binding PropertyDescription.Description}">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
|||||||
@ -0,0 +1,93 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.UI.Ninject.Factories;
|
||||||
|
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
using Artemis.UI.Shared.Input;
|
||||||
|
using Artemis.UI.Shared.Services;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||||
|
{
|
||||||
|
public class DataModelConditionEventViewModel : DataModelConditionViewModel, IDisposable
|
||||||
|
{
|
||||||
|
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
||||||
|
private readonly IDataModelUIService _dataModelUIService;
|
||||||
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
|
private DataModelDynamicViewModel _targetSelectionViewModel;
|
||||||
|
|
||||||
|
public DataModelConditionEventViewModel(DataModelConditionEvent model,
|
||||||
|
IProfileEditorService profileEditorService,
|
||||||
|
IDataModelUIService dataModelUIService,
|
||||||
|
IDataModelConditionsVmFactory dataModelConditionsVmFactory) : base(model)
|
||||||
|
{
|
||||||
|
_profileEditorService = profileEditorService;
|
||||||
|
_dataModelUIService = dataModelUIService;
|
||||||
|
_dataModelConditionsVmFactory = dataModelConditionsVmFactory;
|
||||||
|
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataModelConditionEvent DataModelConditionEvent => (DataModelConditionEvent) Model;
|
||||||
|
|
||||||
|
public DataModelDynamicViewModel TargetSelectionViewModel
|
||||||
|
{
|
||||||
|
get => _targetSelectionViewModel;
|
||||||
|
set => SetAndNotify(ref _targetSelectionViewModel, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
TargetSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
|
||||||
|
TargetSelectionViewModel.PropertySelected += TargetSelectionViewModelOnPropertySelected;
|
||||||
|
|
||||||
|
IReadOnlyCollection<DataModelVisualizationRegistration> editors = _dataModelUIService.RegisteredDataModelEditors;
|
||||||
|
List<Type> supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
|
||||||
|
supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
|
||||||
|
supportedInputTypes.Add(typeof(IEnumerable<>));
|
||||||
|
TargetSelectionViewModel.FilterTypes = supportedInputTypes.ToArray();
|
||||||
|
|
||||||
|
TargetSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(188, 174, 71));
|
||||||
|
TargetSelectionViewModel.Placeholder = "Select a list";
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyEvent()
|
||||||
|
{
|
||||||
|
if (!TargetSelectionViewModel.DataModelPath.GetPropertyType().IsGenericEnumerable())
|
||||||
|
{
|
||||||
|
if (Parent is DataModelConditionGroupViewModel groupViewModel)
|
||||||
|
groupViewModel.ConvertToPredicate(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataModelConditionEvent.UpdateEvent(TargetSelectionViewModel.DataModelPath);
|
||||||
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Event handlers
|
||||||
|
|
||||||
|
private void TargetSelectionViewModelOnPropertySelected(object? sender, DataModelInputDynamicEventArgs e)
|
||||||
|
{
|
||||||
|
ApplyEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
TargetSelectionViewModel.Dispose();
|
||||||
|
TargetSelectionViewModel.PropertySelected -= TargetSelectionViewModelOnPropertySelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -147,6 +147,24 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
|||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ConvertToConditionEvent(DataModelConditionPredicateViewModel predicateViewModel)
|
||||||
|
{
|
||||||
|
// Remove the old child
|
||||||
|
DataModelConditionGroup.RemoveChild(predicateViewModel.Model);
|
||||||
|
|
||||||
|
DataModelConditionPart rootGroup = DataModelConditionGroup;
|
||||||
|
while (rootGroup.Parent != null)
|
||||||
|
rootGroup = rootGroup.Parent;
|
||||||
|
|
||||||
|
// Insert an event at the start of the root group
|
||||||
|
DataModelConditionEvent conditionEvent = new DataModelConditionEvent(rootGroup);
|
||||||
|
conditionEvent.UpdateEvent(predicateViewModel.LeftSideSelectionViewModel.DataModelPath);
|
||||||
|
rootGroup.AddChild(conditionEvent, 0);
|
||||||
|
|
||||||
|
// Update to switch the VMs
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
public void ConvertToPredicate(DataModelConditionListViewModel listViewModel)
|
public void ConvertToPredicate(DataModelConditionListViewModel listViewModel)
|
||||||
{
|
{
|
||||||
// Store the old index and remove the old predicate
|
// Store the old index and remove the old predicate
|
||||||
|
|||||||
@ -97,6 +97,8 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
|||||||
_supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
|
_supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
|
||||||
_supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
|
_supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
|
||||||
_supportedInputTypes.Add(typeof(IEnumerable<>));
|
_supportedInputTypes.Add(typeof(IEnumerable<>));
|
||||||
|
_supportedInputTypes.Add(typeof(DataModelEvent));
|
||||||
|
_supportedInputTypes.Add(typeof(DataModelEvent<>));
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +280,6 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
|||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void RightSideInputViewModelOnSwitchToDynamicRequested(object? sender, EventArgs e)
|
private void RightSideInputViewModelOnSwitchToDynamicRequested(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
DataModelConditionPredicate.PredicateType = ProfileRightSideType.Dynamic;
|
DataModelConditionPredicate.PredicateType = ProfileRightSideType.Dynamic;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Artemis.Core;
|
||||||
using Artemis.Core.DataModelExpansions;
|
using Artemis.Core.DataModelExpansions;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
@ -34,6 +35,22 @@ namespace Artemis.Plugins.DataModelExpansions.TestData.DataModels
|
|||||||
public bool IsWinning { get; set; }
|
public bool IsWinning { get; set; }
|
||||||
|
|
||||||
public List<SomeListItem> ListItems { get; set; }
|
public List<SomeListItem> ListItems { get; set; }
|
||||||
|
|
||||||
|
[DataModelProperty(Description = "Event without arguments")]
|
||||||
|
public DataModelEvent Event1 { get; set; } = new DataModelEvent();
|
||||||
|
|
||||||
|
[DataModelProperty(Description = "Event with arguments")]
|
||||||
|
public DataModelEvent<TestEventArgs> Event2 { get; set; } = new DataModelEvent<TestEventArgs>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestEventArgs : DataModelEventArgs
|
||||||
|
{
|
||||||
|
public TestEventArgs(string someValue)
|
||||||
|
{
|
||||||
|
SomeValue = someValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string SomeValue { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Test<T>
|
public class Test<T>
|
||||||
|
|||||||
@ -23,6 +23,8 @@ namespace Artemis.Plugins.DataModelExpansions.TestData
|
|||||||
{
|
{
|
||||||
// You can access your data model here and update it however you like
|
// You can access your data model here and update it however you like
|
||||||
DataModel.TemplateDataModelString = $"The last delta time was {deltaTime} seconds";
|
DataModel.TemplateDataModelString = $"The last delta time was {deltaTime} seconds";
|
||||||
|
|
||||||
|
// DataModel.Event1.Trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TimedUpdate(double deltaTime)
|
private void TimedUpdate(double deltaTime)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user