A game about forced loneliness, made by TACStudios
1using System;
2using UnityEngine.InputSystem.Composites;
3using UnityEngine.InputSystem.LowLevel;
4
5namespace UnityEngine.InputSystem.Layouts
6{
7 /// <summary>
8 /// Mark a field or property as representing/identifying an input control in some form.
9 /// </summary>
10 /// <remarks>
11 /// This attribute is used in different places for different purposes.
12 ///
13 /// When creating input control layouts (<see cref="InputControlLayout"/>) in C#, applying the
14 /// attribute to fields in a state struct (see <see cref="IInputStateTypeInfo"/> or <see cref="GamepadState"/>
15 /// for an example) or to properties in an input device (<see cref="InputDevice"/>), will cause an
16 /// <see cref="InputControl"/> to be created from the field or property at runtime. The attribute
17 /// can be applied multiple times to create multiple input controls (e.g. when having an int field
18 /// that represents a bitfield where each bit is a separate button).
19 ///
20 /// <example>
21 /// <code>
22 /// public class MyDevice : InputDevice
23 /// {
24 /// // Adds an InputControl with name=myButton and layout=Button to the device.
25 /// [InputControl]
26 /// public ButtonControl myButton { get; set; }
27 /// }
28 /// </code>
29 /// </example>
30 ///
31 /// Another use is for marking <c>string</c> type fields that represent input control paths. Applying
32 /// the attribute to them will cause them to automatically use a custom inspector similar to the one
33 /// found in the action editor. For this use, only the <see cref="layout"/> property is taken into
34 /// account.
35 ///
36 /// <example>
37 /// <code>
38 /// public class MyBehavior : MonoBehaviour
39 /// {
40 /// // In the inspector, shows a control selector that is restricted to
41 /// // selecting buttons. As a result, controlPath will be set to path
42 /// // representing the control that was picked (e.g. "<Gamepad>/buttonSouth").
43 /// [InputControl(layout = "Button")]
44 /// public string controlPath;
45 ///
46 /// protected void OnEnable()
47 /// {
48 /// // Find controls by path.
49 /// var controls = InputSystem.FindControl(controlPath);
50 /// //...
51 /// }
52 /// }
53 /// </code>
54 /// </example>
55 ///
56 /// Finally, the attribute is also used in composite bindings (<see cref="InputBindingComposite"/>)
57 /// to mark fields that reference parts of the composite. An example for this is <see cref="AxisComposite.negative"/>.
58 /// In this use, also only the <see cref="layout"/> property is taken into account while other properties
59 /// are ignored.
60 ///
61 /// <example>
62 /// <code>
63 /// public class MyComposite : InputBindingComposite<float>
64 /// {
65 /// // Add a part to the composite called 'firstControl' which expects
66 /// // AxisControls.
67 /// [InputControl(layout = "Axis")]
68 /// public int firstControl;
69 ///
70 /// // Add a part to the composite called 'secondControl' which expects
71 /// // Vector3Controls.
72 /// [InputControl(layout = "Vector3")]
73 /// public int secondControl;
74 ///
75 /// //...
76 /// }
77 /// </code>
78 /// </example>
79 /// </remarks>
80 /// <seealso cref="InputControlLayout"/>
81 /// <seealso cref="InputBindingComposite"/>
82 [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]
83 public sealed class InputControlAttribute : PropertyAttribute
84 {
85 /// <summary>
86 /// Layout to use for the control.
87 /// </summary>
88 /// <value>Layout to use for the control.</value>
89 /// <remarks>
90 /// If this is not set, the system tries to infer the layout type from the value type of
91 /// the field or property. If the value type is itself registered as a layout, that layout
92 /// will be used (e.g. when you have a property of type <see cref="Controls.ButtonControl"/>, the layout
93 /// will be inferred to be "Button"). Otherwise, if a layout with the same name as the type is registered,
94 /// that layout will be used (e.g. when you have a field of type <see cref="Vector3"/>, the layout
95 /// will be inferred to be "Vector3").
96 /// </remarks>
97 /// <seealso cref="InputControlLayout"/>
98 public string layout { get; set; }
99
100 /// <summary>
101 /// Layout variant to use for the control.
102 /// </summary>
103 /// <value>Layout variant to use for the control.</value>
104 public string variants { get; set; }
105
106 /// <summary>
107 /// Name to give to the name. If null or empty, the name of the property or
108 /// field the attribute is applied to will be used.
109 /// </summary>
110 /// <value>Name to give to the control.</value>
111 /// <seealso cref="InputControl.name"/>
112 public string name { get; set; }
113
114 /// <summary>
115 /// Storage format to use for the control. If not set, default storage format
116 /// for the given <see cref="layout"/> is used.
117 /// </summary>
118 /// <value>Memory storage format to use for the control.</value>
119 /// <seealso cref="InputStateBlock.format"/>
120 public string format { get; set; }
121
122 /// <summary>
123 /// Usage to apply to the control.
124 /// </summary>
125 /// <value>Usage for the control.</value>
126 /// <remarks>
127 /// This property can be used in place of <see cref="usages"/> to set just a single
128 /// usage on the control.
129 /// </remarks>
130 /// <seealso cref="InputControl.usages"/>
131 /// <seealso cref="InputControlLayout.ControlItem.usages"/>
132 /// <seealso cref="CommonUsages"/>
133 public string usage { get; set; }
134
135 /// <summary>
136 /// Usages to apply to the control.
137 /// </summary>
138 /// <value>Usages for the control.</value>
139 /// <remarks>
140 /// This property should be used instead of <see cref="usage"/> when a control has multiple usages.
141 /// </remarks>
142 /// <seealso cref="InputControl.usages"/>
143 /// <seealso cref="InputControlLayout.ControlItem.usages"/>
144 /// <seealso cref="CommonUsages"/>
145 [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.")]
146 public string[] usages { get; set; }
147
148 /// <summary>
149 /// Optional list of parameters to apply to the control.
150 /// </summary>
151 /// <value>Parameters to apply to the control.</value>
152 /// <remarks>
153 /// An <see cref="InputControl"/> may expose public fields which can be set as
154 /// parameters. An example of this is <see cref="Controls.AxisControl.clamp"/>.
155 ///
156 /// <example>
157 /// <code>
158 /// public struct MyStateStruct : IInputStateTypeInfo
159 /// {
160 /// [InputControl(parameters = "clamp,clampMin=-0.5,clampMax=0.5")]
161 /// public float axis;
162 /// }
163 /// </code>
164 /// </example>
165 /// </remarks>
166 /// <seealso cref="InputControlLayout.ControlItem.parameters"/>
167 public string parameters { get; set; }
168
169 /// <summary>
170 /// Optional list of processors to add to the control.
171 /// </summary>
172 /// <value>Processors to apply to the control.</value>
173 /// <remarks>
174 /// Each element in the list is a name of a processor (as registered with
175 /// <see cref="InputSystem.RegisterProcessor{T}"/>) followed by an optional
176 /// list of parameters.
177 ///
178 /// For example, <c>"normalize(min=0,max=256)"</c> is one element that puts
179 /// a <c>NormalizeProcessor</c> on the control and sets its <c>min</c> field
180 /// to 0 and its its <c>max</c> field to 256.
181 ///
182 /// Multiple processors can be put on a control by separating them with a comma.
183 /// For example, <c>"normalize(max=256),scale(factor=2)"</c> puts both a <c>NormalizeProcessor</c>
184 /// and a <c>ScaleProcessor</c> on the control. Processors are applied in the
185 /// order they are listed.
186 /// </remarks>
187 /// <seealso cref="InputControlLayout.ControlItem.processors"/>
188 /// <seealso cref="InputBinding.processors"/>
189 public string processors { get; set; }
190
191 /// <summary>
192 /// An alternative name that can be used in place of <see cref="name"/> to find
193 /// the control.
194 /// </summary>
195 /// <value>Alternative name for the control.</value>
196 /// <remarks>
197 /// This property can be used instead of <see cref="aliases"/> when there is only a
198 /// single alias for the control.
199 ///
200 /// Aliases, like names, are case-insensitive. Any control may have arbitrary many
201 /// aliases.
202 /// </remarks>
203 /// <seealso cref="InputControl.aliases"/>
204 /// <seealso cref="InputControlLayout.ControlItem.aliases"/>
205 public string alias { get; set; }
206
207 /// <summary>
208 /// A list of alternative names that can be used in place of <see cref="name"/> to
209 /// find the control.
210 /// </summary>
211 /// <value>Alternative names for the control.</value>
212 /// <remarks>
213 /// This property should be used instead of <see cref="alias"/> when a control has
214 /// multiple aliases.
215 ///
216 /// Aliases, like names, are case-insensitive. Any control may have arbitrary many
217 /// aliases.
218 /// </remarks>
219 /// <seealso cref="InputControl.aliases"/>
220 /// <seealso cref="InputControlLayout.ControlItem.aliases"/>
221 [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.")]
222 public string[] aliases { get; set; }
223
224 public string useStateFrom { get; set; }
225
226 public uint bit { get; set; } = InputStateBlock.InvalidOffset;
227
228 /// <summary>
229 /// Offset in bytes to where the memory of the control starts. Relative to
230 /// the offset of the parent control (which may be the device itself).
231 /// </summary>
232 /// <value>Byte offset of the control.</value>
233 /// <remarks>
234 /// If the attribute is applied to fields in an <see cref="InputControlLayout"/> and
235 /// this property is not set, the offset of the field is used instead.
236 ///
237 /// <example>
238 /// <code>
239 /// public struct MyStateStruct : IInputStateTypeInfo
240 /// {
241 /// public int buttons;
242 ///
243 /// [InputControl] // Automatically uses the offset of 'axis'.
244 /// public float axis;
245 /// }
246 ///
247 /// [InputControlLayout(stateType = typeof(MyStateStruct))]
248 /// public class MyDevice : InputDevice
249 /// {
250 /// }
251 /// </code>
252 /// </example>
253 /// </remarks>
254 /// <seealso cref="InputControlLayout.ControlItem.offset"/>
255 public uint offset { get; set; } = InputStateBlock.InvalidOffset;
256
257 /// <summary>
258 /// Size of the memory storage for the control in bits.
259 /// </summary>
260 /// <value>Size of the control in bits.</value>
261 /// <remarks>
262 /// If the attribute is applied to fields in an <see cref="InputControlLayout"/> and
263 /// this property is not set, the size is taken from the field.
264 ///
265 /// <example>
266 /// <code>
267 /// public struct MyStateStruct : IInputStateTypeInfo
268 /// {
269 /// public int buttons;
270 ///
271 /// [InputControl] // Automatically uses sizeof(float).
272 /// public float axis;
273 /// }
274 ///
275 /// [InputControlLayout(stateType = typeof(MyStateStruct))]
276 /// public class MyDevice : InputDevice
277 /// {
278 /// }
279 /// </code>
280 /// </example>
281 /// </remarks>
282 /// <seealso cref="InputControlLayout.ControlItem.sizeInBits"/>
283 /// <seealso cref="InputStateBlock.sizeInBits"/>
284 public uint sizeInBits { get; set; }
285
286 public int arraySize { get; set; }
287
288 /// <summary>
289 /// Display name to assign to the control.
290 /// </summary>
291 /// <value>Display name for the control.</value>
292 /// <seealso cref="InputControl.displayName"/>
293 /// <seealso cref="InputControlLayout.ControlItem.displayName"/>
294 public string displayName { get; set; }
295
296 /// <summary>
297 /// Short display name to assign to the control.
298 /// </summary>
299 /// <value>Short display name for the control.</value>
300 /// <seealso cref="InputControl.shortDisplayName"/>
301 /// <seealso cref="InputControlLayout.ControlItem.shortDisplayName"/>
302 public string shortDisplayName { get; set; }
303
304 /// <summary>
305 /// Whether the control is noisy. Off by default.
306 /// </summary>
307 /// <value>Whether control is noisy.</value>
308 /// <seealso cref="InputControl.noisy"/>
309 /// <seealso cref="InputControlLayout.ControlItem.isNoisy"/>
310 public bool noisy { get; set; }
311
312 /// <summary>
313 /// Whether the control is synthetic. Off by default.
314 /// </summary>
315 /// <value>Whether control is synthetic.</value>
316 /// <seealso cref="InputControl.synthetic"/>
317 /// <seealso cref="InputControlLayout.ControlItem.isSynthetic"/>
318 public bool synthetic { get; set; }
319
320 /// <summary>
321 /// Allows you to specify that a control should not be reset when its device is reset.
322 /// </summary>
323 /// <value>If true, resets of the device will leave the value of the control untouched except if a "hard" reset
324 /// is explicitly enforced.</value>
325 /// <seealso cref="InputSystem.ResetDevice"/>
326 /// <seealso cref="InputControlLayout.ControlItem.dontReset"/>
327 public bool dontReset { get; set; }
328
329 /// <summary>
330 /// Default state to write into the control's memory.
331 /// </summary>
332 /// <value>Default memory state for the control.</value>
333 /// <remarks>
334 /// This is not the default <em>value</em> but rather the default memory state, i.e.
335 /// the raw memory value read and the processed and returned as a value. By default
336 /// this is <c>null</c> and result in a control's memory to be initialized with all
337 /// zeroes.
338 /// </remarks>
339 /// <seealso cref="InputControlLayout.ControlItem.defaultState"/>
340 public object defaultState { get; set; }
341
342 /// <summary>
343 /// Lower limit for values of the control.
344 /// </summary>
345 /// <value>Lower limit for values of the control.</value>
346 /// <remarks>
347 /// This is null by default in which case no lower bound is applied to the TODO
348 /// </remarks>
349 public object minValue { get; set; }
350 public object maxValue { get; set; }
351 }
352}