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:
commit
df2f364cbe
@ -1,4 +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;
|
||||
@ -82,16 +84,26 @@ namespace Artemis.Core
|
||||
if (Children.Count == 1)
|
||||
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)
|
||||
{
|
||||
case BooleanOperator.And:
|
||||
return Children.All(c => c.Evaluate());
|
||||
return targets.All(c => c.Evaluate());
|
||||
case BooleanOperator.Or:
|
||||
return Children.Any(c => c.Evaluate());
|
||||
return targets.Any(c => c.Evaluate());
|
||||
case BooleanOperator.AndNot:
|
||||
return Children.All(c => !c.Evaluate());
|
||||
return targets.All(c => !c.Evaluate());
|
||||
case BooleanOperator.OrNot:
|
||||
return Children.Any(c => !c.Evaluate());
|
||||
return targets.Any(c => !c.Evaluate());
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
@ -97,9 +97,6 @@ namespace Artemis.Core
|
||||
TimeLine = TimelineLength;
|
||||
ExtraTimeLines.Clear();
|
||||
|
||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
||||
baseLayerEffect.BaseProperties?.Reset();
|
||||
|
||||
foreach (ProfileElement child in Children)
|
||||
child.Reset();
|
||||
}
|
||||
@ -234,7 +231,7 @@ namespace Artemis.Core
|
||||
|
||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
||||
{
|
||||
baseLayerEffect.BaseProperties?.Update(renderDelta);
|
||||
baseLayerEffect.BaseProperties?.Update(timeLine, renderDelta);
|
||||
baseLayerEffect.Update(renderDelta);
|
||||
}
|
||||
|
||||
|
||||
@ -182,13 +182,6 @@ namespace Artemis.Core
|
||||
DisplayConditionMet = false;
|
||||
TimeLine = TimelineLength;
|
||||
ExtraTimeLines.Clear();
|
||||
|
||||
General.Reset();
|
||||
Transform.Reset();
|
||||
LayerBrush.BaseProperties?.Reset();
|
||||
|
||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
||||
baseLayerEffect.BaseProperties?.Reset();
|
||||
}
|
||||
|
||||
#region Storage
|
||||
@ -310,39 +303,39 @@ namespace Artemis.Core
|
||||
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);
|
||||
Transform.Update(renderDelta);
|
||||
LayerBrush.BaseProperties?.Update(renderDelta);
|
||||
General.Update(renderTime, renderDelta);
|
||||
Transform.Update(renderTime, renderDelta);
|
||||
LayerBrush.BaseProperties?.Update(renderTime, renderDelta);
|
||||
LayerBrush.Update(renderDelta);
|
||||
|
||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
||||
{
|
||||
baseLayerEffect.BaseProperties?.Update(renderDelta);
|
||||
baseLayerEffect.BaseProperties?.Update(renderTime, renderDelta);
|
||||
baseLayerEffect.Update(renderDelta);
|
||||
}
|
||||
|
||||
_lastRenderTime = timeLine;
|
||||
_lastRenderTime = renderTime;
|
||||
}
|
||||
|
||||
private void RenderLayer(TimeSpan timeLine, SKCanvas canvas)
|
||||
{
|
||||
if (timeLine > TimelineLength || timeLine == TimeSpan.Zero && !DisplayConditionMet)
|
||||
if (timeLine > TimelineLength)
|
||||
return;
|
||||
|
||||
PrepareForRender(timeLine);
|
||||
|
||||
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 = 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);
|
||||
@ -350,7 +343,7 @@ namespace Artemis.Core
|
||||
using SKPaint layerPaint = new SKPaint
|
||||
{
|
||||
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();
|
||||
|
||||
@ -370,7 +363,7 @@ namespace Artemis.Core
|
||||
else if (General.ResizeMode.CurrentValue == LayerResizeMode.Clip)
|
||||
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))
|
||||
baseLayerEffect.PostProcess(layerCanvas, _layerBitmap.Info, layerPath, canvasPaint);
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ namespace Artemis.Core
|
||||
/// initialize these for you.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public interface ILayerProperty : IStorageModel, IUpdateModel, IDisposable
|
||||
public interface ILayerProperty : IStorageModel, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the description attribute applied to this property
|
||||
@ -38,8 +38,10 @@ namespace Artemis.Core
|
||||
List<IDataBindingRegistration> GetAllDataBindingRegistrations();
|
||||
|
||||
/// <summary>
|
||||
/// Resets the internal state of the property
|
||||
/// Updates the layer properties internal state
|
||||
/// </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);
|
||||
}
|
||||
}
|
||||
@ -19,7 +19,6 @@ namespace Artemis.Core
|
||||
public class LayerProperty<T> : ILayerProperty
|
||||
{
|
||||
private bool _disposed;
|
||||
private TimeSpan _keyframeProgress;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="LayerProperty{T}" /> class
|
||||
@ -38,16 +37,15 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Updates the property, applying keyframes and data bindings to the current value
|
||||
/// </summary>
|
||||
public void Update(double deltaTime)
|
||||
public void Update(TimeSpan time, double deltaTime)
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("LayerProperty");
|
||||
|
||||
CurrentValue = BaseValue;
|
||||
_keyframeProgress = _keyframeProgress.Add(TimeSpan.FromSeconds(deltaTime));
|
||||
|
||||
if (ProfileElement.ApplyKeyframesEnabled)
|
||||
UpdateKeyframes(deltaTime);
|
||||
UpdateKeyframes(time);
|
||||
if (ProfileElement.ApplyDataBindingsEnabled)
|
||||
UpdateDataBindings(deltaTime);
|
||||
|
||||
@ -127,7 +125,7 @@ namespace Artemis.Core
|
||||
return;
|
||||
|
||||
_baseValue = value;
|
||||
Update(0);
|
||||
Update(ProfileElement.TimeLine, 0);
|
||||
OnCurrentValueSet();
|
||||
}
|
||||
}
|
||||
@ -171,7 +169,7 @@ namespace Artemis.Core
|
||||
|
||||
// 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
|
||||
Update(0);
|
||||
Update(ProfileElement.TimeLine, 0);
|
||||
OnCurrentValueSet();
|
||||
}
|
||||
|
||||
@ -296,13 +294,13 @@ namespace Artemis.Core
|
||||
_keyframes = _keyframes.OrderBy(k => k.Position).ToList();
|
||||
}
|
||||
|
||||
private void UpdateKeyframes(double deltaTime)
|
||||
private void UpdateKeyframes(TimeSpan time)
|
||||
{
|
||||
if (!KeyframesSupported || !KeyframesEnabled)
|
||||
return;
|
||||
|
||||
// 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
|
||||
int nextIndex = _keyframes.IndexOf(CurrentKeyframe) + 1;
|
||||
NextKeyframe = _keyframes.Count > nextIndex ? _keyframes[nextIndex] : null;
|
||||
@ -316,7 +314,7 @@ namespace Artemis.Core
|
||||
else
|
||||
{
|
||||
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);
|
||||
UpdateCurrentValue(keyframeProgress, keyframeProgressEased);
|
||||
}
|
||||
@ -364,12 +362,6 @@ namespace Artemis.Core
|
||||
return _dataBindingRegistrations;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Reset()
|
||||
{
|
||||
_keyframeProgress = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public void RegisterDataBindingProperty<TProperty>(Expression<Func<T, TProperty>> propertyExpression, DataBindingConverter<T, TProperty> converter)
|
||||
{
|
||||
if (_disposed)
|
||||
@ -460,7 +452,6 @@ namespace Artemis.Core
|
||||
Entity = entity ?? throw new ArgumentNullException(nameof(entity));
|
||||
PropertyDescription = description ?? throw new ArgumentNullException(nameof(description));
|
||||
IsLoadedFromStorage = fromStorage;
|
||||
LayerPropertyGroup.PropertyGroupUpdating += (sender, args) => Update(args.DeltaTime);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@ -198,11 +198,12 @@ namespace Artemis.Core
|
||||
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,
|
||||
// let properties subscribe to the update event and update themselves
|
||||
OnPropertyGroupUpdating(new LayerPropertyGroupUpdatingEventArgs(deltaTime));
|
||||
foreach (ILayerProperty layerProperty in LayerProperties)
|
||||
layerProperty.Update(renderTime, deltaTime);
|
||||
foreach (LayerPropertyGroup layerPropertyGroup in LayerPropertyGroups)
|
||||
layerPropertyGroup.Update(renderTime, deltaTime);
|
||||
}
|
||||
|
||||
private void InitializeProperty(PropertyInfo propertyInfo, PropertyDescriptionAttribute propertyDescription)
|
||||
@ -266,8 +267,6 @@ namespace Artemis.Core
|
||||
|
||||
#region Events
|
||||
|
||||
internal event EventHandler<LayerPropertyGroupUpdatingEventArgs> PropertyGroupUpdating;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the property group has initialized all its children
|
||||
/// </summary>
|
||||
@ -284,11 +283,6 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public event EventHandler VisibilityChanged;
|
||||
|
||||
internal virtual void OnPropertyGroupUpdating(LayerPropertyGroupUpdatingEventArgs e)
|
||||
{
|
||||
PropertyGroupUpdating?.Invoke(this, e);
|
||||
}
|
||||
|
||||
internal virtual void OnVisibilityChanged()
|
||||
{
|
||||
VisibilityChanged?.Invoke(this, EventArgs.Empty);
|
||||
@ -300,16 +294,5 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
#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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22,7 +22,6 @@ namespace Artemis.UI.Shared.Services
|
||||
private readonly object _selectedProfileLock = new object();
|
||||
private TimeSpan _currentTime;
|
||||
private int _pixelsPerSecond;
|
||||
private bool _previewInvalidated;
|
||||
|
||||
public ProfileEditorService(IProfileService profileService, IKernel kernel, ILogger logger, ICoreService coreService)
|
||||
{
|
||||
@ -31,20 +30,15 @@ namespace Artemis.UI.Shared.Services
|
||||
_coreService = coreService;
|
||||
_registeredPropertyEditors = new List<PropertyInputRegistration>();
|
||||
|
||||
_coreService.FrameRendered += CoreServiceOnFrameRendered;
|
||||
|
||||
Kernel = kernel;
|
||||
PixelsPerSecond = 100;
|
||||
}
|
||||
|
||||
private void CoreServiceOnFrameRendered(object? sender, FrameRenderedEventArgs e)
|
||||
{
|
||||
if (_previewInvalidated)
|
||||
{
|
||||
_previewInvalidated = false;
|
||||
_coreService.FrameRendered -= CoreServiceOnFrameRendered;
|
||||
Execute.PostToUIThread(OnProfilePreviewUpdated);
|
||||
}
|
||||
}
|
||||
|
||||
public IKernel Kernel { get; }
|
||||
public ReadOnlyCollection<PropertyInputRegistration> RegisteredPropertyEditors => _registeredPropertyEditors.AsReadOnly();
|
||||
@ -160,7 +154,7 @@ namespace Artemis.UI.Shared.Services
|
||||
foreach (Layer layer in SelectedProfile.GetAllLayers())
|
||||
layer.OverrideTimeLines(CurrentTime, layer != SelectedProfileElement);
|
||||
|
||||
_previewInvalidated = true;
|
||||
_coreService.FrameRendered += CoreServiceOnFrameRendered;
|
||||
}
|
||||
|
||||
public bool UndoUpdateProfile()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user