using System; using Artemis.Core.Services; using SkiaSharp; using Stylet; namespace Artemis.Core.LayerEffects { /// /// For internal use only, please use instead /// public abstract class BaseLayerEffect : PropertyChangedBase, IDisposable { private LayerEffectConfigurationDialog _configurationDialog; private LayerEffectDescriptor _descriptor; private bool _enabled; private Guid _entityId; private bool _hasBeenRenamed; private string _name; private int _order; private RenderProfileElement _profileElement; /// /// Gets the unique ID of this effect /// public Guid EntityId { get => _entityId; internal set => SetAndNotify(ref _entityId, value); } /// /// Gets the profile element (such as layer or folder) this effect is applied to /// public RenderProfileElement ProfileElement { get => _profileElement; internal set => SetAndNotify(ref _profileElement, value); } /// /// The name which appears in the editor /// public string Name { get => _name; set => SetAndNotify(ref _name, value); } /// /// Gets or sets the enabled state, if not enabled the effect is skipped in render and update /// public bool Enabled { get => _enabled; set => SetAndNotify(ref _enabled, value); } /// /// Gets or sets whether the effect has been renamed by the user, if true consider refraining from changing the name /// programatically /// public bool HasBeenRenamed { get => _hasBeenRenamed; set => SetAndNotify(ref _hasBeenRenamed, value); } /// /// Gets the order in which this effect appears in the update loop and editor /// public int Order { get => _order; set => SetAndNotify(ref _order, value); } /// /// Gets the that registered this effect /// public LayerEffectDescriptor Descriptor { get => _descriptor; internal set => SetAndNotify(ref _descriptor, value); } /// /// Gets or sets a configuration dialog complementing the regular properties /// public LayerEffectConfigurationDialog ConfigurationDialog { get => _configurationDialog; protected set => SetAndNotify(ref _configurationDialog, value); } /// /// Gets the plugin info that defined this effect /// public PluginInfo PluginInfo => Descriptor.LayerEffectProvider?.PluginInfo; /// /// Gets a reference to the layer property group without knowing it's type /// public virtual LayerPropertyGroup BaseProperties => null; internal string PropertyRootPath => $"LayerEffect.{EntityId}.{GetType().Name}."; /// public void Dispose() { DisableLayerEffect(); BaseProperties?.Dispose(); } /// /// Called when the layer effect is activated /// public abstract void EnableLayerEffect(); /// /// Called when the layer effect is deactivated /// public abstract void DisableLayerEffect(); /// /// Called before rendering every frame, write your update logic here /// /// public abstract void Update(double deltaTime); /// /// Called before the layer or folder will be rendered /// /// The canvas used to render the frame /// Info on the canvas size and pixel type /// The bounds this layer/folder will render in /// The paint this layer/folder will use to render public abstract void PreProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath renderBounds, SKPaint paint); /// /// Called after the layer of folder has been rendered /// /// The canvas used to render the frame /// Info on the canvas size and pixel type /// The bounds this layer/folder rendered in /// The paint this layer/folder used to render public abstract void PostProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath renderBounds, SKPaint paint); // Not only is this needed to initialize properties on the layer effects, it also prevents implementing anything // but LayerEffect outside the core internal abstract void Initialize(); internal virtual string GetEffectTypeName() => GetType().Name; } }