1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Merge remote-tracking branch 'origin/feature/events' into feature/events

This commit is contained in:
Robert 2020-10-28 22:09:06 +01:00
commit df2f364cbe
7 changed files with 57 additions and 85 deletions

View File

@ -1,4 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using Artemis.Storage.Entities.Profile.Abstract; using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions; using Artemis.Storage.Entities.Profile.Conditions;
@ -82,16 +84,26 @@ namespace Artemis.Core
if (Children.Count == 1) if (Children.Count == 1)
return Children[0].Evaluate(); return Children[0].Evaluate();
if (ContainsEvents)
{
bool eventTriggered = Children.Where(c => c is DataModelConditionEvent).Any(c => c.Evaluate());
return eventTriggered && EvaluateWithOperator(Children.Where(c => !(c is DataModelConditionEvent)));
}
return EvaluateWithOperator(Children);
}
private bool EvaluateWithOperator(IEnumerable<DataModelConditionPart> targets)
{
switch (BooleanOperator) switch (BooleanOperator)
{ {
case BooleanOperator.And: case BooleanOperator.And:
return Children.All(c => c.Evaluate()); return targets.All(c => c.Evaluate());
case BooleanOperator.Or: case BooleanOperator.Or:
return Children.Any(c => c.Evaluate()); return targets.Any(c => c.Evaluate());
case BooleanOperator.AndNot: case BooleanOperator.AndNot:
return Children.All(c => !c.Evaluate()); return targets.All(c => !c.Evaluate());
case BooleanOperator.OrNot: case BooleanOperator.OrNot:
return Children.Any(c => !c.Evaluate()); return targets.Any(c => !c.Evaluate());
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }

View File

@ -97,9 +97,6 @@ namespace Artemis.Core
TimeLine = TimelineLength; TimeLine = TimelineLength;
ExtraTimeLines.Clear(); ExtraTimeLines.Clear();
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
baseLayerEffect.BaseProperties?.Reset();
foreach (ProfileElement child in Children) foreach (ProfileElement child in Children)
child.Reset(); child.Reset();
} }
@ -234,7 +231,7 @@ namespace Artemis.Core
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled)) foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
{ {
baseLayerEffect.BaseProperties?.Update(renderDelta); baseLayerEffect.BaseProperties?.Update(timeLine, renderDelta);
baseLayerEffect.Update(renderDelta); baseLayerEffect.Update(renderDelta);
} }

View File

@ -182,13 +182,6 @@ namespace Artemis.Core
DisplayConditionMet = false; DisplayConditionMet = false;
TimeLine = TimelineLength; TimeLine = TimelineLength;
ExtraTimeLines.Clear(); ExtraTimeLines.Clear();
General.Reset();
Transform.Reset();
LayerBrush.BaseProperties?.Reset();
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
baseLayerEffect.BaseProperties?.Reset();
} }
#region Storage #region Storage
@ -265,7 +258,7 @@ namespace Artemis.Core
#endregion #endregion
#region Rendering #region Rendering
private TimeSpan _lastRenderTime; private TimeSpan _lastRenderTime;
/// <inheritdoc /> /// <inheritdoc />
@ -288,7 +281,7 @@ namespace Artemis.Core
{ {
TimelineLength = StartSegmentLength + MainSegmentLength + EndSegmentLength; TimelineLength = StartSegmentLength + MainSegmentLength + EndSegmentLength;
} }
/// <inheritdoc /> /// <inheritdoc />
public override void Render(SKCanvas canvas, SKImageInfo canvasInfo) public override void Render(SKCanvas canvas, SKImageInfo canvasInfo)
{ {
@ -306,43 +299,43 @@ namespace Artemis.Core
return; return;
RenderLayer(TimeLine, canvas); RenderLayer(TimeLine, canvas);
foreach (TimeSpan extraTimeLine in ExtraTimeLines) foreach (TimeSpan extraTimeLine in ExtraTimeLines)
RenderLayer(extraTimeLine, canvas); RenderLayer(extraTimeLine, canvas);
} }
private void PrepareForRender(TimeSpan timeLine) private void PrepareForRender(TimeSpan renderTime)
{ {
double renderDelta = (timeLine - _lastRenderTime).TotalSeconds; double renderDelta = (renderTime - _lastRenderTime).TotalSeconds;
General.Update(renderDelta); General.Update(renderTime, renderDelta);
Transform.Update(renderDelta); Transform.Update(renderTime, renderDelta);
LayerBrush.BaseProperties?.Update(renderDelta); LayerBrush.BaseProperties?.Update(renderTime, renderDelta);
LayerBrush.Update(renderDelta); LayerBrush.Update(renderDelta);
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled)) foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
{ {
baseLayerEffect.BaseProperties?.Update(renderDelta); baseLayerEffect.BaseProperties?.Update(renderTime, renderDelta);
baseLayerEffect.Update(renderDelta); baseLayerEffect.Update(renderDelta);
} }
_lastRenderTime = timeLine; _lastRenderTime = renderTime;
} }
private void RenderLayer(TimeSpan timeLine, SKCanvas canvas) private void RenderLayer(TimeSpan timeLine, SKCanvas canvas)
{ {
if (timeLine > TimelineLength || timeLine == TimeSpan.Zero && !DisplayConditionMet) if (timeLine > TimelineLength)
return; return;
PrepareForRender(timeLine); PrepareForRender(timeLine);
if (_layerBitmap == null) if (_layerBitmap == null)
{ {
_layerBitmap = new SKBitmap(new SKImageInfo((int)Path.Bounds.Width, (int)Path.Bounds.Height)); _layerBitmap = new SKBitmap(new SKImageInfo((int) Path.Bounds.Width, (int) Path.Bounds.Height));
} }
else if (_layerBitmap.Info.Width != (int)Path.Bounds.Width || _layerBitmap.Info.Height != (int)Path.Bounds.Height) else if (_layerBitmap.Info.Width != (int) Path.Bounds.Width || _layerBitmap.Info.Height != (int) Path.Bounds.Height)
{ {
_layerBitmap.Dispose(); _layerBitmap.Dispose();
_layerBitmap = new SKBitmap(new SKImageInfo((int)Path.Bounds.Width, (int)Path.Bounds.Height)); _layerBitmap = new SKBitmap(new SKImageInfo((int) Path.Bounds.Width, (int) Path.Bounds.Height));
} }
using SKPath layerPath = new SKPath(Path); using SKPath layerPath = new SKPath(Path);
@ -350,7 +343,7 @@ namespace Artemis.Core
using SKPaint layerPaint = new SKPaint using SKPaint layerPaint = new SKPaint
{ {
FilterQuality = SKFilterQuality.Low, FilterQuality = SKFilterQuality.Low,
Color = new SKColor(0, 0, 0, (byte)(Transform.Opacity.CurrentValue * 2.55f)) Color = new SKColor(0, 0, 0, (byte) (Transform.Opacity.CurrentValue * 2.55f))
}; };
layerCanvas.Clear(); layerCanvas.Clear();
@ -370,7 +363,7 @@ namespace Artemis.Core
else if (General.ResizeMode.CurrentValue == LayerResizeMode.Clip) else if (General.ResizeMode.CurrentValue == LayerResizeMode.Clip)
ClipRender(layerCanvas, _layerBitmap.Info, layerPaint, layerPath); ClipRender(layerCanvas, _layerBitmap.Info, layerPaint, layerPath);
using SKPaint canvasPaint = new SKPaint { BlendMode = General.BlendMode.CurrentValue }; using SKPaint canvasPaint = new SKPaint {BlendMode = General.BlendMode.CurrentValue};
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled)) foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
baseLayerEffect.PostProcess(layerCanvas, _layerBitmap.Info, layerPath, canvasPaint); baseLayerEffect.PostProcess(layerCanvas, _layerBitmap.Info, layerPath, canvasPaint);

View File

@ -11,7 +11,7 @@ namespace Artemis.Core
/// initialize these for you. /// initialize these for you.
/// </para> /// </para>
/// </summary> /// </summary>
public interface ILayerProperty : IStorageModel, IUpdateModel, IDisposable public interface ILayerProperty : IStorageModel, IDisposable
{ {
/// <summary> /// <summary>
/// Gets the description attribute applied to this property /// Gets the description attribute applied to this property
@ -38,8 +38,10 @@ namespace Artemis.Core
List<IDataBindingRegistration> GetAllDataBindingRegistrations(); List<IDataBindingRegistration> GetAllDataBindingRegistrations();
/// <summary> /// <summary>
/// Resets the internal state of the property /// Updates the layer properties internal state
/// </summary> /// </summary>
void Reset(); /// <param name="renderTime">The current position in the timeline</param>
/// <param name="deltaTime">The position difference since last update</param>
void Update(TimeSpan renderTime, double deltaTime);
} }
} }

View File

@ -19,7 +19,6 @@ namespace Artemis.Core
public class LayerProperty<T> : ILayerProperty public class LayerProperty<T> : ILayerProperty
{ {
private bool _disposed; private bool _disposed;
private TimeSpan _keyframeProgress;
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="LayerProperty{T}" /> class /// Creates a new instance of the <see cref="LayerProperty{T}" /> class
@ -38,16 +37,15 @@ namespace Artemis.Core
/// <summary> /// <summary>
/// Updates the property, applying keyframes and data bindings to the current value /// Updates the property, applying keyframes and data bindings to the current value
/// </summary> /// </summary>
public void Update(double deltaTime) public void Update(TimeSpan time, double deltaTime)
{ {
if (_disposed) if (_disposed)
throw new ObjectDisposedException("LayerProperty"); throw new ObjectDisposedException("LayerProperty");
CurrentValue = BaseValue; CurrentValue = BaseValue;
_keyframeProgress = _keyframeProgress.Add(TimeSpan.FromSeconds(deltaTime));
if (ProfileElement.ApplyKeyframesEnabled) if (ProfileElement.ApplyKeyframesEnabled)
UpdateKeyframes(deltaTime); UpdateKeyframes(time);
if (ProfileElement.ApplyDataBindingsEnabled) if (ProfileElement.ApplyDataBindingsEnabled)
UpdateDataBindings(deltaTime); UpdateDataBindings(deltaTime);
@ -127,7 +125,7 @@ namespace Artemis.Core
return; return;
_baseValue = value; _baseValue = value;
Update(0); Update(ProfileElement.TimeLine, 0);
OnCurrentValueSet(); OnCurrentValueSet();
} }
} }
@ -171,7 +169,7 @@ namespace Artemis.Core
// Force an update so that the base value is applied to the current value and // Force an update so that the base value is applied to the current value and
// keyframes/data bindings are applied using the new base value // keyframes/data bindings are applied using the new base value
Update(0); Update(ProfileElement.TimeLine, 0);
OnCurrentValueSet(); OnCurrentValueSet();
} }
@ -296,13 +294,13 @@ namespace Artemis.Core
_keyframes = _keyframes.OrderBy(k => k.Position).ToList(); _keyframes = _keyframes.OrderBy(k => k.Position).ToList();
} }
private void UpdateKeyframes(double deltaTime) private void UpdateKeyframes(TimeSpan time)
{ {
if (!KeyframesSupported || !KeyframesEnabled) if (!KeyframesSupported || !KeyframesEnabled)
return; return;
// The current keyframe is the last keyframe before the current time // The current keyframe is the last keyframe before the current time
CurrentKeyframe = _keyframes.LastOrDefault(k => k.Position <= _keyframeProgress); CurrentKeyframe = _keyframes.LastOrDefault(k => k.Position <= time);
// Keyframes are sorted by position so we can safely assume the next keyframe's position is after the current // Keyframes are sorted by position so we can safely assume the next keyframe's position is after the current
int nextIndex = _keyframes.IndexOf(CurrentKeyframe) + 1; int nextIndex = _keyframes.IndexOf(CurrentKeyframe) + 1;
NextKeyframe = _keyframes.Count > nextIndex ? _keyframes[nextIndex] : null; NextKeyframe = _keyframes.Count > nextIndex ? _keyframes[nextIndex] : null;
@ -316,7 +314,7 @@ namespace Artemis.Core
else else
{ {
TimeSpan timeDiff = NextKeyframe.Position - CurrentKeyframe.Position; TimeSpan timeDiff = NextKeyframe.Position - CurrentKeyframe.Position;
float keyframeProgress = (float) ((_keyframeProgress - CurrentKeyframe.Position).TotalMilliseconds / timeDiff.TotalMilliseconds); float keyframeProgress = (float) ((time - CurrentKeyframe.Position).TotalMilliseconds / timeDiff.TotalMilliseconds);
float keyframeProgressEased = (float) Easings.Interpolate(keyframeProgress, CurrentKeyframe.EasingFunction); float keyframeProgressEased = (float) Easings.Interpolate(keyframeProgress, CurrentKeyframe.EasingFunction);
UpdateCurrentValue(keyframeProgress, keyframeProgressEased); UpdateCurrentValue(keyframeProgress, keyframeProgressEased);
} }
@ -363,13 +361,7 @@ namespace Artemis.Core
{ {
return _dataBindingRegistrations; return _dataBindingRegistrations;
} }
/// <inheritdoc />
public void Reset()
{
_keyframeProgress = TimeSpan.Zero;
}
public void RegisterDataBindingProperty<TProperty>(Expression<Func<T, TProperty>> propertyExpression, DataBindingConverter<T, TProperty> converter) public void RegisterDataBindingProperty<TProperty>(Expression<Func<T, TProperty>> propertyExpression, DataBindingConverter<T, TProperty> converter)
{ {
if (_disposed) if (_disposed)
@ -460,7 +452,6 @@ namespace Artemis.Core
Entity = entity ?? throw new ArgumentNullException(nameof(entity)); Entity = entity ?? throw new ArgumentNullException(nameof(entity));
PropertyDescription = description ?? throw new ArgumentNullException(nameof(description)); PropertyDescription = description ?? throw new ArgumentNullException(nameof(description));
IsLoadedFromStorage = fromStorage; IsLoadedFromStorage = fromStorage;
LayerPropertyGroup.PropertyGroupUpdating += (sender, args) => Update(args.DeltaTime);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@ -198,11 +198,12 @@ namespace Artemis.Core
layerPropertyGroup.ApplyToEntity(); layerPropertyGroup.ApplyToEntity();
} }
internal void Update(double deltaTime) internal void Update(TimeSpan renderTime, double deltaTime)
{ {
// Since at this point we don't know what properties the group has without using reflection, foreach (ILayerProperty layerProperty in LayerProperties)
// let properties subscribe to the update event and update themselves layerProperty.Update(renderTime, deltaTime);
OnPropertyGroupUpdating(new LayerPropertyGroupUpdatingEventArgs(deltaTime)); foreach (LayerPropertyGroup layerPropertyGroup in LayerPropertyGroups)
layerPropertyGroup.Update(renderTime, deltaTime);
} }
private void InitializeProperty(PropertyInfo propertyInfo, PropertyDescriptionAttribute propertyDescription) private void InitializeProperty(PropertyInfo propertyInfo, PropertyDescriptionAttribute propertyDescription)
@ -266,8 +267,6 @@ namespace Artemis.Core
#region Events #region Events
internal event EventHandler<LayerPropertyGroupUpdatingEventArgs> PropertyGroupUpdating;
/// <summary> /// <summary>
/// Occurs when the property group has initialized all its children /// Occurs when the property group has initialized all its children
/// </summary> /// </summary>
@ -284,11 +283,6 @@ namespace Artemis.Core
/// </summary> /// </summary>
public event EventHandler VisibilityChanged; public event EventHandler VisibilityChanged;
internal virtual void OnPropertyGroupUpdating(LayerPropertyGroupUpdatingEventArgs e)
{
PropertyGroupUpdating?.Invoke(this, e);
}
internal virtual void OnVisibilityChanged() internal virtual void OnVisibilityChanged()
{ {
VisibilityChanged?.Invoke(this, EventArgs.Empty); VisibilityChanged?.Invoke(this, EventArgs.Empty);
@ -300,16 +294,5 @@ namespace Artemis.Core
} }
#endregion #endregion
/// <summary>
/// Resets the internal state of the property group
/// </summary>
public void Reset()
{
foreach (ILayerProperty layerProperty in LayerProperties)
layerProperty.Reset();
foreach (LayerPropertyGroup layerPropertyGroup in LayerPropertyGroups)
layerPropertyGroup.Reset();
}
} }
} }

View File

@ -22,7 +22,6 @@ namespace Artemis.UI.Shared.Services
private readonly object _selectedProfileLock = new object(); private readonly object _selectedProfileLock = new object();
private TimeSpan _currentTime; private TimeSpan _currentTime;
private int _pixelsPerSecond; private int _pixelsPerSecond;
private bool _previewInvalidated;
public ProfileEditorService(IProfileService profileService, IKernel kernel, ILogger logger, ICoreService coreService) public ProfileEditorService(IProfileService profileService, IKernel kernel, ILogger logger, ICoreService coreService)
{ {
@ -31,19 +30,14 @@ namespace Artemis.UI.Shared.Services
_coreService = coreService; _coreService = coreService;
_registeredPropertyEditors = new List<PropertyInputRegistration>(); _registeredPropertyEditors = new List<PropertyInputRegistration>();
_coreService.FrameRendered += CoreServiceOnFrameRendered;
Kernel = kernel; Kernel = kernel;
PixelsPerSecond = 100; PixelsPerSecond = 100;
} }
private void CoreServiceOnFrameRendered(object? sender, FrameRenderedEventArgs e) private void CoreServiceOnFrameRendered(object? sender, FrameRenderedEventArgs e)
{ {
if (_previewInvalidated) _coreService.FrameRendered -= CoreServiceOnFrameRendered;
{ Execute.PostToUIThread(OnProfilePreviewUpdated);
_previewInvalidated = false;
Execute.PostToUIThread(OnProfilePreviewUpdated);
}
} }
public IKernel Kernel { get; } public IKernel Kernel { get; }
@ -160,7 +154,7 @@ namespace Artemis.UI.Shared.Services
foreach (Layer layer in SelectedProfile.GetAllLayers()) foreach (Layer layer in SelectedProfile.GetAllLayers())
layer.OverrideTimeLines(CurrentTime, layer != SelectedProfileElement); layer.OverrideTimeLines(CurrentTime, layer != SelectedProfileElement);
_previewInvalidated = true; _coreService.FrameRendered += CoreServiceOnFrameRendered;
} }
public bool UndoUpdateProfile() public bool UndoUpdateProfile()