using System;
using UnityEngine.InputSystem.Composites;
using UnityEngine.InputSystem.LowLevel;
namespace UnityEngine.InputSystem.Layouts
{
///
/// Mark a field or property as representing/identifying an input control in some form.
///
///
/// This attribute is used in different places for different purposes.
///
/// When creating input control layouts () in C#, applying the
/// attribute to fields in a state struct (see or
/// for an example) or to properties in an input device (), will cause an
/// to be created from the field or property at runtime. The attribute
/// can be applied multiple times to create multiple input controls (e.g. when having an int field
/// that represents a bitfield where each bit is a separate button).
///
///
///
/// public class MyDevice : InputDevice
/// {
/// // Adds an InputControl with name=myButton and layout=Button to the device.
/// [InputControl]
/// public ButtonControl myButton { get; set; }
/// }
///
///
///
/// Another use is for marking string type fields that represent input control paths. Applying
/// the attribute to them will cause them to automatically use a custom inspector similar to the one
/// found in the action editor. For this use, only the property is taken into
/// account.
///
///
///
/// public class MyBehavior : MonoBehaviour
/// {
/// // In the inspector, shows a control selector that is restricted to
/// // selecting buttons. As a result, controlPath will be set to path
/// // representing the control that was picked (e.g. "<Gamepad>/buttonSouth").
/// [InputControl(layout = "Button")]
/// public string controlPath;
///
/// protected void OnEnable()
/// {
/// // Find controls by path.
/// var controls = InputSystem.FindControl(controlPath);
/// //...
/// }
/// }
///
///
///
/// Finally, the attribute is also used in composite bindings ()
/// to mark fields that reference parts of the composite. An example for this is .
/// In this use, also only the property is taken into account while other properties
/// are ignored.
///
///
///
/// public class MyComposite : InputBindingComposite<float>
/// {
/// // Add a part to the composite called 'firstControl' which expects
/// // AxisControls.
/// [InputControl(layout = "Axis")]
/// public int firstControl;
///
/// // Add a part to the composite called 'secondControl' which expects
/// // Vector3Controls.
/// [InputControl(layout = "Vector3")]
/// public int secondControl;
///
/// //...
/// }
///
///
///
///
///
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]
public sealed class InputControlAttribute : PropertyAttribute
{
///
/// Layout to use for the control.
///
/// Layout to use for the control.
///
/// If this is not set, the system tries to infer the layout type from the value type of
/// the field or property. If the value type is itself registered as a layout, that layout
/// will be used (e.g. when you have a property of type , the layout
/// will be inferred to be "Button"). Otherwise, if a layout with the same name as the type is registered,
/// that layout will be used (e.g. when you have a field of type , the layout
/// will be inferred to be "Vector3").
///
///
public string layout { get; set; }
///
/// Layout variant to use for the control.
///
/// Layout variant to use for the control.
public string variants { get; set; }
///
/// Name to give to the name. If null or empty, the name of the property or
/// field the attribute is applied to will be used.
///
/// Name to give to the control.
///
public string name { get; set; }
///
/// Storage format to use for the control. If not set, default storage format
/// for the given is used.
///
/// Memory storage format to use for the control.
///
public string format { get; set; }
///
/// Usage to apply to the control.
///
/// Usage for the control.
///
/// This property can be used in place of to set just a single
/// usage on the control.
///
///
///
///
public string usage { get; set; }
///
/// Usages to apply to the control.
///
/// Usages for the control.
///
/// This property should be used instead of when a control has multiple usages.
///
///
///
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "According to MSDN, this message can be ignored for attribute parameters, as there are no better alternatives.")]
public string[] usages { get; set; }
///
/// Optional list of parameters to apply to the control.
///
/// Parameters to apply to the control.
///
/// An may expose public fields which can be set as
/// parameters. An example of this is .
///
///
///
/// public struct MyStateStruct : IInputStateTypeInfo
/// {
/// [InputControl(parameters = "clamp,clampMin=-0.5,clampMax=0.5")]
/// public float axis;
/// }
///
///
///
///
public string parameters { get; set; }
///
/// Optional list of processors to add to the control.
///
/// Processors to apply to the control.
///
/// Each element in the list is a name of a processor (as registered with
/// ) followed by an optional
/// list of parameters.
///
/// For example, "normalize(min=0,max=256)" is one element that puts
/// a NormalizeProcessor on the control and sets its min field
/// to 0 and its its max field to 256.
///
/// Multiple processors can be put on a control by separating them with a comma.
/// For example, "normalize(max=256),scale(factor=2)" puts both a NormalizeProcessor
/// and a ScaleProcessor on the control. Processors are applied in the
/// order they are listed.
///
///
///
public string processors { get; set; }
///
/// An alternative name that can be used in place of to find
/// the control.
///
/// Alternative name for the control.
///
/// This property can be used instead of when there is only a
/// single alias for the control.
///
/// Aliases, like names, are case-insensitive. Any control may have arbitrary many
/// aliases.
///
///
///
public string alias { get; set; }
///
/// A list of alternative names that can be used in place of to
/// find the control.
///
/// Alternative names for the control.
///
/// This property should be used instead of when a control has
/// multiple aliases.
///
/// Aliases, like names, are case-insensitive. Any control may have arbitrary many
/// aliases.
///
///
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "According to MSDN, this message can be ignored for attribute parameters, as there are no better alternatives.")]
public string[] aliases { get; set; }
public string useStateFrom { get; set; }
public uint bit { get; set; } = InputStateBlock.InvalidOffset;
///
/// Offset in bytes to where the memory of the control starts. Relative to
/// the offset of the parent control (which may be the device itself).
///
/// Byte offset of the control.
///
/// If the attribute is applied to fields in an and
/// this property is not set, the offset of the field is used instead.
///
///
///
/// public struct MyStateStruct : IInputStateTypeInfo
/// {
/// public int buttons;
///
/// [InputControl] // Automatically uses the offset of 'axis'.
/// public float axis;
/// }
///
/// [InputControlLayout(stateType = typeof(MyStateStruct))]
/// public class MyDevice : InputDevice
/// {
/// }
///
///
///
///
public uint offset { get; set; } = InputStateBlock.InvalidOffset;
///
/// Size of the memory storage for the control in bits.
///
/// Size of the control in bits.
///
/// If the attribute is applied to fields in an and
/// this property is not set, the size is taken from the field.
///
///
///
/// public struct MyStateStruct : IInputStateTypeInfo
/// {
/// public int buttons;
///
/// [InputControl] // Automatically uses sizeof(float).
/// public float axis;
/// }
///
/// [InputControlLayout(stateType = typeof(MyStateStruct))]
/// public class MyDevice : InputDevice
/// {
/// }
///
///
///
///
///
public uint sizeInBits { get; set; }
public int arraySize { get; set; }
///
/// Display name to assign to the control.
///
/// Display name for the control.
///
///
public string displayName { get; set; }
///
/// Short display name to assign to the control.
///
/// Short display name for the control.
///
///
public string shortDisplayName { get; set; }
///
/// Whether the control is noisy. Off by default.
///
/// Whether control is noisy.
///
///
public bool noisy { get; set; }
///
/// Whether the control is synthetic. Off by default.
///
/// Whether control is synthetic.
///
///
public bool synthetic { get; set; }
///
/// Allows you to specify that a control should not be reset when its device is reset.
///
/// If true, resets of the device will leave the value of the control untouched except if a "hard" reset
/// is explicitly enforced.
///
///
public bool dontReset { get; set; }
///
/// Default state to write into the control's memory.
///
/// Default memory state for the control.
///
/// This is not the default value but rather the default memory state, i.e.
/// the raw memory value read and the processed and returned as a value. By default
/// this is null and result in a control's memory to be initialized with all
/// zeroes.
///
///
public object defaultState { get; set; }
///
/// Lower limit for values of the control.
///
/// Lower limit for values of the control.
///
/// This is null by default in which case no lower bound is applied to the TODO
///
public object minValue { get; set; }
public object maxValue { get; set; }
}
}