/*
Copyright 2020 Katy Coe - http://www.djkaty.com - https://github.com/djkaty
All rights reserved.
*/
using System;
using System.Collections.Generic;
using System.Linq;
namespace Il2CppInspector.PluginAPI.V100
{
///
/// Interface representing a plugin option
///
public interface IPluginOption
{
///
/// Option name for CLI and unique ID
///
public string Name { get; set; }
///
/// Option description for GUI
///
public string Description { get; set; }
///
/// True if the setting is required for the plugin to function, false if optional
/// Optional by default
///
public bool Required { get; set; }
///
/// The default value of the option, if any
/// Becomes the current value of the option when supplied by the user
///
public object Value { get; set; }
}
///
/// Defines how to display lists of choices in the GUI
/// Dropdown for a dropdown box, List for a list of radio buttons
///
public enum PluginOptionChoiceStyle
{
Dropdown,
List
}
///
/// Defines how to display and parse numbers in the CLI and GUI
/// Decimal for regular numbers, Hex for hexadecimal strings
///
public enum PluginOptionNumberStyle
{
Decimal,
Hex
}
///
/// The base option from which all other options are derived
///
public abstract class PluginOption : IPluginOption
{
///
/// The name of the option as it will be supplied in an argument on the command-line
/// If you specify a single character, the single-dash syntax "-x" can be used instead of "--xxxxxx"
///
public string Name { get; set; }
///
/// A description of what the option does
///
public string Description { get; set; }
///
/// True if the option must be specified, false if optional
///
public bool Required { get; set; }
///
/// When created, the default value of the option
/// During plugin execution, the current value of the option
///
private T _value;
object IPluginOption.Value { get => Value; set => Value = (T) value; }
public T Value {
get => _value;
set {
// Perform internal validation
InternalValidate(value);
// Perform optional user-supplied validation
Validate?.Invoke(value);
// Save changes
_value = value;
}
}
///
/// Optional validation function for the option in addition to basic automatic validation
/// Must either throw an exception or return true
///
public Func Validate;
// Internal validation of each option (for internal use only)
protected abstract void InternalValidate(T value);
}
///
/// Numeric type option (for internal use only)
///
public interface IPluginOptionNumber
{
///
/// The style of the number
///
public PluginOptionNumberStyle Style { get; set; }
///
/// The value of the number
///
object Value { get; set; }
}
///
/// Option representing a text string
///
public class PluginOptionText : PluginOption
{
protected sealed override void InternalValidate(string text) {
// Don't allow required text to be empty
if (Required && string.IsNullOrWhiteSpace(text))
throw new ArgumentException("Text cannot be empty");
}
}
///
/// Option representing a file path
///
public class PluginOptionFilePath : PluginOption
{
// Don't asllow required path name to be empty
protected sealed override void InternalValidate(string path) {
if (Required && string.IsNullOrWhiteSpace(path))
throw new ArgumentException("Path name is required");
// Throws an exception if the path is invalid (file or folder may or may not exist)
System.IO.Path.GetFullPath(path ?? "");
}
}
///
/// And option representing boolean true or false (yes/no, on/off etc.)
///
public class PluginOptionBoolean : PluginOption
{
protected sealed override void InternalValidate(bool value) { }
}
///
/// Option representing a number
///
/// The type of the number
public class PluginOptionNumber : PluginOption, IPluginOptionNumber where T : struct
{
///
/// Decimal for normal numbers
/// Hex to display and parse numbers as hex in the CLI and GUI
///
public PluginOptionNumberStyle Style { get; set; }
///
/// The value of the number
///
object IPluginOptionNumber.Value { get => Value; set => Value = (T) value; }
protected sealed override void InternalValidate(T value) { }
}
///
/// Option representing a single choice from a list of choices
///
public class PluginOptionChoice : PluginOption
{
///
/// List of items to choose from
/// The Keys are the actual values and those supplied via the CLI
/// The Values are descriptions of each value shown in the GUI
///
public Dictionary Choices { get; set; }
///
/// Dropdown to display the list as a drop-down box in the GUI
/// List to display the list as a set of grouped radio buttons in the GUI
///
public PluginOptionChoiceStyle Style { get; set; }
protected sealed override void InternalValidate(T value) {
// Allow Choices to be null so that setting Value first on init doesn't throw an exception
if (!Choices?.Keys.Contains(value) ?? false)
throw new ArgumentException("Specified choice is not one of the available choices");
}
}
}