Profiles - Finished dispose implementation

Profiles - Added transition between active profiles
Core - Added startup animation
This commit is contained in:
Robert committed 2020-08-10 19:16:21 +02:00
1 parent c0bdd8cf26
commit d955bc8635
43 files changed
+1908 -361

No files matched your search

+42 -11
View File
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Artemis.Core.Plugins.LayerEffect.Abstract;
using Artemis.Core.Utilities;
using Artemis.Storage.Entities.Profile;
using Artemis.Storage.Entities.Profile.Abstract;
using SkiaSharp;
@@ -61,9 +62,13 @@ namespace Artemis.Core.Models.Profile
internal FolderEntity FolderEntity { get; set; }
internal override RenderElementEntity RenderElementEntity => FolderEntity;
public bool IsRootFolder => Parent == Profile;
public override void Update(double deltaTime)
{
if (_disposed)
throw new ObjectDisposedException("Folder");
if (!Enabled)
return;
@@ -89,6 +94,9 @@ namespace Artemis.Core.Models.Profile
public override void OverrideProgress(TimeSpan timeOverride, bool stickToMainSegment)
{
if (_disposed)
throw new ObjectDisposedException("Folder");
if (!Enabled)
return;
@@ -125,6 +133,9 @@ namespace Artemis.Core.Models.Profile
public override void Render(double deltaTime, SKCanvas canvas, SKImageInfo canvasInfo)
{
if (_disposed)
throw new ObjectDisposedException("Folder");
if (Path == null || !Enabled || !Children.Any(c => c.Enabled))
return;
@@ -172,6 +183,13 @@ namespace Artemis.Core.Models.Profile
profileElement.Render(deltaTime, folderCanvas, _folderBitmap.Info);
folderCanvas.Restore();
}
// If required, apply the opacity override of the module to the root folder
if (IsRootFolder && Profile.Module.OpacityOverride < 1)
{
var multiplier = Easings.SineEaseInOut(Profile.Module.OpacityOverride);
folderPaint.Color = folderPaint.Color.WithAlpha((byte) (folderPaint.Color.Alpha * multiplier));
}
foreach (var baseLayerEffect in LayerEffects.Where(e => e.Enabled))
baseLayerEffect.PostProcess(canvas, canvasInfo, folderPath, folderPaint);
@@ -187,6 +205,9 @@ namespace Artemis.Core.Models.Profile
/// <returns></returns>
public Folder AddFolder(string name)
{
if (_disposed)
throw new ObjectDisposedException("Folder");
var folder = new Folder(Profile, this, name) {Order = Children.LastOrDefault()?.Order ?? 1};
AddChild(folder);
return folder;
@@ -195,6 +216,9 @@ namespace Artemis.Core.Models.Profile
/// <inheritdoc />
public override void AddChild(ProfileElement child, int? order = null)
{
if (_disposed)
throw new ObjectDisposedException("Folder");
base.AddChild(child, order);
CalculateRenderProperties();
}
@@ -202,6 +226,9 @@ namespace Artemis.Core.Models.Profile
/// <inheritdoc />
public override void RemoveChild(ProfileElement child)
{
if (_disposed)
throw new ObjectDisposedException("Folder");
base.RemoveChild(child);
CalculateRenderProperties();
}
@@ -213,6 +240,9 @@ namespace Artemis.Core.Models.Profile
public void CalculateRenderProperties()
{
if (_disposed)
throw new ObjectDisposedException("Folder");
var path = new SKPath {FillType = SKPathFillType.Winding};
foreach (var child in Children)
{
@@ -234,16 +264,27 @@ namespace Artemis.Core.Models.Profile
if (!disposing)
return;
_folderBitmap?.Dispose();
foreach (var baseLayerEffect in LayerEffects)
baseLayerEffect.Dispose();
_layerEffects.Clear();
foreach (var profileElement in Children)
profileElement.Dispose();
ChildrenList.Clear();
_folderBitmap?.Dispose();
_folderBitmap = null;
Profile = null;
_disposed = true;
}
internal override void ApplyToEntity()
{
if (_disposed)
throw new ObjectDisposedException("Folder");
FolderEntity.Id = EntityId;
FolderEntity.ParentId = Parent?.EntityId ?? new Guid();
@@ -262,16 +303,6 @@ namespace Artemis.Core.Models.Profile
DisplayConditionGroup?.ApplyToEntity();
}
internal void Deactivate()
{
_folderBitmap?.Dispose();
_folderBitmap = null;
var layerEffects = new List<BaseLayerEffect>(LayerEffects);
foreach (var baseLayerEffect in layerEffects)
DeactivateLayerEffect(baseLayerEffect);
}
#region Events
public event EventHandler RenderPropertiesUpdated;
+61 -18
View File
@@ -126,6 +126,9 @@ namespace Artemis.Core.Models.Profile
/// <inheritdoc />
public override List<BaseLayerPropertyKeyframe> GetAllKeyframes()
{
if (_disposed)
throw new ObjectDisposedException("Layer");
var keyframes = base.GetAllKeyframes();
foreach (var baseLayerProperty in General.GetAllLayerProperties())
@@ -143,22 +146,36 @@ namespace Artemis.Core.Models.Profile
protected override void Dispose(bool disposing)
{
if (!disposing)
if (!disposing)
return;
_general?.Dispose();
_layerBitmap?.Dispose();
_disposed = true;
// Brush first in case it depends on any of the other disposables during it's own disposal
_layerBrush?.Dispose();
_transform?.Dispose();
_layerBrush = null;
foreach (var baseLayerEffect in LayerEffects)
baseLayerEffect.Dispose();
_layerEffects.Clear();
_general?.Dispose();
_general = null;
_layerBitmap?.Dispose();
_layerBitmap = null;
_transform?.Dispose();
_transform = null;
Profile = null;
}
#region Storage
internal override void ApplyToEntity()
{
if (_disposed)
throw new ObjectDisposedException("Layer");
// Properties
LayerEntity.Id = EntityId;
LayerEntity.ParentId = Parent?.EntityId ?? new Guid();
@@ -231,6 +248,9 @@ namespace Artemis.Core.Models.Profile
/// <inheritdoc />
public override void Update(double deltaTime)
{
if (_disposed)
throw new ObjectDisposedException("Layer");
if (!Enabled || LayerBrush?.BaseProperties == null || !LayerBrush.BaseProperties.PropertiesInitialized)
return;
@@ -259,6 +279,9 @@ namespace Artemis.Core.Models.Profile
public override void OverrideProgress(TimeSpan timeOverride, bool stickToMainSegment)
{
if (_disposed)
throw new ObjectDisposedException("Layer");
if (!Enabled || LayerBrush?.BaseProperties == null || !LayerBrush.BaseProperties.PropertiesInitialized)
return;
@@ -268,9 +291,7 @@ namespace Artemis.Core.Models.Profile
{
if (!DisplayContinuously)
{
var position = timeOverride + StartSegmentLength;
if (position > StartSegmentLength + EndSegmentLength)
TimelinePosition = StartSegmentLength + EndSegmentLength;
TimelinePosition = StartSegmentLength + timeOverride;
}
else
{
@@ -301,6 +322,9 @@ namespace Artemis.Core.Models.Profile
/// <inheritdoc />
public override void Render(double deltaTime, SKCanvas canvas, SKImageInfo canvasInfo)
{
if (_disposed)
throw new ObjectDisposedException("Layer");
if (!Enabled || TimelinePosition > TimelineLength)
return;
@@ -424,6 +448,9 @@ namespace Artemis.Core.Models.Profile
internal void CalculateRenderProperties()
{
if (_disposed)
throw new ObjectDisposedException("Layer");
if (!Leds.Any())
Path = new SKPath();
else
@@ -448,6 +475,9 @@ namespace Artemis.Core.Models.Profile
internal SKPoint GetLayerAnchorPosition(SKPath layerPath, bool zeroBased = false)
{
if (_disposed)
throw new ObjectDisposedException("Layer");
var positionProperty = Transform.Position.CurrentValue;
// Start at the center of the shape
@@ -469,6 +499,9 @@ namespace Artemis.Core.Models.Profile
/// <param name="path"></param>
public void IncludePathInTranslation(SKPath path, bool zeroBased)
{
if (_disposed)
throw new ObjectDisposedException("Layer");
var sizeProperty = Transform.Scale.CurrentValue;
var rotationProperty = Transform.Rotation.CurrentValue;
@@ -498,6 +531,9 @@ namespace Artemis.Core.Models.Profile
/// </summary>
public void ExcludePathFromTranslation(SKPath path, bool zeroBased)
{
if (_disposed)
throw new ObjectDisposedException("Layer");
var sizeProperty = Transform.Scale.CurrentValue;
var rotationProperty = Transform.Rotation.CurrentValue;
@@ -531,6 +567,9 @@ namespace Artemis.Core.Models.Profile
/// <returns>The number of transformations applied</returns>
public int ExcludeCanvasFromTranslation(SKCanvas canvas, bool zeroBased)
{
if (_disposed)
throw new ObjectDisposedException("Layer");
var sizeProperty = Transform.Scale.CurrentValue;
var rotationProperty = Transform.Rotation.CurrentValue;
@@ -568,6 +607,9 @@ namespace Artemis.Core.Models.Profile
/// <param name="led">The LED to add</param>
public void AddLed(ArtemisLed led)
{
if (_disposed)
throw new ObjectDisposedException("Layer");
_leds.Add(led);
CalculateRenderProperties();
}
@@ -578,6 +620,9 @@ namespace Artemis.Core.Models.Profile
/// <param name="leds">The LEDs to add</param>
public void AddLeds(IEnumerable<ArtemisLed> leds)
{
if (_disposed)
throw new ObjectDisposedException("Layer");
_leds.AddRange(leds);
CalculateRenderProperties();
}
@@ -588,6 +633,9 @@ namespace Artemis.Core.Models.Profile
/// <param name="led">The LED to remove</param>
public void RemoveLed(ArtemisLed led)
{
if (_disposed)
throw new ObjectDisposedException("Layer");
_leds.Remove(led);
CalculateRenderProperties();
}
@@ -597,12 +645,18 @@ namespace Artemis.Core.Models.Profile
/// </summary>
public void ClearLeds()
{
if (_disposed)
throw new ObjectDisposedException("Layer");
_leds.Clear();
CalculateRenderProperties();
}
internal void PopulateLeds(ArtemisSurface surface)
{
if (_disposed)
throw new ObjectDisposedException("Layer");
var leds = new List<ArtemisLed>();
// Get the surface LEDs for this layer
@@ -623,17 +677,6 @@ namespace Artemis.Core.Models.Profile
#region Activation
internal void Deactivate()
{
_layerBitmap?.Dispose();
_layerBitmap = null;
DeactivateLayerBrush();
var layerEffects = new List<BaseLayerEffect>(LayerEffects);
foreach (var baseLayerEffect in layerEffects)
DeactivateLayerEffect(baseLayerEffect);
}
internal void DeactivateLayerBrush()
{
if (LayerBrush == null)
@@ -28,5 +28,9 @@ namespace Artemis.Core.Models.Profile
protected override void EnableProperties()
{
}
protected override void DisableProperties()
{
}
}
}
@@ -110,6 +110,8 @@ namespace Artemis.Core.Models.Profile
public void Dispose()
{
DisableProperties();
foreach (var layerPropertyGroup in _layerPropertyGroups)
layerPropertyGroup.Dispose();
}
/// <summary>
@@ -30,5 +30,9 @@ namespace Artemis.Core.Models.Profile
protected override void EnableProperties()
{
}
protected override void DisableProperties()
{
}
}
}
+30 -25
View File
@@ -57,6 +57,8 @@ namespace Artemis.Core.Models.Profile
{
lock (this)
{
if (_disposed)
throw new ObjectDisposedException("Profile");
if (!IsActivated)
throw new ArtemisCoreException($"Cannot update inactive profile: {this}");
@@ -69,6 +71,8 @@ namespace Artemis.Core.Models.Profile
{
lock (this)
{
if (_disposed)
throw new ObjectDisposedException("Profile");
if (!IsActivated)
throw new ArtemisCoreException($"Cannot render inactive profile: {this}");
@@ -79,21 +83,26 @@ namespace Artemis.Core.Models.Profile
public Folder GetRootFolder()
{
if (_disposed)
throw new ObjectDisposedException("Profile");
return (Folder) Children.Single();
}
public void ApplyToProfile()
{
if (_disposed)
throw new ObjectDisposedException("Profile");
Name = ProfileEntity.Name;
lock (ChildrenList)
{
foreach (var folder in GetAllFolders())
folder.Deactivate();
foreach (var layer in GetAllLayers())
layer.Deactivate();
// Remove the old profile tree
foreach (var profileElement in Children)
profileElement.Dispose();
ChildrenList.Clear();
// Populate the profile starting at the root, the rest is populated recursively
var rootFolder = ProfileEntity.Folders.FirstOrDefault(f => f.ParentId == EntityId);
if (rootFolder == null)
@@ -113,13 +122,21 @@ namespace Artemis.Core.Models.Profile
if (!disposing)
return;
Deactivate();
OnDeactivating();
foreach (var profileElement in Children)
profileElement.Dispose();
ChildrenList.Clear();
IsActivated = false;
_disposed = true;
}
internal override void ApplyToEntity()
{
if (_disposed)
throw new ObjectDisposedException("Profile");
ProfileEntity.Id = EntityId;
ProfileEntity.PluginGuid = Module.PluginInfo.Guid;
ProfileEntity.Name = Name;
@@ -139,6 +156,8 @@ namespace Artemis.Core.Models.Profile
{
lock (this)
{
if (_disposed)
throw new ObjectDisposedException("Profile");
if (IsActivated)
return;
@@ -148,25 +167,11 @@ namespace Artemis.Core.Models.Profile
}
}
internal void Deactivate()
{
lock (this)
{
if (!IsActivated)
return;
foreach (var folder in GetAllFolders())
folder.Deactivate();
foreach (var layer in GetAllLayers())
layer.Deactivate();
IsActivated = false;
OnDeactivated();
}
}
internal void PopulateLeds(ArtemisSurface surface)
{
if (_disposed)
throw new ObjectDisposedException("Profile");
foreach (var layer in GetAllLayers())
layer.PopulateLeds(surface);
}
@@ -174,7 +179,7 @@ namespace Artemis.Core.Models.Profile
#region Events
/// <summary>
/// Occurs when the profile is being activated.
/// Occurs when the profile has been activated.
/// </summary>
public event EventHandler Activated;
@@ -188,7 +193,7 @@ namespace Artemis.Core.Models.Profile
Activated?.Invoke(this, EventArgs.Empty);
}
private void OnDeactivated()
private void OnDeactivating()
{
Deactivated?.Invoke(this, EventArgs.Empty);
}
@@ -9,16 +9,16 @@ namespace Artemis.Core.Models.Profile
internal ProfileDescriptor(ProfileModule profileModule, ProfileEntity profileEntity)
{
ProfileModule = profileModule;
ProfileEntity = profileEntity;
Id = profileEntity.Id;
Name = profileEntity.Name;
IsLastActiveProfile = profileEntity.IsActive;
}
public bool IsLastActiveProfile { get; set; }
public Guid Id { get; }
public ProfileModule ProfileModule { get; }
public string Name { get; }
internal ProfileEntity ProfileEntity { get; }
}
}
@@ -22,6 +22,7 @@ namespace Artemis.Core.Models.Profile
GC.SuppressFinalize(this);
}
protected bool _disposed;
private bool _enabled;
private Guid _entityId;
private string _name;
@@ -98,6 +99,9 @@ namespace Artemis.Core.Models.Profile
public List<Folder> GetAllFolders()
{
if (_disposed)
throw new ObjectDisposedException(GetType().Name);
var folders = new List<Folder>();
foreach (var childFolder in Children.Where(c => c is Folder).Cast<Folder>())
{
@@ -112,6 +116,9 @@ namespace Artemis.Core.Models.Profile
public List<Layer> GetAllLayers()
{
if (_disposed)
throw new ObjectDisposedException(GetType().Name);
var layers = new List<Layer>();
// Add all layers in this element
@@ -131,6 +138,9 @@ namespace Artemis.Core.Models.Profile
/// <param name="order">The order where to place the child (1-based), defaults to the end of the collection</param>
public virtual void AddChild(ProfileElement child, int? order = null)
{
if (_disposed)
throw new ObjectDisposedException(GetType().Name);
lock (ChildrenList)
{
// Add to the end of the list
@@ -169,6 +179,9 @@ namespace Artemis.Core.Models.Profile
/// <param name="child">The profile element to remove</param>
public virtual void RemoveChild(ProfileElement child)
{
if (_disposed)
throw new ObjectDisposedException(GetType().Name);
lock (ChildrenList)
{
ChildrenList.Remove(child);
@@ -203,8 +203,6 @@ namespace Artemis.Core.Models.Profile
// If we are at the end of the main timeline, wrap around back to the beginning
if (DisplayContinuously && TimelinePosition >= mainSegmentEnd)
TimelinePosition = StartSegmentLength + (mainSegmentEnd - TimelinePosition);
else if (TimelinePosition >= TimelineLength)
TimelinePosition = TimelineLength;
}
else
{