mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Core - Removed scripting providers
Meta - Updated packages
This commit is contained in:
parent
7691af95b9
commit
37f973b093
@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Core.ScriptingProviders;
|
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
@ -14,15 +12,10 @@ namespace Artemis.Core;
|
|||||||
public sealed class Profile : ProfileElement
|
public sealed class Profile : ProfileElement
|
||||||
{
|
{
|
||||||
private readonly object _lock = new();
|
private readonly object _lock = new();
|
||||||
private readonly ObservableCollection<ScriptConfiguration> _scriptConfigurations;
|
|
||||||
private readonly ObservableCollection<ProfileScript> _scripts;
|
|
||||||
private bool _isFreshImport;
|
private bool _isFreshImport;
|
||||||
|
|
||||||
internal Profile(ProfileConfiguration configuration, ProfileEntity profileEntity) : base(null!)
|
internal Profile(ProfileConfiguration configuration, ProfileEntity profileEntity) : base(null!)
|
||||||
{
|
{
|
||||||
_scripts = new ObservableCollection<ProfileScript>();
|
|
||||||
_scriptConfigurations = new ObservableCollection<ScriptConfiguration>();
|
|
||||||
|
|
||||||
Opacity = 0d;
|
Opacity = 0d;
|
||||||
ShouldDisplay = true;
|
ShouldDisplay = true;
|
||||||
Configuration = configuration;
|
Configuration = configuration;
|
||||||
@ -31,8 +24,6 @@ public sealed class Profile : ProfileElement
|
|||||||
EntityId = profileEntity.Id;
|
EntityId = profileEntity.Id;
|
||||||
|
|
||||||
Exceptions = new List<Exception>();
|
Exceptions = new List<Exception>();
|
||||||
Scripts = new ReadOnlyObservableCollection<ProfileScript>(_scripts);
|
|
||||||
ScriptConfigurations = new ReadOnlyObservableCollection<ScriptConfiguration>(_scriptConfigurations);
|
|
||||||
|
|
||||||
Load();
|
Load();
|
||||||
}
|
}
|
||||||
@ -41,17 +32,7 @@ public sealed class Profile : ProfileElement
|
|||||||
/// Gets the profile configuration of this profile
|
/// Gets the profile configuration of this profile
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ProfileConfiguration Configuration { get; }
|
public ProfileConfiguration Configuration { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a collection of all active scripts assigned to this profile
|
|
||||||
/// </summary>
|
|
||||||
public ReadOnlyObservableCollection<ProfileScript> Scripts { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a collection of all script configurations assigned to this profile
|
|
||||||
/// </summary>
|
|
||||||
public ReadOnlyObservableCollection<ScriptConfiguration> ScriptConfigurations { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a boolean indicating whether this profile is freshly imported i.e. no changes have been made to it
|
/// Gets or sets a boolean indicating whether this profile is freshly imported i.e. no changes have been made to it
|
||||||
/// since import
|
/// since import
|
||||||
@ -85,15 +66,9 @@ public sealed class Profile : ProfileElement
|
|||||||
if (Disposed)
|
if (Disposed)
|
||||||
throw new ObjectDisposedException("Profile");
|
throw new ObjectDisposedException("Profile");
|
||||||
|
|
||||||
foreach (ProfileScript profileScript in Scripts)
|
|
||||||
profileScript.OnProfileUpdating(deltaTime);
|
|
||||||
|
|
||||||
foreach (ProfileElement profileElement in Children)
|
foreach (ProfileElement profileElement in Children)
|
||||||
profileElement.Update(deltaTime);
|
profileElement.Update(deltaTime);
|
||||||
|
|
||||||
foreach (ProfileScript profileScript in Scripts)
|
|
||||||
profileScript.OnProfileUpdated(deltaTime);
|
|
||||||
|
|
||||||
const double OPACITY_PER_SECOND = 1;
|
const double OPACITY_PER_SECOND = 1;
|
||||||
|
|
||||||
if (ShouldDisplay && Opacity < 1)
|
if (ShouldDisplay && Opacity < 1)
|
||||||
@ -111,9 +86,6 @@ public sealed class Profile : ProfileElement
|
|||||||
if (Disposed)
|
if (Disposed)
|
||||||
throw new ObjectDisposedException("Profile");
|
throw new ObjectDisposedException("Profile");
|
||||||
|
|
||||||
foreach (ProfileScript profileScript in Scripts)
|
|
||||||
profileScript.OnProfileRendering(canvas, canvas.LocalClipBounds);
|
|
||||||
|
|
||||||
SKPaint? opacityPaint = null;
|
SKPaint? opacityPaint = null;
|
||||||
bool applyOpacityLayer = Configuration.FadeInAndOut && Opacity < 1;
|
bool applyOpacityLayer = Configuration.FadeInAndOut && Opacity < 1;
|
||||||
|
|
||||||
@ -133,9 +105,6 @@ public sealed class Profile : ProfileElement
|
|||||||
opacityPaint?.Dispose();
|
opacityPaint?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (ProfileScript profileScript in Scripts)
|
|
||||||
profileScript.OnProfileRendered(canvas, canvas.LocalClipBounds);
|
|
||||||
|
|
||||||
if (!Exceptions.Any())
|
if (!Exceptions.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -174,7 +143,7 @@ public sealed class Profile : ProfileElement
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override IEnumerable<PluginFeature> GetFeatureDependencies()
|
public override IEnumerable<PluginFeature> GetFeatureDependencies()
|
||||||
{
|
{
|
||||||
return GetRootFolder().GetFeatureDependencies().Concat(Scripts.Select(c => c.ScriptingProvider));
|
return GetRootFolder().GetFeatureDependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -205,10 +174,7 @@ public sealed class Profile : ProfileElement
|
|||||||
{
|
{
|
||||||
if (!disposing)
|
if (!disposing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (Scripts.Count > 0)
|
|
||||||
RemoveScript(Scripts[0]);
|
|
||||||
|
|
||||||
foreach (ProfileElement profileElement in Children)
|
foreach (ProfileElement profileElement in Children)
|
||||||
profileElement.Dispose();
|
profileElement.Dispose();
|
||||||
ChildrenList.Clear();
|
ChildrenList.Clear();
|
||||||
@ -238,61 +204,11 @@ public sealed class Profile : ProfileElement
|
|||||||
AddChild(new Folder(this, this, rootFolder));
|
AddChild(new Folder(this, this, rootFolder));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (_scriptConfigurations.Any())
|
|
||||||
RemoveScriptConfiguration(_scriptConfigurations[0]);
|
|
||||||
foreach (ScriptConfiguration scriptConfiguration in ProfileEntity.ScriptConfigurations.Select(e => new ScriptConfiguration(e)))
|
|
||||||
AddScriptConfiguration(scriptConfiguration);
|
|
||||||
|
|
||||||
// Load node scripts last since they may rely on the profile structure being in place
|
// Load node scripts last since they may rely on the profile structure being in place
|
||||||
foreach (RenderProfileElement renderProfileElement in GetAllRenderElements())
|
foreach (RenderProfileElement renderProfileElement in GetAllRenderElements())
|
||||||
renderProfileElement.LoadNodeScript();
|
renderProfileElement.LoadNodeScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes a script configuration from the profile, if the configuration has an active script it is also removed.
|
|
||||||
/// </summary>
|
|
||||||
internal void RemoveScriptConfiguration(ScriptConfiguration scriptConfiguration)
|
|
||||||
{
|
|
||||||
if (!_scriptConfigurations.Contains(scriptConfiguration))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Script? script = scriptConfiguration.Script;
|
|
||||||
if (script != null)
|
|
||||||
RemoveScript((ProfileScript) script);
|
|
||||||
|
|
||||||
_scriptConfigurations.Remove(scriptConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a script configuration to the profile but does not instantiate it's script.
|
|
||||||
/// </summary>
|
|
||||||
internal void AddScriptConfiguration(ScriptConfiguration scriptConfiguration)
|
|
||||||
{
|
|
||||||
if (!_scriptConfigurations.Contains(scriptConfiguration))
|
|
||||||
_scriptConfigurations.Add(scriptConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a script that has a script configuration belonging to this profile.
|
|
||||||
/// </summary>
|
|
||||||
internal void AddScript(ProfileScript script)
|
|
||||||
{
|
|
||||||
if (!_scriptConfigurations.Contains(script.ScriptConfiguration))
|
|
||||||
throw new ArtemisCoreException("Cannot add a script to a profile whose script configuration doesn't belong to the same profile.");
|
|
||||||
|
|
||||||
if (!_scripts.Contains(script))
|
|
||||||
_scripts.Add(script);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes a script from the profile and disposes it.
|
|
||||||
/// </summary>
|
|
||||||
internal void RemoveScript(ProfileScript script)
|
|
||||||
{
|
|
||||||
_scripts.Remove(script);
|
|
||||||
script.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal override void Save()
|
internal override void Save()
|
||||||
{
|
{
|
||||||
if (Disposed)
|
if (Disposed)
|
||||||
@ -310,12 +226,5 @@ public sealed class Profile : ProfileElement
|
|||||||
|
|
||||||
ProfileEntity.Layers.Clear();
|
ProfileEntity.Layers.Clear();
|
||||||
ProfileEntity.Layers.AddRange(GetAllLayers().Select(f => f.LayerEntity));
|
ProfileEntity.Layers.AddRange(GetAllLayers().Select(f => f.LayerEntity));
|
||||||
|
|
||||||
ProfileEntity.ScriptConfigurations.Clear();
|
|
||||||
foreach (ScriptConfiguration scriptConfiguration in ScriptConfigurations)
|
|
||||||
{
|
|
||||||
scriptConfiguration.Save();
|
|
||||||
ProfileEntity.ScriptConfigurations.Add(scriptConfiguration.Entity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,23 +0,0 @@
|
|||||||
namespace Artemis.Core.ScriptingProviders;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a view model containing a script editor
|
|
||||||
/// </summary>
|
|
||||||
public interface IScriptEditorViewModel
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the script type this view model was created for
|
|
||||||
/// </summary>
|
|
||||||
ScriptType ScriptType { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the script this editor is editing
|
|
||||||
/// </summary>
|
|
||||||
Script? Script { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called whenever the view model must display a different script
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="script">The script to display or <see langword="null" /> if no script is to be displayed</param>
|
|
||||||
void ChangeScript(Script? script);
|
|
||||||
}
|
|
||||||
@ -1,163 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Artemis.Storage.Entities.General;
|
|
||||||
|
|
||||||
namespace Artemis.Core.ScriptingProviders;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents the configuration of a script
|
|
||||||
/// </summary>
|
|
||||||
public class ScriptConfiguration : CorePropertyChanged, IStorageModel
|
|
||||||
{
|
|
||||||
private bool _hasChanges;
|
|
||||||
private bool _isSuspended;
|
|
||||||
private string _name;
|
|
||||||
private string? _pendingScriptContent;
|
|
||||||
private string? _scriptContent;
|
|
||||||
private string _scriptingProviderId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new instance of the <see cref="ScriptConfiguration" /> class
|
|
||||||
/// </summary>
|
|
||||||
public ScriptConfiguration(ScriptingProvider provider, string name, ScriptType scriptType)
|
|
||||||
{
|
|
||||||
_scriptingProviderId = provider.Id;
|
|
||||||
_name = name;
|
|
||||||
Entity = new ScriptConfigurationEntity();
|
|
||||||
PendingScriptContent = provider.GetDefaultScriptContent(scriptType);
|
|
||||||
ScriptContent = PendingScriptContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal ScriptConfiguration(ScriptConfigurationEntity entity)
|
|
||||||
{
|
|
||||||
_scriptingProviderId = null!;
|
|
||||||
_name = null!;
|
|
||||||
Entity = entity;
|
|
||||||
|
|
||||||
Load();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the ID of the scripting provider
|
|
||||||
/// </summary>
|
|
||||||
public string ScriptingProviderId
|
|
||||||
{
|
|
||||||
get => _scriptingProviderId;
|
|
||||||
set => SetAndNotify(ref _scriptingProviderId, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name of the script
|
|
||||||
/// </summary>
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get => _name;
|
|
||||||
set => SetAndNotify(ref _name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the script's content
|
|
||||||
/// </summary>
|
|
||||||
public string? ScriptContent
|
|
||||||
{
|
|
||||||
get => _scriptContent;
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
if (!SetAndNotify(ref _scriptContent, value)) return;
|
|
||||||
OnScriptContentChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the pending changes to the script's content
|
|
||||||
/// </summary>
|
|
||||||
public string? PendingScriptContent
|
|
||||||
{
|
|
||||||
get => _pendingScriptContent;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(value))
|
|
||||||
value = null;
|
|
||||||
if (!SetAndNotify(ref _pendingScriptContent, value)) return;
|
|
||||||
HasChanges = ScriptContent != PendingScriptContent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Implement suspension
|
|
||||||
/// <summary>
|
|
||||||
/// [NYI] Gets or sets a boolean indicating whether this configuration is suspended
|
|
||||||
/// </summary>
|
|
||||||
public bool IsSuspended
|
|
||||||
{
|
|
||||||
get => _isSuspended;
|
|
||||||
set => SetAndNotify(ref _isSuspended, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a boolean indicating whether this configuration has pending changes to it's
|
|
||||||
/// <see cref="ScriptContent" />
|
|
||||||
/// </summary>
|
|
||||||
public bool HasChanges
|
|
||||||
{
|
|
||||||
get => _hasChanges;
|
|
||||||
set => SetAndNotify(ref _hasChanges, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If active, gets the script
|
|
||||||
/// </summary>
|
|
||||||
public Script? Script { get; internal set; }
|
|
||||||
|
|
||||||
internal ScriptConfigurationEntity Entity { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Applies the <see cref="PendingScriptContent" /> to the <see cref="ScriptContent" />
|
|
||||||
/// </summary>
|
|
||||||
public void ApplyPendingChanges()
|
|
||||||
{
|
|
||||||
ScriptContent = PendingScriptContent;
|
|
||||||
HasChanges = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Discards the <see cref="PendingScriptContent" />
|
|
||||||
/// </summary>
|
|
||||||
public void DiscardPendingChanges()
|
|
||||||
{
|
|
||||||
PendingScriptContent = ScriptContent;
|
|
||||||
HasChanges = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs whenever the contents of the script have changed
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler? ScriptContentChanged;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invokes the <see cref="ScriptContentChanged" /> event
|
|
||||||
/// </summary>
|
|
||||||
protected virtual void OnScriptContentChanged()
|
|
||||||
{
|
|
||||||
ScriptContentChanged?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Implementation of IStorageModel
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Load()
|
|
||||||
{
|
|
||||||
ScriptingProviderId = Entity.ScriptingProviderId;
|
|
||||||
ScriptContent = Entity.ScriptContent;
|
|
||||||
PendingScriptContent = Entity.ScriptContent;
|
|
||||||
Name = Entity.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Save()
|
|
||||||
{
|
|
||||||
Entity.ScriptingProviderId = ScriptingProviderId;
|
|
||||||
Entity.ScriptContent = ScriptContent;
|
|
||||||
Entity.Name = Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
|
|
||||||
namespace Artemis.Core.ScriptingProviders;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Allows you to implement and register your own scripting provider.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class ScriptingProvider<TGlobalScript, TProfileScript> : ScriptingProvider
|
|
||||||
where TGlobalScript : GlobalScript
|
|
||||||
where TProfileScript : ProfileScript
|
|
||||||
{
|
|
||||||
#region Overrides of PluginFeature
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
internal override void InternalDisable()
|
|
||||||
{
|
|
||||||
base.InternalDisable();
|
|
||||||
|
|
||||||
while (Scripts.Count > 0)
|
|
||||||
Scripts[0].Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Overrides of ScriptingProvider
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
internal override Type ProfileScriptType => typeof(TProfileScript);
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
internal override Type GlobalScriptType => typeof(TGlobalScript);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Allows you to implement and register your own scripting provider.
|
|
||||||
/// <para>
|
|
||||||
/// Note: You can't implement this, implement
|
|
||||||
/// <see cref="ScriptingProvider{TGlobalScript, TProfileScript}" /> instead.
|
|
||||||
/// </para>
|
|
||||||
/// </summary>
|
|
||||||
public abstract class ScriptingProvider : PluginFeature
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The base constructor of the <see cref="ScriptingProvider" /> class
|
|
||||||
/// </summary>
|
|
||||||
protected ScriptingProvider()
|
|
||||||
{
|
|
||||||
Scripts = new ReadOnlyCollection<Script>(InternalScripts);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the name of the scripting language this provider provides
|
|
||||||
/// </summary>
|
|
||||||
public abstract string LanguageName { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a list of all active scripts belonging to this scripting provider
|
|
||||||
/// </summary>
|
|
||||||
public ReadOnlyCollection<Script> Scripts { get; }
|
|
||||||
|
|
||||||
internal abstract Type GlobalScriptType { get; }
|
|
||||||
internal abstract Type ProfileScriptType { get; }
|
|
||||||
internal List<Script> InternalScripts { get; } = new();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when the UI needs a script editor for the specified <paramref name="scriptType" />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="scriptType">The type of script the editor will host</param>
|
|
||||||
public abstract IScriptEditorViewModel CreateScriptEditor(ScriptType scriptType);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when a script for a certain type needs default content.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="scriptType">The type of script the default content is for.</param>
|
|
||||||
public abstract string GetDefaultScriptContent(ScriptType scriptType);
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
using Artemis.Core.Services;
|
|
||||||
|
|
||||||
namespace Artemis.Core.ScriptingProviders;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a script running globally
|
|
||||||
/// </summary>
|
|
||||||
public abstract class GlobalScript : Script
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected GlobalScript(ScriptConfiguration configuration) : base(configuration)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
internal ScriptingService? ScriptingService { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called whenever the Artemis Core is about to update
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="deltaTime">Seconds passed since last update</param>
|
|
||||||
public virtual void OnCoreUpdating(double deltaTime)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called whenever the Artemis Core has been updated
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="deltaTime">Seconds passed since last update</param>
|
|
||||||
public virtual void OnCoreUpdated(double deltaTime)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Overrides of Script
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override ScriptType ScriptType => ScriptType.Global;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
internal override void InternalCleanup()
|
|
||||||
{
|
|
||||||
ScriptingService?.RemoveScript(ScriptConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
using SkiaSharp;
|
|
||||||
|
|
||||||
namespace Artemis.Core.ScriptingProviders;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a script bound to a specific <see cref="Profile" /> processed by a <see cref="ScriptingProvider" />.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class ProfileScript : Script
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected ProfileScript(Profile profile, ScriptConfiguration configuration) : base(configuration)
|
|
||||||
{
|
|
||||||
Profile = profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the profile this script is bound to
|
|
||||||
/// </summary>
|
|
||||||
public Profile Profile { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called whenever the profile is about to update
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="deltaTime">Seconds passed since last update</param>
|
|
||||||
public virtual void OnProfileUpdating(double deltaTime)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called whenever the profile has been updated
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="deltaTime">Seconds passed since last update</param>
|
|
||||||
public virtual void OnProfileUpdated(double deltaTime)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called whenever the profile is about to render
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="canvas">The profile canvas</param>
|
|
||||||
/// <param name="bounds">The area to be filled, covers the entire canvas</param>
|
|
||||||
public virtual void OnProfileRendering(SKCanvas canvas, SKRect bounds)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called whenever the profile has been rendered
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="canvas">The profile canvas</param>
|
|
||||||
/// <param name="bounds">The area to be filled, covers the entire canvas</param>
|
|
||||||
public virtual void OnProfileRendered(SKCanvas canvas, SKRect bounds)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Overrides of Script
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override ScriptType ScriptType => ScriptType.Profile;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
internal override void InternalCleanup()
|
|
||||||
{
|
|
||||||
Profile.RemoveScript(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
@ -1,114 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
|
|
||||||
namespace Artemis.Core.ScriptingProviders;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a script processed by a <see cref="ScriptingProviders.ScriptingProvider" />.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class Script : CorePropertyChanged, IDisposable
|
|
||||||
{
|
|
||||||
private bool _disposed;
|
|
||||||
private ScriptingProvider _scriptingProvider = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The base constructor of any script
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="configuration">The script configuration this script belongs to</param>
|
|
||||||
protected Script(ScriptConfiguration configuration)
|
|
||||||
{
|
|
||||||
if (configuration.Script != null)
|
|
||||||
throw new ArtemisCoreException("The provided script configuration already has an active script");
|
|
||||||
|
|
||||||
ScriptConfiguration = configuration;
|
|
||||||
ScriptConfiguration.PropertyChanged += ScriptConfigurationOnPropertyChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the scripting provider this script belongs to
|
|
||||||
/// </summary>
|
|
||||||
public ScriptingProvider ScriptingProvider
|
|
||||||
{
|
|
||||||
get => _scriptingProvider;
|
|
||||||
internal set => SetAndNotify(ref _scriptingProvider, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the script configuration this script belongs to
|
|
||||||
/// </summary>
|
|
||||||
public ScriptConfiguration ScriptConfiguration { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the script type of this script
|
|
||||||
/// </summary>
|
|
||||||
public abstract ScriptType ScriptType { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs when the contents of the script have changed
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler? ScriptContentChanged;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Releases the unmanaged resources used by the object and optionally releases the managed resources.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="disposing">
|
|
||||||
/// <see langword="true" /> to release both managed and unmanaged resources;
|
|
||||||
/// <see langword="false" /> to release only unmanaged resources.
|
|
||||||
/// </param>
|
|
||||||
protected virtual void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invokes the <see cref="ScriptContentChanged" /> event
|
|
||||||
/// </summary>
|
|
||||||
protected virtual void OnScriptContentChanged()
|
|
||||||
{
|
|
||||||
ScriptContentChanged?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal abstract void InternalCleanup();
|
|
||||||
|
|
||||||
private void ScriptConfigurationOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.PropertyName == nameof(ScriptConfiguration.ScriptContent))
|
|
||||||
OnScriptContentChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (_disposed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_disposed = true;
|
|
||||||
ScriptConfiguration.PropertyChanged -= ScriptConfigurationOnPropertyChanged;
|
|
||||||
ScriptConfiguration.Script = null;
|
|
||||||
ScriptingProvider.InternalScripts.Remove(this);
|
|
||||||
|
|
||||||
// Can't trust those pesky plugin devs!
|
|
||||||
InternalCleanup();
|
|
||||||
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a type of script
|
|
||||||
/// </summary>
|
|
||||||
public enum ScriptType
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A global script that's always active
|
|
||||||
/// </summary>
|
|
||||||
Global,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A script tied to a <see cref="Profile" />
|
|
||||||
/// </summary>
|
|
||||||
Profile
|
|
||||||
}
|
|
||||||
@ -1,4 +1,3 @@
|
|||||||
using Artemis.Core.ScriptingProviders;
|
|
||||||
using Artemis.Core.Services.Core;
|
using Artemis.Core.Services.Core;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
@ -7,22 +6,17 @@ namespace Artemis.Core.Services;
|
|||||||
internal class CoreRenderer : IRenderer
|
internal class CoreRenderer : IRenderer
|
||||||
{
|
{
|
||||||
private readonly IModuleService _moduleService;
|
private readonly IModuleService _moduleService;
|
||||||
private readonly IScriptingService _scriptingService;
|
|
||||||
private readonly IProfileService _profileService;
|
private readonly IProfileService _profileService;
|
||||||
|
|
||||||
public CoreRenderer(IModuleService moduleService, IScriptingService scriptingService, IProfileService profileService)
|
public CoreRenderer(IModuleService moduleService, IProfileService profileService)
|
||||||
{
|
{
|
||||||
_moduleService = moduleService;
|
_moduleService = moduleService;
|
||||||
_scriptingService = scriptingService;
|
|
||||||
_profileService = profileService;
|
_profileService = profileService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Render(SKCanvas canvas, double delta)
|
public void Render(SKCanvas canvas, double delta)
|
||||||
{
|
{
|
||||||
foreach (GlobalScript scriptingServiceGlobalScript in _scriptingService.GlobalScripts)
|
|
||||||
scriptingServiceGlobalScript.OnCoreUpdating(delta);
|
|
||||||
|
|
||||||
_moduleService.UpdateActiveModules(delta);
|
_moduleService.UpdateActiveModules(delta);
|
||||||
|
|
||||||
if (!_profileService.ProfileRenderingDisabled)
|
if (!_profileService.ProfileRenderingDisabled)
|
||||||
@ -30,9 +24,6 @@ internal class CoreRenderer : IRenderer
|
|||||||
_profileService.UpdateProfiles(delta);
|
_profileService.UpdateProfiles(delta);
|
||||||
_profileService.RenderProfiles(canvas);
|
_profileService.RenderProfiles(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (GlobalScript scriptingServiceGlobalScript in _scriptingService.GlobalScripts)
|
|
||||||
scriptingServiceGlobalScript.OnCoreUpdated(delta);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@ -1,17 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Artemis.Core.DryIoc.Factories;
|
using Artemis.Core.DryIoc.Factories;
|
||||||
using Artemis.Core.ScriptingProviders;
|
|
||||||
using Artemis.Storage;
|
|
||||||
using DryIoc;
|
using DryIoc;
|
||||||
using HidSharp;
|
using HidSharp;
|
||||||
using RGB.NET.Core;
|
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
using SkiaSharp;
|
|
||||||
|
|
||||||
namespace Artemis.Core.Services;
|
namespace Artemis.Core.Services;
|
||||||
|
|
||||||
@ -33,7 +28,6 @@ internal class CoreService : ICoreService
|
|||||||
IPluginManagementService pluginManagementService,
|
IPluginManagementService pluginManagementService,
|
||||||
IProfileService profileService,
|
IProfileService profileService,
|
||||||
IModuleService moduleService,
|
IModuleService moduleService,
|
||||||
IScriptingService scriptingService,
|
|
||||||
IRenderService renderService)
|
IRenderService renderService)
|
||||||
{
|
{
|
||||||
Constants.CorePlugin.Container = container;
|
Constants.CorePlugin.Container = container;
|
||||||
|
|||||||
@ -1,46 +0,0 @@
|
|||||||
using System.Collections.ObjectModel;
|
|
||||||
using Artemis.Core.ScriptingProviders;
|
|
||||||
|
|
||||||
namespace Artemis.Core.Services;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A service that allows you to manage various types of <see cref="NodeScript" /> instances
|
|
||||||
/// </summary>
|
|
||||||
public interface IScriptingService : IArtemisService
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a list of all available scripting providers
|
|
||||||
/// </summary>
|
|
||||||
ReadOnlyCollection<ScriptingProvider> ScriptingProviders { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a list of all currently active global scripts
|
|
||||||
/// </summary>
|
|
||||||
ReadOnlyCollection<GlobalScript> GlobalScripts { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a script by the provided script configuration to the provided profile and instantiates it.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="scriptConfiguration">The script configuration whose script to add.</param>
|
|
||||||
/// <param name="profile">The profile to add the script to.</param>
|
|
||||||
ProfileScript AddScript(ScriptConfiguration scriptConfiguration, Profile profile);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes a script by the provided script configuration from the provided profile and disposes it.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="scriptConfiguration">The script configuration whose script to remove.</param>
|
|
||||||
/// <param name="profile">The profile to remove the script from.</param>
|
|
||||||
void RemoveScript(ScriptConfiguration scriptConfiguration, Profile profile);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a script by the provided script configuration to the global collection and instantiates it.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="scriptConfiguration">The script configuration whose script to add.</param>
|
|
||||||
GlobalScript AddScript(ScriptConfiguration scriptConfiguration);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes a script by the provided script configuration from the global collection and disposes it.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="scriptConfiguration">The script configuration whose script to remove.</param>
|
|
||||||
void RemoveScript(ScriptConfiguration scriptConfiguration);
|
|
||||||
}
|
|
||||||
@ -1,165 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Linq;
|
|
||||||
using Artemis.Core.ScriptingProviders;
|
|
||||||
|
|
||||||
namespace Artemis.Core.Services;
|
|
||||||
|
|
||||||
internal class ScriptingService : IScriptingService
|
|
||||||
{
|
|
||||||
private readonly List<GlobalScript> _globalScripts;
|
|
||||||
private readonly IPluginManagementService _pluginManagementService;
|
|
||||||
private readonly IProfileService _profileService;
|
|
||||||
private readonly List<ScriptingProvider> _scriptingProviders;
|
|
||||||
|
|
||||||
public ScriptingService(IPluginManagementService pluginManagementService, IProfileService profileService)
|
|
||||||
{
|
|
||||||
_pluginManagementService = pluginManagementService;
|
|
||||||
_profileService = profileService;
|
|
||||||
|
|
||||||
_pluginManagementService.PluginFeatureEnabled += PluginManagementServiceOnPluginFeatureToggled;
|
|
||||||
_pluginManagementService.PluginFeatureDisabled += PluginManagementServiceOnPluginFeatureToggled;
|
|
||||||
_scriptingProviders = _pluginManagementService.GetFeaturesOfType<ScriptingProvider>();
|
|
||||||
_globalScripts = new List<GlobalScript>();
|
|
||||||
|
|
||||||
ScriptingProviders = new ReadOnlyCollection<ScriptingProvider>(_scriptingProviders);
|
|
||||||
GlobalScripts = new ReadOnlyCollection<GlobalScript>(_globalScripts);
|
|
||||||
|
|
||||||
// No need to sub to Deactivated, scripts will deactivate themselves
|
|
||||||
profileService.ProfileActivated += ProfileServiceOnProfileActivated;
|
|
||||||
|
|
||||||
foreach (ProfileCategory profileCategory in _profileService.ProfileCategories)
|
|
||||||
{
|
|
||||||
foreach (ProfileConfiguration profileConfiguration in profileCategory.ProfileConfigurations)
|
|
||||||
{
|
|
||||||
if (profileConfiguration.Profile != null)
|
|
||||||
InitializeProfileScripts(profileConfiguration.Profile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private GlobalScript CreateScriptInstance(ScriptConfiguration scriptConfiguration)
|
|
||||||
{
|
|
||||||
GlobalScript? script = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (scriptConfiguration.Script != null)
|
|
||||||
throw new ArtemisCoreException("The provided script configuration already has an active script");
|
|
||||||
|
|
||||||
ScriptingProvider? provider = _scriptingProviders.FirstOrDefault(p => p.Id == scriptConfiguration.ScriptingProviderId);
|
|
||||||
if (provider == null)
|
|
||||||
throw new ArtemisCoreException($"Can't create script instance as there is no matching scripting provider found for the script ({scriptConfiguration.ScriptingProviderId}).");
|
|
||||||
|
|
||||||
script = (GlobalScript) provider.Plugin.Resolve(provider.GlobalScriptType, scriptConfiguration);
|
|
||||||
script.ScriptingProvider = provider;
|
|
||||||
script.ScriptingService = this;
|
|
||||||
scriptConfiguration.Script = script;
|
|
||||||
provider.InternalScripts.Add(script);
|
|
||||||
|
|
||||||
return script;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
script?.Dispose();
|
|
||||||
throw new ArtemisCoreException("Failed to initialize global script", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProfileScript CreateScriptInstance(ScriptConfiguration scriptConfiguration, Profile profile)
|
|
||||||
{
|
|
||||||
ProfileScript? script = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (scriptConfiguration.Script != null)
|
|
||||||
throw new ArtemisCoreException("The provided script configuration already has an active script");
|
|
||||||
|
|
||||||
ScriptingProvider? provider = _scriptingProviders.FirstOrDefault(p => p.Id == scriptConfiguration.ScriptingProviderId);
|
|
||||||
if (provider == null)
|
|
||||||
throw new ArtemisCoreException($"Can't create script instance as there is no matching scripting provider found for the script ({scriptConfiguration.ScriptingProviderId}).");
|
|
||||||
|
|
||||||
script = (ProfileScript) provider.Plugin.Resolve(provider.ProfileScriptType, profile, scriptConfiguration);
|
|
||||||
script.ScriptingProvider = provider;
|
|
||||||
scriptConfiguration.Script = script;
|
|
||||||
provider.InternalScripts.Add(script);
|
|
||||||
lock (profile)
|
|
||||||
{
|
|
||||||
profile.AddScript(script);
|
|
||||||
}
|
|
||||||
|
|
||||||
return script;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
// If something went wrong but the script was created, clean up as best we can
|
|
||||||
if (script != null)
|
|
||||||
{
|
|
||||||
if (profile.Scripts.Contains(script))
|
|
||||||
profile.RemoveScript(script);
|
|
||||||
else
|
|
||||||
script.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new ArtemisCoreException("Failed to initialize profile script", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeProfileScripts(Profile profile)
|
|
||||||
{
|
|
||||||
// Initialize the scripts on the profile
|
|
||||||
foreach (ScriptConfiguration scriptConfiguration in profile.ScriptConfigurations.Where(c => c.Script == null && _scriptingProviders.Any(p => p.Id == c.ScriptingProviderId)))
|
|
||||||
CreateScriptInstance(scriptConfiguration, profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PluginManagementServiceOnPluginFeatureToggled(object? sender, PluginFeatureEventArgs e)
|
|
||||||
{
|
|
||||||
_scriptingProviders.Clear();
|
|
||||||
_scriptingProviders.AddRange(_pluginManagementService.GetFeaturesOfType<ScriptingProvider>());
|
|
||||||
|
|
||||||
foreach (ProfileCategory profileCategory in _profileService.ProfileCategories)
|
|
||||||
{
|
|
||||||
foreach (ProfileConfiguration profileConfiguration in profileCategory.ProfileConfigurations)
|
|
||||||
{
|
|
||||||
if (profileConfiguration.Profile != null)
|
|
||||||
InitializeProfileScripts(profileConfiguration.Profile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProfileServiceOnProfileActivated(object? sender, ProfileConfigurationEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.ProfileConfiguration.Profile != null)
|
|
||||||
InitializeProfileScripts(e.ProfileConfiguration.Profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ReadOnlyCollection<ScriptingProvider> ScriptingProviders { get; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ReadOnlyCollection<GlobalScript> GlobalScripts { get; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ProfileScript AddScript(ScriptConfiguration scriptConfiguration, Profile profile)
|
|
||||||
{
|
|
||||||
profile.AddScriptConfiguration(scriptConfiguration);
|
|
||||||
return CreateScriptInstance(scriptConfiguration, profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void RemoveScript(ScriptConfiguration scriptConfiguration, Profile profile)
|
|
||||||
{
|
|
||||||
profile.RemoveScriptConfiguration(scriptConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public GlobalScript AddScript(ScriptConfiguration scriptConfiguration)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException("Global scripts are not yet implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void RemoveScript(ScriptConfiguration scriptConfiguration)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException("Global scripts are not yet implemented.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.General;
|
|
||||||
|
|
||||||
public class ScriptConfigurationEntity
|
|
||||||
{
|
|
||||||
public Guid Id { get; set; }
|
|
||||||
|
|
||||||
public string Name { get; set; } = string.Empty;
|
|
||||||
public string ScriptingProviderId { get; set; } = string.Empty;
|
|
||||||
public string? ScriptContent { get; set; }
|
|
||||||
}
|
|
||||||
@ -11,7 +11,6 @@ public class ProfileEntity
|
|||||||
{
|
{
|
||||||
Folders = new List<FolderEntity>();
|
Folders = new List<FolderEntity>();
|
||||||
Layers = new List<LayerEntity>();
|
Layers = new List<LayerEntity>();
|
||||||
ScriptConfigurations = new List<ScriptConfigurationEntity>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
@ -21,7 +20,6 @@ public class ProfileEntity
|
|||||||
|
|
||||||
public List<FolderEntity> Folders { get; set; }
|
public List<FolderEntity> Folders { get; set; }
|
||||||
public List<LayerEntity> Layers { get; set; }
|
public List<LayerEntity> Layers { get; set; }
|
||||||
public List<ScriptConfigurationEntity> ScriptConfigurations { get; set; }
|
|
||||||
|
|
||||||
public void UpdateGuid(Guid guid)
|
public void UpdateGuid(Guid guid)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,54 +0,0 @@
|
|||||||
using Artemis.Core.ScriptingProviders;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Shared.ScriptingProviders;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a Stylet view model containing a script editor
|
|
||||||
/// </summary>
|
|
||||||
public class ScriptEditorViewModel : ActivatableViewModelBase, IScriptEditorViewModel
|
|
||||||
{
|
|
||||||
private Script? _script;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new instance of <see cref="ScriptEditorViewModel" />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="scriptType">The script type this view model was created for</param>
|
|
||||||
public ScriptEditorViewModel(ScriptType scriptType)
|
|
||||||
{
|
|
||||||
ScriptType = scriptType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called just before the script is changed to a different one
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="script">The script to display or <see langword="null" /> if no script is to be displayed</param>
|
|
||||||
protected virtual void OnScriptChanging(Script? script)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called after the script was changed to a different one
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="script">The script to display or <see langword="null" /> if no script is to be displayed</param>
|
|
||||||
protected virtual void OnScriptChanged(Script? script)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ScriptType ScriptType { get; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Script? Script
|
|
||||||
{
|
|
||||||
get => _script;
|
|
||||||
internal set => RaiseAndSetIfChanged(ref _script, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void ChangeScript(Script? script)
|
|
||||||
{
|
|
||||||
OnScriptChanging(script);
|
|
||||||
Script = script;
|
|
||||||
OnScriptChanged(script);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -67,5 +67,8 @@
|
|||||||
<UpToDateCheckInput Remove="Screens\Workshop\Entries\Tabs\PluginListView.axaml" />
|
<UpToDateCheckInput Remove="Screens\Workshop\Entries\Tabs\PluginListView.axaml" />
|
||||||
<UpToDateCheckInput Remove="Screens\Workshop\Entries\Tabs\ProfileListView.axaml" />
|
<UpToDateCheckInput Remove="Screens\Workshop\Entries\Tabs\ProfileListView.axaml" />
|
||||||
<UpToDateCheckInput Remove="Screens\Workshop\Plugins\Dialogs\PluginDialogView.axaml" />
|
<UpToDateCheckInput Remove="Screens\Workshop\Plugins\Dialogs\PluginDialogView.axaml" />
|
||||||
|
<UpToDateCheckInput Remove="Screens\Scripting\Dialogs\ScriptConfigurationCreateView.axaml" />
|
||||||
|
<UpToDateCheckInput Remove="Screens\Scripting\Dialogs\ScriptConfigurationEditView.axaml" />
|
||||||
|
<UpToDateCheckInput Remove="Screens\Scripting\ScriptsDialogView.axaml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@ -3,7 +3,6 @@ using System.Reactive;
|
|||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.LayerBrushes;
|
using Artemis.Core.LayerBrushes;
|
||||||
using Artemis.Core.LayerEffects;
|
using Artemis.Core.LayerEffects;
|
||||||
using Artemis.Core.ScriptingProviders;
|
|
||||||
using Artemis.UI.Screens.Device;
|
using Artemis.UI.Screens.Device;
|
||||||
using Artemis.UI.Screens.Device.General;
|
using Artemis.UI.Screens.Device.General;
|
||||||
using Artemis.UI.Screens.Device.InputMappings;
|
using Artemis.UI.Screens.Device.InputMappings;
|
||||||
@ -21,7 +20,6 @@ using Artemis.UI.Screens.ProfileEditor.Properties.DataBinding;
|
|||||||
using Artemis.UI.Screens.ProfileEditor.Properties.Timeline;
|
using Artemis.UI.Screens.ProfileEditor.Properties.Timeline;
|
||||||
using Artemis.UI.Screens.ProfileEditor.Properties.Tree;
|
using Artemis.UI.Screens.ProfileEditor.Properties.Tree;
|
||||||
using Artemis.UI.Screens.ProfileEditor.VisualEditor.Visualizers;
|
using Artemis.UI.Screens.ProfileEditor.VisualEditor.Visualizers;
|
||||||
using Artemis.UI.Screens.Scripting;
|
|
||||||
using Artemis.UI.Screens.Settings;
|
using Artemis.UI.Screens.Settings;
|
||||||
using Artemis.UI.Screens.Settings.Updating;
|
using Artemis.UI.Screens.Settings.Updating;
|
||||||
using Artemis.UI.Screens.Sidebar;
|
using Artemis.UI.Screens.Sidebar;
|
||||||
@ -470,32 +468,6 @@ public class LayerHintVmFactory : ILayerHintVmFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IScriptVmFactory : IVmFactory
|
|
||||||
{
|
|
||||||
ScriptConfigurationViewModel ScriptConfigurationViewModel(ScriptConfiguration scriptConfiguration);
|
|
||||||
ScriptConfigurationViewModel ScriptConfigurationViewModel(Profile profile, ScriptConfiguration scriptConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ScriptVmFactory : IScriptVmFactory
|
|
||||||
{
|
|
||||||
private readonly IContainer _container;
|
|
||||||
|
|
||||||
public ScriptVmFactory(IContainer container)
|
|
||||||
{
|
|
||||||
_container = container;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptConfigurationViewModel ScriptConfigurationViewModel(ScriptConfiguration scriptConfiguration)
|
|
||||||
{
|
|
||||||
return _container.Resolve<ScriptConfigurationViewModel>(new object[] {scriptConfiguration});
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptConfigurationViewModel ScriptConfigurationViewModel(Profile profile, ScriptConfiguration scriptConfiguration)
|
|
||||||
{
|
|
||||||
return _container.Resolve<ScriptConfigurationViewModel>(new object[] {profile, scriptConfiguration});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IReleaseVmFactory : IVmFactory
|
public interface IReleaseVmFactory : IVmFactory
|
||||||
{
|
{
|
||||||
ReleaseViewModel ReleaseListViewModel(IGetReleases_PublishedReleases_Nodes release);
|
ReleaseViewModel ReleaseListViewModel(IGetReleases_PublishedReleases_Nodes release);
|
||||||
|
|||||||
@ -9,7 +9,6 @@ using Artemis.Core.DeviceProviders;
|
|||||||
using Artemis.Core.LayerBrushes;
|
using Artemis.Core.LayerBrushes;
|
||||||
using Artemis.Core.LayerEffects;
|
using Artemis.Core.LayerEffects;
|
||||||
using Artemis.Core.Modules;
|
using Artemis.Core.Modules;
|
||||||
using Artemis.Core.ScriptingProviders;
|
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
@ -99,8 +98,6 @@ public partial class PluginFeatureViewModel : ActivatableViewModelBase
|
|||||||
return MaterialIconKind.Brush;
|
return MaterialIconKind.Brush;
|
||||||
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(LayerEffectProvider)))
|
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(LayerEffectProvider)))
|
||||||
return MaterialIconKind.AutoAwesome;
|
return MaterialIconKind.AutoAwesome;
|
||||||
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(ScriptingProvider)))
|
|
||||||
return MaterialIconKind.Code;
|
|
||||||
return MaterialIconKind.Extension;
|
return MaterialIconKind.Extension;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,8 +114,6 @@ public partial class PluginFeatureViewModel : ActivatableViewModelBase
|
|||||||
return "Layer Brush";
|
return "Layer Brush";
|
||||||
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(LayerEffectProvider)))
|
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(LayerEffectProvider)))
|
||||||
return "Layer Effect";
|
return "Layer Effect";
|
||||||
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(ScriptingProvider)))
|
|
||||||
return "Scripting Provider";
|
|
||||||
return "Miscellaneous feature";
|
return "Miscellaneous feature";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,11 +31,6 @@
|
|||||||
<avalonia:MaterialIcon Kind="Settings" />
|
<avalonia:MaterialIcon Kind="Settings" />
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="_View Scripts" Command="{CompiledBinding ViewScripts}">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<avalonia:MaterialIcon Kind="BookEdit" />
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="Adapt Profile" Command="{CompiledBinding AdaptProfile}">
|
<MenuItem Header="Adapt Profile" Command="{CompiledBinding AdaptProfile}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<avalonia:MaterialIcon Kind="Magic" />
|
<avalonia:MaterialIcon Kind="Magic" />
|
||||||
|
|||||||
@ -8,7 +8,6 @@ using System.Reactive.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Screens.Scripting;
|
|
||||||
using Artemis.UI.Screens.Sidebar;
|
using Artemis.UI.Screens.Sidebar;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Routing;
|
using Artemis.UI.Shared.Routing;
|
||||||
@ -64,7 +63,6 @@ public partial class MenuBarViewModel : ActivatableViewModelBase
|
|||||||
AddFolder = ReactiveCommand.Create(ExecuteAddFolder);
|
AddFolder = ReactiveCommand.Create(ExecuteAddFolder);
|
||||||
AddLayer = ReactiveCommand.Create(ExecuteAddLayer);
|
AddLayer = ReactiveCommand.Create(ExecuteAddLayer);
|
||||||
ViewProperties = ReactiveCommand.CreateFromTask(ExecuteViewProperties, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
|
ViewProperties = ReactiveCommand.CreateFromTask(ExecuteViewProperties, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
|
||||||
ViewScripts = ReactiveCommand.CreateFromTask(ExecuteViewScripts, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
|
|
||||||
AdaptProfile = ReactiveCommand.CreateFromTask(ExecuteAdaptProfile, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
|
AdaptProfile = ReactiveCommand.CreateFromTask(ExecuteAdaptProfile, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
|
||||||
ToggleSuspended = ReactiveCommand.Create(ExecuteToggleSuspended, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
|
ToggleSuspended = ReactiveCommand.Create(ExecuteToggleSuspended, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
|
||||||
DeleteProfile = ReactiveCommand.CreateFromTask(ExecuteDeleteProfile, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
|
DeleteProfile = ReactiveCommand.CreateFromTask(ExecuteDeleteProfile, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
|
||||||
@ -81,7 +79,6 @@ public partial class MenuBarViewModel : ActivatableViewModelBase
|
|||||||
public ReactiveCommand<Unit, Unit> AddLayer { get; }
|
public ReactiveCommand<Unit, Unit> AddLayer { get; }
|
||||||
public ReactiveCommand<Unit, Unit> ToggleSuspended { get; }
|
public ReactiveCommand<Unit, Unit> ToggleSuspended { get; }
|
||||||
public ReactiveCommand<Unit, Unit> ViewProperties { get; }
|
public ReactiveCommand<Unit, Unit> ViewProperties { get; }
|
||||||
public ReactiveCommand<Unit, Unit> ViewScripts { get; }
|
|
||||||
public ReactiveCommand<Unit, Unit> AdaptProfile { get; }
|
public ReactiveCommand<Unit, Unit> AdaptProfile { get; }
|
||||||
public ReactiveCommand<Unit, Unit> DeleteProfile { get; }
|
public ReactiveCommand<Unit, Unit> DeleteProfile { get; }
|
||||||
public ReactiveCommand<Unit, Unit> ExportProfile { get; }
|
public ReactiveCommand<Unit, Unit> ExportProfile { get; }
|
||||||
@ -133,16 +130,7 @@ public partial class MenuBarViewModel : ActivatableViewModelBase
|
|||||||
|
|
||||||
await _windowService.ShowDialogAsync<ProfileConfigurationEditViewModel, ProfileConfiguration?>(ProfileConfiguration.Category, ProfileConfiguration);
|
await _windowService.ShowDialogAsync<ProfileConfigurationEditViewModel, ProfileConfiguration?>(ProfileConfiguration.Category, ProfileConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ExecuteViewScripts()
|
|
||||||
{
|
|
||||||
if (ProfileConfiguration?.Profile == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
await _windowService.ShowDialogAsync<ScriptsDialogViewModel, object?>(ProfileConfiguration.Profile);
|
|
||||||
await _profileEditorService.SaveProfileAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ExecuteAdaptProfile()
|
private async Task ExecuteAdaptProfile()
|
||||||
{
|
{
|
||||||
if (ProfileConfiguration?.Profile == null)
|
if (ProfileConfiguration?.Profile == null)
|
||||||
|
|||||||
@ -1,36 +0,0 @@
|
|||||||
<UserControl xmlns="https://github.com/avaloniaui"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:dialogs="clr-namespace:Artemis.UI.Screens.Scripting.Dialogs"
|
|
||||||
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
|
||||||
xmlns:scriptingProviders="clr-namespace:Artemis.Core.ScriptingProviders;assembly=Artemis.Core"
|
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
|
||||||
x:Class="Artemis.UI.Screens.Scripting.Dialogs.ScriptConfigurationCreateView"
|
|
||||||
x:DataType="dialogs:ScriptConfigurationCreateViewModel">
|
|
||||||
<Panel>
|
|
||||||
<StackPanel IsVisible="{CompiledBinding ScriptingProviders.Count}">
|
|
||||||
<TextBlock Classes="label" Margin="0 5">Script name</TextBlock>
|
|
||||||
<TextBox Watermark="Name" Text="{CompiledBinding ScriptName}" />
|
|
||||||
<TextBlock Classes="label" Margin="0 5">Script type</TextBlock>
|
|
||||||
<ComboBox SelectedItem="{CompiledBinding SelectedScriptingProvider}" ItemsSource="{CompiledBinding ScriptingProviders}" HorizontalAlignment="Stretch">
|
|
||||||
<ComboBox.ItemsPanel>
|
|
||||||
<ItemsPanelTemplate>
|
|
||||||
<VirtualizingStackPanel />
|
|
||||||
</ItemsPanelTemplate>
|
|
||||||
</ComboBox.ItemsPanel>
|
|
||||||
<ComboBox.ItemTemplate>
|
|
||||||
<DataTemplate x:DataType="scriptingProviders:ScriptingProvider">
|
|
||||||
<StackPanel Orientation="Horizontal">
|
|
||||||
<shared:ArtemisIcon Icon="{CompiledBinding Plugin.Info.ResolvedIcon}" Width="16" Height="16" Margin="0 0 5 0" />
|
|
||||||
<TextBlock Text="{CompiledBinding LanguageName}" />
|
|
||||||
</StackPanel>
|
|
||||||
</DataTemplate>
|
|
||||||
</ComboBox.ItemTemplate>
|
|
||||||
</ComboBox>
|
|
||||||
</StackPanel>
|
|
||||||
<TextBlock IsVisible="{CompiledBinding !ScriptingProviders.Count}">
|
|
||||||
You don't have any scripting providers installed or enabled, therefore you cannot use scripts.
|
|
||||||
</TextBlock>
|
|
||||||
</Panel>
|
|
||||||
</UserControl>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
using Avalonia.Markup.Xaml;
|
|
||||||
using Avalonia.ReactiveUI;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Scripting.Dialogs;
|
|
||||||
|
|
||||||
public partial class ScriptConfigurationCreateView : ReactiveUserControl<ScriptConfigurationCreateViewModel>
|
|
||||||
{
|
|
||||||
public ScriptConfigurationCreateView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reactive;
|
|
||||||
using Artemis.Core.ScriptingProviders;
|
|
||||||
using Artemis.Core.Services;
|
|
||||||
using Artemis.UI.Shared;
|
|
||||||
using FluentAvalonia.UI.Controls;
|
|
||||||
using PropertyChanged.SourceGenerator;
|
|
||||||
using ReactiveUI;
|
|
||||||
using ReactiveUI.Validation.Extensions;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Scripting.Dialogs;
|
|
||||||
|
|
||||||
public partial class ScriptConfigurationCreateViewModel : ContentDialogViewModelBase
|
|
||||||
{
|
|
||||||
[Notify] private string? _scriptName;
|
|
||||||
[Notify] private ScriptingProvider _selectedScriptingProvider;
|
|
||||||
|
|
||||||
public ScriptConfigurationCreateViewModel(IScriptingService scriptingService)
|
|
||||||
{
|
|
||||||
ScriptingProviders = new List<ScriptingProvider>(scriptingService.ScriptingProviders);
|
|
||||||
Submit = ReactiveCommand.Create(ExecuteSubmit, ValidationContext.Valid);
|
|
||||||
_selectedScriptingProvider = ScriptingProviders.First();
|
|
||||||
|
|
||||||
this.ValidationRule(vm => vm.ScriptName, s => !string.IsNullOrWhiteSpace(s), "Script name cannot be empty.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptConfiguration? ScriptConfiguration { get; private set; }
|
|
||||||
public List<ScriptingProvider> ScriptingProviders { get; }
|
|
||||||
public ReactiveCommand<Unit, Unit> Submit { get; }
|
|
||||||
|
|
||||||
private void ExecuteSubmit()
|
|
||||||
{
|
|
||||||
if (ScriptName == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ScriptConfiguration = new ScriptConfiguration(SelectedScriptingProvider, ScriptName, ScriptType.Profile);
|
|
||||||
ContentDialog?.Hide(ContentDialogResult.Primary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
<UserControl xmlns="https://github.com/avaloniaui"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:dialogs="clr-namespace:Artemis.UI.Screens.Scripting.Dialogs"
|
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
|
||||||
x:Class="Artemis.UI.Screens.Scripting.Dialogs.ScriptConfigurationEditView"
|
|
||||||
x:DataType="dialogs:ScriptConfigurationEditViewModel">
|
|
||||||
<TextBox Watermark="Name" Name="Input" Text="{CompiledBinding ScriptName}" />
|
|
||||||
</UserControl>
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
using Avalonia.Markup.Xaml;
|
|
||||||
using Avalonia.ReactiveUI;
|
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Scripting.Dialogs;
|
|
||||||
|
|
||||||
public partial class ScriptConfigurationEditView : ReactiveUserControl<ScriptConfigurationEditViewModel>
|
|
||||||
{
|
|
||||||
public ScriptConfigurationEditView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
this.WhenActivated(_ =>
|
|
||||||
{
|
|
||||||
Input.Focus();
|
|
||||||
Input.SelectAll();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
using System.Reactive;
|
|
||||||
using Artemis.Core.ScriptingProviders;
|
|
||||||
using Artemis.UI.Shared;
|
|
||||||
using FluentAvalonia.UI.Controls;
|
|
||||||
using PropertyChanged.SourceGenerator;
|
|
||||||
using ReactiveUI;
|
|
||||||
using ReactiveUI.Validation.Extensions;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Scripting.Dialogs;
|
|
||||||
|
|
||||||
public partial class ScriptConfigurationEditViewModel : ContentDialogViewModelBase
|
|
||||||
{
|
|
||||||
[Notify] private string? _scriptName;
|
|
||||||
|
|
||||||
public ScriptConfigurationEditViewModel(ScriptConfiguration scriptConfiguration)
|
|
||||||
{
|
|
||||||
ScriptConfiguration = scriptConfiguration;
|
|
||||||
Submit = ReactiveCommand.Create(ExecuteSubmit, ValidationContext.Valid);
|
|
||||||
ScriptName = ScriptConfiguration.Name;
|
|
||||||
|
|
||||||
this.ValidationRule(vm => vm.ScriptName, s => !string.IsNullOrWhiteSpace(s), "Script name cannot be empty.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptConfiguration ScriptConfiguration { get; }
|
|
||||||
public ReactiveCommand<Unit, Unit> Submit { get; }
|
|
||||||
|
|
||||||
private void ExecuteSubmit()
|
|
||||||
{
|
|
||||||
if (ScriptName == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ScriptConfiguration.Name = ScriptName;
|
|
||||||
ContentDialog?.Hide(ContentDialogResult.Primary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
using System.Reactive;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Artemis.Core;
|
|
||||||
using Artemis.Core.ScriptingProviders;
|
|
||||||
using Artemis.Core.Services;
|
|
||||||
using Artemis.UI.Screens.Scripting.Dialogs;
|
|
||||||
using Artemis.UI.Shared;
|
|
||||||
using Artemis.UI.Shared.Services;
|
|
||||||
using FluentAvalonia.UI.Controls;
|
|
||||||
using ReactiveUI;
|
|
||||||
using ContentDialogButton = Artemis.UI.Shared.Services.Builders.ContentDialogButton;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Scripting;
|
|
||||||
|
|
||||||
public class ScriptConfigurationViewModel : ActivatableViewModelBase
|
|
||||||
{
|
|
||||||
private readonly IScriptingService _scriptingService;
|
|
||||||
private readonly IWindowService _windowService;
|
|
||||||
|
|
||||||
public ScriptConfigurationViewModel(ScriptConfiguration scriptConfiguration, IScriptingService scriptingService, IWindowService windowService)
|
|
||||||
{
|
|
||||||
_scriptingService = scriptingService;
|
|
||||||
_windowService = windowService;
|
|
||||||
|
|
||||||
ScriptConfiguration = scriptConfiguration;
|
|
||||||
Script = ScriptConfiguration.Script;
|
|
||||||
EditScriptConfiguration = ReactiveCommand.CreateFromTask<ScriptConfiguration>(ExecuteEditScriptConfiguration);
|
|
||||||
ToggleSuspended = ReactiveCommand.Create(() => ScriptConfiguration.IsSuspended = !ScriptConfiguration.IsSuspended);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptConfigurationViewModel(Profile profile, ScriptConfiguration scriptConfiguration, IScriptingService scriptingService, IWindowService windowService)
|
|
||||||
: this(scriptConfiguration, scriptingService, windowService)
|
|
||||||
{
|
|
||||||
Profile = profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Profile? Profile { get; }
|
|
||||||
public ScriptConfiguration ScriptConfiguration { get; }
|
|
||||||
public Script? Script { get; }
|
|
||||||
public ReactiveCommand<ScriptConfiguration, Unit> EditScriptConfiguration { get; }
|
|
||||||
public ReactiveCommand<Unit, bool> ToggleSuspended { get; }
|
|
||||||
|
|
||||||
private async Task ExecuteEditScriptConfiguration(ScriptConfiguration scriptConfiguration)
|
|
||||||
{
|
|
||||||
ContentDialogResult contentDialogResult = await _windowService.CreateContentDialog()
|
|
||||||
.WithTitle("Edit script")
|
|
||||||
.WithViewModel(out ScriptConfigurationEditViewModel vm, scriptConfiguration)
|
|
||||||
.WithCloseButtonText("Cancel")
|
|
||||||
.HavingPrimaryButton(b => b.WithText("Confirm").WithCommand(vm.Submit))
|
|
||||||
.HavingSecondaryButton(b => b.WithText("Delete"))
|
|
||||||
.WithDefaultButton(ContentDialogButton.Primary)
|
|
||||||
.ShowAsync();
|
|
||||||
|
|
||||||
// Remove the script if the delete button was pressed
|
|
||||||
if (contentDialogResult == ContentDialogResult.Secondary)
|
|
||||||
{
|
|
||||||
if (Profile != null)
|
|
||||||
_scriptingService.RemoveScript(scriptConfiguration, Profile);
|
|
||||||
else
|
|
||||||
_scriptingService.RemoveScript(scriptConfiguration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
<windowing:AppWindow xmlns="https://github.com/avaloniaui"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:scripting="clr-namespace:Artemis.UI.Screens.Scripting"
|
|
||||||
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
|
||||||
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
|
||||||
xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia"
|
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
|
||||||
x:Class="Artemis.UI.Screens.Scripting.ScriptsDialogView"
|
|
||||||
x:DataType="scripting:ScriptsDialogViewModel"
|
|
||||||
Icon="/Assets/Images/Logo/application.ico"
|
|
||||||
Title="Artemis | Scripts"
|
|
||||||
Width="1200"
|
|
||||||
Height="750">
|
|
||||||
<DockPanel>
|
|
||||||
<ScrollViewer DockPanel.Dock="Left" VerticalScrollBarVisibility="Auto" Width="300" Margin="10">
|
|
||||||
<StackPanel>
|
|
||||||
<ListBox ItemsSource="{CompiledBinding ScriptConfigurations}" SelectedItem="{CompiledBinding SelectedScript}">
|
|
||||||
<ListBox.ItemTemplate>
|
|
||||||
<DataTemplate DataType="{x:Type scripting:ScriptConfigurationViewModel}">
|
|
||||||
<Grid ColumnDefinitions="Auto,*,Auto,Auto" RowDefinitions="*,*" Margin="4">
|
|
||||||
<shared:ArtemisIcon Grid.Row="0"
|
|
||||||
Grid.Column="0"
|
|
||||||
Grid.RowSpan="2"
|
|
||||||
Icon="{CompiledBinding ScriptConfiguration.Script.ScriptingProvider.Plugin.Info.ResolvedIcon, FallbackValue=QuestionMark}"
|
|
||||||
Width="32 "
|
|
||||||
Height="32"
|
|
||||||
Margin="0 0 10 0"
|
|
||||||
VerticalAlignment="Center" />
|
|
||||||
<TextBlock Grid.Row="0"
|
|
||||||
Grid.Column="1"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{CompiledBinding ScriptConfiguration.Name}"
|
|
||||||
IsVisible="{CompiledBinding !ScriptConfiguration.HasChanges}"
|
|
||||||
TextTrimming="CharacterEllipsis" />
|
|
||||||
<StackPanel Grid.Row="0"
|
|
||||||
Grid.Column="1"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Orientation="Horizontal"
|
|
||||||
IsVisible="{CompiledBinding ScriptConfiguration.HasChanges}">
|
|
||||||
<TextBlock Text="{CompiledBinding ScriptConfiguration.Name}" FontWeight="Bold"></TextBlock>
|
|
||||||
<TextBlock Text="*"></TextBlock>
|
|
||||||
</StackPanel>
|
|
||||||
<TextBlock Grid.Row="1"
|
|
||||||
Grid.Column="1"
|
|
||||||
Text="{CompiledBinding ScriptConfiguration.Script.ScriptingProvider.LanguageName, FallbackValue='Unknown scripting provider'}"
|
|
||||||
Classes="subtitle"
|
|
||||||
FontSize="11"
|
|
||||||
VerticalAlignment="Center" />
|
|
||||||
|
|
||||||
<Button Classes="icon-button icon-button-small"
|
|
||||||
Grid.Row="0"
|
|
||||||
Grid.RowSpan="2"
|
|
||||||
Grid.Column="2"
|
|
||||||
ToolTip.Tip="Edit script"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Command="{CompiledBinding EditScriptConfiguration}"
|
|
||||||
CommandParameter="{CompiledBinding ScriptConfiguration}"
|
|
||||||
Margin="0 0 2 0">
|
|
||||||
<avalonia:MaterialIcon Kind="Cog" />
|
|
||||||
</Button>
|
|
||||||
<Button Classes="icon-button icon-button-small"
|
|
||||||
Command="{CompiledBinding ToggleSuspended}"
|
|
||||||
Grid.Row="0"
|
|
||||||
Grid.RowSpan="2"
|
|
||||||
Grid.Column="3"
|
|
||||||
ToolTip.Tip="Suspend/resume script">
|
|
||||||
<Panel>
|
|
||||||
<avalonia:MaterialIcon Kind="EyeOff" IsVisible="{CompiledBinding ScriptConfiguration.IsSuspended}" />
|
|
||||||
<avalonia:MaterialIcon Kind="Eye" IsVisible="{CompiledBinding !ScriptConfiguration.IsSuspended}" />
|
|
||||||
</Panel>
|
|
||||||
</Button>
|
|
||||||
</Grid>
|
|
||||||
</DataTemplate>
|
|
||||||
</ListBox.ItemTemplate>
|
|
||||||
</ListBox>
|
|
||||||
<Button Content="Add new script"
|
|
||||||
Margin="10"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
Command="{CompiledBinding AddScriptConfiguration}" />
|
|
||||||
</StackPanel>
|
|
||||||
</ScrollViewer>
|
|
||||||
|
|
||||||
<Border DockPanel.Dock="Top" Classes="router-container" Margin="0 10 0 0">
|
|
||||||
<ContentControl Content="{CompiledBinding ScriptEditorViewModel}" />
|
|
||||||
</Border>
|
|
||||||
</DockPanel>
|
|
||||||
|
|
||||||
</windowing:AppWindow>
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using Artemis.UI.Shared;
|
|
||||||
using Avalonia;
|
|
||||||
using Avalonia.Markup.Xaml;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Scripting;
|
|
||||||
|
|
||||||
public partial class ScriptsDialogView : ReactiveAppWindow<ScriptsDialogViewModel>
|
|
||||||
{
|
|
||||||
private bool _canClose;
|
|
||||||
|
|
||||||
public ScriptsDialogView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
#if DEBUG
|
|
||||||
this.AttachDevTools();
|
|
||||||
#endif
|
|
||||||
Closing += OnClosing;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void OnClosing(object? sender, CancelEventArgs e)
|
|
||||||
{
|
|
||||||
if (_canClose)
|
|
||||||
return;
|
|
||||||
|
|
||||||
e.Cancel = true;
|
|
||||||
if (ViewModel == null || await ViewModel.CanClose())
|
|
||||||
{
|
|
||||||
_canClose = true;
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,142 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reactive;
|
|
||||||
using System.Reactive.Disposables;
|
|
||||||
using System.Reactive.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Artemis.Core;
|
|
||||||
using Artemis.Core.ScriptingProviders;
|
|
||||||
using Artemis.Core.Services;
|
|
||||||
using Artemis.UI.DryIoc.Factories;
|
|
||||||
using Artemis.UI.Screens.Scripting.Dialogs;
|
|
||||||
using Artemis.UI.Shared;
|
|
||||||
using Artemis.UI.Shared.Services;
|
|
||||||
using Artemis.UI.Shared.Services.Builders;
|
|
||||||
using DynamicData;
|
|
||||||
using DynamicData.Binding;
|
|
||||||
using PropertyChanged.SourceGenerator;
|
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Scripting;
|
|
||||||
|
|
||||||
public partial class ScriptsDialogViewModel : DialogViewModelBase<object?>
|
|
||||||
{
|
|
||||||
private readonly Dictionary<ScriptingProvider, IScriptEditorViewModel> _providerViewModels = new();
|
|
||||||
private readonly IScriptingService _scriptingService;
|
|
||||||
private readonly IWindowService _windowService;
|
|
||||||
private ObservableAsPropertyHelper<bool>? _hasScripts;
|
|
||||||
[Notify] private ReadOnlyObservableCollection<ScriptConfigurationViewModel> _scriptConfigurations;
|
|
||||||
[Notify] private IScriptEditorViewModel? _scriptEditorViewModel;
|
|
||||||
[Notify] private ScriptConfigurationViewModel? _selectedScript;
|
|
||||||
|
|
||||||
public ScriptsDialogViewModel(IScriptingService scriptingService, IWindowService windowService, IProfileService profileService, IScriptVmFactory scriptVmFactory)
|
|
||||||
{
|
|
||||||
_scriptingService = scriptingService;
|
|
||||||
_windowService = windowService;
|
|
||||||
|
|
||||||
ScriptType = ScriptType.Global;
|
|
||||||
ScriptingProviders = new List<ScriptingProvider>(scriptingService.ScriptingProviders);
|
|
||||||
|
|
||||||
AddScriptConfiguration = ReactiveCommand.CreateFromTask(ExecuteAddScriptConfiguration, Observable.Return(ScriptingProviders.Any()));
|
|
||||||
this.WhenAnyValue(vm => vm.SelectedScript).Subscribe(s => SetupScriptEditor(s?.ScriptConfiguration));
|
|
||||||
|
|
||||||
_scriptConfigurations = new ReadOnlyObservableCollection<ScriptConfigurationViewModel>(new ObservableCollection<ScriptConfigurationViewModel>());
|
|
||||||
// TODO: When not bound to a profile, base the contents of the UI on the ScriptingService
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptsDialogViewModel(Profile profile, IScriptingService scriptingService, IWindowService windowService, IProfileService profileService, IScriptVmFactory scriptVmFactory)
|
|
||||||
: this(scriptingService, windowService, profileService, scriptVmFactory)
|
|
||||||
{
|
|
||||||
ScriptType = ScriptType.Profile;
|
|
||||||
Profile = profile;
|
|
||||||
|
|
||||||
this.WhenActivated(d =>
|
|
||||||
{
|
|
||||||
_hasScripts = Profile.ScriptConfigurations.ToObservableChangeSet()
|
|
||||||
.Count()
|
|
||||||
.Select(c => c > 0)
|
|
||||||
.ToProperty(this, vm => vm.HasScripts)
|
|
||||||
.DisposeWith(d);
|
|
||||||
Profile.ScriptConfigurations.ToObservableChangeSet()
|
|
||||||
.Transform(c => scriptVmFactory.ScriptConfigurationViewModel(Profile, c))
|
|
||||||
.Bind(out ReadOnlyObservableCollection<ScriptConfigurationViewModel> scriptConfigurationViewModels)
|
|
||||||
.Subscribe()
|
|
||||||
.DisposeWith(d);
|
|
||||||
|
|
||||||
ScriptConfigurations = scriptConfigurationViewModels;
|
|
||||||
SelectedScript = ScriptConfigurations.FirstOrDefault();
|
|
||||||
Disposable.Create(() => profileService.SaveProfile(Profile, false)).DisposeWith(d);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptType ScriptType { get; }
|
|
||||||
public List<ScriptingProvider> ScriptingProviders { get; }
|
|
||||||
public Profile? Profile { get; }
|
|
||||||
public bool HasScripts => _hasScripts?.Value ?? false;
|
|
||||||
public ReactiveCommand<Unit, Unit> AddScriptConfiguration { get; }
|
|
||||||
|
|
||||||
public async Task<bool> CanClose()
|
|
||||||
{
|
|
||||||
if (!ScriptConfigurations.Any(s => s.ScriptConfiguration.HasChanges))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
bool result = await _windowService.ShowConfirmContentDialog("Discard changes", "One or more scripts still have pending changes, do you want to discard them?");
|
|
||||||
if (!result)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
foreach (ScriptConfigurationViewModel scriptConfigurationViewModel in ScriptConfigurations)
|
|
||||||
scriptConfigurationViewModel.ScriptConfiguration.DiscardPendingChanges();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void SetupScriptEditor(ScriptConfiguration? scriptConfiguration)
|
|
||||||
{
|
|
||||||
if (scriptConfiguration == null)
|
|
||||||
{
|
|
||||||
ScriptEditorViewModel = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The script is null if the provider is missing
|
|
||||||
if (scriptConfiguration.Script == null)
|
|
||||||
{
|
|
||||||
ScriptEditorViewModel = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_providerViewModels.TryGetValue(scriptConfiguration.Script.ScriptingProvider, out IScriptEditorViewModel? viewModel))
|
|
||||||
{
|
|
||||||
viewModel = scriptConfiguration.Script.ScriptingProvider.CreateScriptEditor(ScriptType);
|
|
||||||
_providerViewModels.Add(scriptConfiguration.Script.ScriptingProvider, viewModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScriptEditorViewModel = viewModel;
|
|
||||||
ScriptEditorViewModel.ChangeScript(scriptConfiguration.Script);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ExecuteAddScriptConfiguration()
|
|
||||||
{
|
|
||||||
await _windowService.CreateContentDialog()
|
|
||||||
.WithTitle("Add script")
|
|
||||||
.WithViewModel(out ScriptConfigurationCreateViewModel vm)
|
|
||||||
.WithCloseButtonText("Cancel")
|
|
||||||
.HavingPrimaryButton(b => b.WithText("Confirm").WithCommand(vm.Submit))
|
|
||||||
.WithDefaultButton(ContentDialogButton.Primary)
|
|
||||||
.ShowAsync();
|
|
||||||
|
|
||||||
if (vm.ScriptConfiguration == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Add the script to the profile and instantiate it
|
|
||||||
if (Profile != null)
|
|
||||||
_scriptingService.AddScript(vm.ScriptConfiguration, Profile);
|
|
||||||
else
|
|
||||||
_scriptingService.AddScript(vm.ScriptConfiguration);
|
|
||||||
|
|
||||||
// Select the new script
|
|
||||||
SelectedScript = ScriptConfigurations.LastOrDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -5,62 +5,62 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="AsyncImageLoader.Avalonia" Version="3.3.0" />
|
<PackageVersion Include="AsyncImageLoader.Avalonia" Version="3.3.0" />
|
||||||
<PackageVersion Include="Avalonia" Version="11.1.3" />
|
<PackageVersion Include="Avalonia" Version="11.2.0" />
|
||||||
<PackageVersion Include="Avalonia.AvaloniaEdit" Version="11.1.0" />
|
<PackageVersion Include="Avalonia.AvaloniaEdit" Version="11.1.0" />
|
||||||
<PackageVersion Include="Avalonia.Controls.ItemsRepeater" Version="11.1.3" />
|
<PackageVersion Include="Avalonia.Controls.ItemsRepeater" Version="11.1.4" />
|
||||||
<PackageVersion Include="Avalonia.Controls.PanAndZoom" Version="11.1.0.1" />
|
<PackageVersion Include="Avalonia.Controls.PanAndZoom" Version="11.2.0" />
|
||||||
<PackageVersion Include="Avalonia.Desktop" Version="11.1.3" />
|
<PackageVersion Include="Avalonia.Desktop" Version="11.2.0" />
|
||||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.9" />
|
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.9" />
|
||||||
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.1.3" />
|
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.2.0" />
|
||||||
<PackageVersion Include="Avalonia.Skia.Lottie" Version="11.0.0" />
|
<PackageVersion Include="Avalonia.Skia.Lottie" Version="11.0.0" />
|
||||||
<PackageVersion Include="Avalonia.Win32" Version="11.1.3" />
|
<PackageVersion Include="Avalonia.Win32" Version="11.2.0" />
|
||||||
<PackageVersion Include="HPPH.SkiaSharp" Version="1.0.0" />
|
<PackageVersion Include="HPPH.SkiaSharp" Version="1.0.0" />
|
||||||
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="8.0.0" />
|
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="9.0.0" />
|
||||||
<PackageVersion Include="Avalonia.Xaml.Behaviors" Version="11.1.0.4" />
|
<PackageVersion Include="Avalonia.Xaml.Behaviors" Version="11.2.0" />
|
||||||
<PackageVersion Include="AvaloniaEdit.TextMate" Version="11.1.0" />
|
<PackageVersion Include="AvaloniaEdit.TextMate" Version="11.1.0" />
|
||||||
<PackageVersion Include="DryIoc.Microsoft.DependencyInjection" Version="6.2.0" />
|
<PackageVersion Include="DryIoc.Microsoft.DependencyInjection" Version="6.2.0" />
|
||||||
<PackageVersion Include="DryIoc.dll" Version="5.4.3" />
|
<PackageVersion Include="DryIoc.dll" Version="5.4.3" />
|
||||||
<PackageVersion Include="DynamicData" Version="8.4.1" />
|
<PackageVersion Include="DynamicData" Version="9.0.4" />
|
||||||
<PackageVersion Include="EmbedIO" Version="3.5.2" />
|
<PackageVersion Include="EmbedIO" Version="3.5.2" />
|
||||||
<PackageVersion Include="FluentAvalonia.ProgressRing" Version="1.69.2" />
|
<PackageVersion Include="FluentAvalonia.ProgressRing" Version="1.69.2" />
|
||||||
<PackageVersion Include="FluentAvaloniaUI" Version="2.1.0" />
|
<PackageVersion Include="FluentAvaloniaUI" Version="2.1.0" />
|
||||||
<PackageVersion Include="HidSharp" Version="2.1.0" />
|
<PackageVersion Include="HidSharp" Version="2.1.0" />
|
||||||
<PackageVersion Include="Humanizer.Core" Version="2.14.1" />
|
<PackageVersion Include="Humanizer.Core" Version="2.14.1" />
|
||||||
<PackageVersion Include="IdentityModel" Version="7.0.0" />
|
<PackageVersion Include="IdentityModel" Version="7.0.0" />
|
||||||
<PackageVersion Include="JetBrains.Annotations" Version="2024.2.0" />
|
<PackageVersion Include="JetBrains.Annotations" Version="2024.3.0" />
|
||||||
<PackageVersion Include="LiteDB" Version="5.0.21" />
|
<PackageVersion Include="LiteDB" Version="5.0.21" />
|
||||||
<PackageVersion Include="Markdown.Avalonia.Tight" Version="11.0.2" />
|
<PackageVersion Include="Markdown.Avalonia.Tight" Version="11.0.2" />
|
||||||
<PackageVersion Include="Material.Icons.Avalonia" Version="2.1.10" />
|
<PackageVersion Include="Material.Icons.Avalonia" Version="2.1.10" />
|
||||||
<PackageVersion Include="McMaster.NETCore.Plugins" Version="1.4.0" />
|
<PackageVersion Include="McMaster.NETCore.Plugins" Version="1.4.0" />
|
||||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.2" />
|
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.2" />
|
||||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.8" />
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.0" />
|
||||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8">
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.0">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageVersion>
|
</PackageVersion>
|
||||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
<PackageVersion Include="Microsoft.Extensions.Http" Version="9.0.0" />
|
||||||
<PackageVersion Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
|
<PackageVersion Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
|
||||||
<PackageVersion Include="Microsoft.Win32" Version="2.0.1" />
|
<PackageVersion Include="Microsoft.Win32" Version="2.0.1" />
|
||||||
<PackageVersion Include="Microsoft.Windows.Compatibility" Version="8.0.8" />
|
<PackageVersion Include="Microsoft.Windows.Compatibility" Version="9.0.0" />
|
||||||
<PackageVersion Include="NoStringEvaluating" Version="2.5.2" />
|
<PackageVersion Include="NoStringEvaluating" Version="2.5.2" />
|
||||||
<PackageVersion Include="Octopus.Octodiff" Version="2.0.546" />
|
<PackageVersion Include="Octopus.Octodiff" Version="2.0.547" />
|
||||||
<PackageVersion Include="PropertyChanged.SourceGenerator" Version="1.1.0" />
|
<PackageVersion Include="PropertyChanged.SourceGenerator" Version="1.1.0" />
|
||||||
<PackageVersion Include="RGB.NET.Core" Version="3.0.0-prerelease.1 " />
|
<PackageVersion Include="RGB.NET.Core" Version="3.0.0-prerelease.3" />
|
||||||
<PackageVersion Include="RGB.NET.Layout" Version="3.0.0-prerelease.1 " />
|
<PackageVersion Include="RGB.NET.Layout" Version="3.0.0-prerelease.3" />
|
||||||
<PackageVersion Include="RGB.NET.Presets" Version="3.0.0-prerelease.1 " />
|
<PackageVersion Include="RGB.NET.Presets" Version="3.0.0-prerelease.3" />
|
||||||
<PackageVersion Include="RawInput.Sharp" Version="0.1.3" />
|
<PackageVersion Include="RawInput.Sharp" Version="0.1.3" />
|
||||||
<PackageVersion Include="ReactiveUI" Version="20.1.1" />
|
<PackageVersion Include="ReactiveUI" Version="20.1.63" />
|
||||||
<PackageVersion Include="ReactiveUI.Validation" Version="4.0.9" />
|
<PackageVersion Include="ReactiveUI.Validation" Version="4.1.1" />
|
||||||
<PackageVersion Include="Serilog" Version="4.0.1" />
|
<PackageVersion Include="Serilog" Version="4.1.0" />
|
||||||
<PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0" />
|
<PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||||
<PackageVersion Include="Serilog.Sinks.Debug" Version="3.0.0" />
|
<PackageVersion Include="Serilog.Sinks.Debug" Version="3.0.0" />
|
||||||
<PackageVersion Include="Serilog.Sinks.File" Version="6.0.0" />
|
<PackageVersion Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||||
<PackageVersion Include="SkiaSharp" Version="2.88.8" />
|
<PackageVersion Include="SkiaSharp" Version="2.88.9" />
|
||||||
<PackageVersion Include="SkiaSharp.Vulkan.SharpVk" Version="2.88.8" />
|
<PackageVersion Include="SkiaSharp.Vulkan.SharpVk" Version="2.88.9" />
|
||||||
<PackageVersion Include="Splat.DryIoc" Version="15.2.22" />
|
<PackageVersion Include="Splat.DryIoc" Version="15.2.22" />
|
||||||
<PackageVersion Include="StrawberryShake.Server" Version="13.9.12" />
|
<PackageVersion Include="StrawberryShake.Server" Version="14.1.0" />
|
||||||
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="8.0.2" />
|
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="8.2.0" />
|
||||||
<PackageVersion Include="System.Text.Json" Version="8.0.4" />
|
<PackageVersion Include="System.Text.Json" Version="9.0.0" />
|
||||||
<PackageVersion Include="TextMateSharp.Grammars" Version="1.0.63" />
|
<PackageVersion Include="TextMateSharp.Grammars" Version="1.0.64" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Loading…
x
Reference in New Issue
Block a user