using System;
using System.Collections.Generic;
using System.Linq;
using Artemis.Core.DataModelExpansions;
using Artemis.Storage.Entities.Module;
using SkiaSharp;
namespace Artemis.Core.Modules
{
///
/// Allows you to add support for new games/applications while utilizing your own data model
///
public abstract class Module : Module where T : DataModel
{
///
/// The data model driving this module
/// Note: This default data model is automatically registered upon plugin enable
///
public T DataModel
{
get => (T) InternalDataModel;
internal set => InternalDataModel = value;
}
///
/// Gets or sets whether this module must also expand the main data model
///
/// Note: If expanding the main data model is all you want your plugin to do, create a
/// plugin instead.
///
///
public bool ExpandsDataModel
{
get => InternalExpandsMainDataModel;
set => InternalExpandsMainDataModel = value;
}
///
/// Override to provide your own data model description. By default this returns a description matching your plugin
/// name and description
///
///
public virtual DataModelPropertyAttribute GetDataModelDescription()
{
return new DataModelPropertyAttribute {Name = PluginInfo.Name, Description = PluginInfo.Description};
}
internal override void InternalEnablePlugin()
{
DataModel = Activator.CreateInstance();
DataModel.PluginInfo = PluginInfo;
DataModel.DataModelDescription = GetDataModelDescription();
base.InternalEnablePlugin();
}
internal override void InternalDisablePlugin()
{
DataModel = null;
base.InternalDisablePlugin();
}
}
///
/// Allows you to add support for new games/applications
///
public abstract class Module : Plugin
{
///
/// The modules display name that's shown in the menu
///
public string DisplayName { get; protected set; }
///
/// The modules display icon that's shown in the menu see for available
/// icons
///
public string DisplayIcon { get; set; }
///
/// A path to an image to use as the modules display icon that's shown in the menu.
/// If set, takes precedence over
///
public string DisplayIconPath { get; set; }
///
/// Gets whether this module is activated. A module can only be active while its
/// are met
///
public bool IsActivated { get; internal set; }
///
/// Gets whether this module's activation was due to an override, can only be true if is
/// true
///
public bool IsActivatedOverride { get; set; }
///
/// A list of activation requirements
/// Note: if empty the module is always activated
///
public List ActivationRequirements { get; } = new List();
///
/// Gets or sets the activation requirement mode, defaults to
///
public ActivationRequirementType ActivationRequirementMode { get; set; } = ActivationRequirementType.Any;
///
/// Gets or sets the default priority category for this module, defaults to
///
///
public ModulePriorityCategory DefaultPriorityCategory { get; set; } = ModulePriorityCategory.Normal;
///
/// Gets the current priority category of this module
///
public ModulePriorityCategory PriorityCategory { get; internal set; }
///
/// Gets the current priority of this module within its priority category
///
public int Priority { get; internal set; }
internal DataModel InternalDataModel { get; set; }
internal bool InternalExpandsMainDataModel { get; set; }
internal ModuleSettingsEntity Entity { get; set; }
///
/// A list of custom module tabs that show in the UI
///
public IEnumerable ModuleTabs { get; protected set; }
///
/// Called each frame when the module must update
///
/// Time in seconds since the last update
public abstract void Update(double deltaTime);
///
/// Called each frame when the module must render
///
/// Time since the last render
/// The RGB Surface to render to
///
///
public abstract void Render(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo);
///
/// Called when the are met or during an override
///
///
/// If true, the activation was due to an override. This usually means the module was activated
/// by the profile editor
///
public abstract void ModuleActivated(bool isOverride);
///
/// Called when the are no longer met or during an override
///
///
/// If true, the deactivation was due to an override. This usually means the module was deactivated
/// by the profile editor
///
public abstract void ModuleDeactivated(bool isOverride);
internal virtual void InternalUpdate(double deltaTime)
{
Update(deltaTime);
}
internal virtual void InternalRender(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo)
{
Render(deltaTime, surface, canvas, canvasInfo);
}
///
/// Evaluates the activation requirements following the and returns the result
///
/// The evaluated result of the activation requirements
public bool EvaluateActivationRequirements()
{
if (!ActivationRequirements.Any())
return true;
if (ActivationRequirementMode == ActivationRequirementType.All)
return ActivationRequirements.All(r => r.Evaluate());
if (ActivationRequirementMode == ActivationRequirementType.Any)
return ActivationRequirements.Any(r => r.Evaluate());
return false;
}
internal virtual void Activate(bool isOverride)
{
if (IsActivated)
return;
IsActivatedOverride = isOverride;
ModuleActivated(isOverride);
IsActivated = true;
}
internal virtual void Deactivate(bool isOverride)
{
if (!IsActivated)
return;
IsActivatedOverride = false;
IsActivated = false;
ModuleDeactivated(isOverride);
}
internal void ApplyToEntity()
{
if (Entity == null)
Entity = new ModuleSettingsEntity();
Entity.PluginGuid = PluginInfo.Guid;
Entity.PriorityCategory = (int) PriorityCategory;
Entity.Priority = Priority;
}
}
///
/// Describes in what way the activation requirements of a module must be met
///
public enum ActivationRequirementType
{
///
/// Any activation requirement must be met for the module to activate
///
Any,
///
/// All activation requirements must be met for the module to activate
///
All
}
///
/// Describes the priority category of a module
///
public enum ModulePriorityCategory
{
///
/// Indicates a normal render priority
///
Normal,
///
/// Indicates that the module renders for a specific application/game, rendering on top of normal modules
///
Application,
///
/// Indicates that the module renders an overlay, always rendering on top
///
Overlay
}
}