1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00
Artemis/src/Artemis.Core/Models/BreakableModel.cs
RobertBeekman 28640f9502 Profiles - Avoid unnecessary OnBrokenStateChanged calls
Profiles - Fixed int range/float range deserialization
Profiles - Use Random.Shared where applicable
2024-03-02 17:38:20 +01:00

99 lines
2.8 KiB
C#

using System;
using System.Collections.Generic;
namespace Artemis.Core;
/// <summary>
/// Provides a default implementation for models that can have a broken state
/// </summary>
public abstract class BreakableModel : CorePropertyChanged, IBreakableModel
{
private string? _brokenState;
private Exception? _brokenStateException;
/// <summary>
/// Invokes the <see cref="BrokenStateChanged" /> event
/// </summary>
protected virtual void OnBrokenStateChanged()
{
BrokenStateChanged?.Invoke(this, EventArgs.Empty);
}
/// <inheritdoc />
public abstract string BrokenDisplayName { get; }
/// <summary>
/// Gets or sets the broken state of this breakable model, if <see langword="null" /> this model is not broken.
/// <para>Note: If setting this manually you are also responsible for invoking <see cref="BrokenStateChanged" /></para>
/// </summary>
public string? BrokenState
{
get => _brokenState;
set => SetAndNotify(ref _brokenState, value);
}
/// <summary>
/// Gets or sets the exception that caused the broken state
/// <para>Note: If setting this manually you are also responsible for invoking <see cref="BrokenStateChanged" /></para>
/// </summary>
public Exception? BrokenStateException
{
get => _brokenStateException;
set => SetAndNotify(ref _brokenStateException, value);
}
/// <inheritdoc />
public bool TryOrBreak(Action action, string breakMessage)
{
try
{
action();
ClearBrokenState(breakMessage);
return true;
}
catch (Exception e)
{
SetBrokenState(breakMessage, e);
return false;
}
}
/// <inheritdoc />
public void SetBrokenState(string state, Exception? exception = null)
{
if (state == BrokenState && BrokenStateException?.StackTrace == exception?.StackTrace)
return;
BrokenState = state ?? throw new ArgumentNullException(nameof(state));
BrokenStateException = exception;
OnBrokenStateChanged();
}
/// <inheritdoc />
public void ClearBrokenState(string state)
{
if (state == null)
throw new ArgumentNullException(nameof(state));
// If there was no broken state to begin with, done!
if (BrokenState == null)
return;
// Only clear similar broken states
if (BrokenState != state)
return;
BrokenState = null;
BrokenStateException = null;
OnBrokenStateChanged();
}
/// <inheritdoc />
public virtual IEnumerable<IBreakableModel> GetBrokenHierarchy()
{
if (BrokenState != null)
yield return this;
}
/// <inheritdoc />
public event EventHandler? BrokenStateChanged;
}