Skip to content

Commit febf538

Browse files
committed
DOCS: Added auto-generated docs for auto-generated code.
1 parent 08349cc commit febf538

File tree

1 file changed

+168
-2
lines changed

1 file changed

+168
-2
lines changed

Packages/com.unity.inputsystem/InputSystem/Editor/AssetImporter/InputActionCodeGenerator.cs

Lines changed: 168 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#if UNITY_EDITOR
22
using System;
3+
using System.Collections;
34
using System.IO;
45
using System.Linq;
56
using System.Text;
@@ -41,6 +42,54 @@ public static class InputActionCodeGenerator
4142
{
4243
private const int kSpacesPerIndentLevel = 4;
4344

45+
private const string kClassExample = @"using namespace UnityEngine;
46+
using UnityEngine.InputSystem;
47+
48+
// Example of using an InputActionMap named ""Player"" from a MonoBehavior implementing callback interface.
49+
public class Example : MonoBehaviour, MyActions.IPlayerActions
50+
{
51+
private MyActions_Actions m_Actions; // Source code representation of asset.
52+
private MyActions_Actions.PlayerActions m_Player; // Source code representation of action map.
53+
54+
void Awake()
55+
{
56+
m_Actions = new MyActions_Actions(); // Create asset object.
57+
m_Player = m_Actions.Player; // Extract action map object.
58+
m_Player.AddCallbacks(this); // Register callback interface IPlayerActions.
59+
}
60+
61+
void OnDestroy()
62+
{
63+
m_Actions.Dispose(); // Destroy asset object.
64+
}
65+
66+
void OnEnable()
67+
{
68+
m_Player.Enable(); // Enable all actions within map.
69+
}
70+
71+
void OnDisable()
72+
{
73+
m_Player.Disable(); // Disable all actions within map.
74+
}
75+
76+
#region Interface implementation of MyActions.IPlayerActions
77+
78+
// Invoked when ""Move"" action is either started, performed or canceled.
79+
public void OnMove(InputAction.CallbackContext context)
80+
{
81+
Debug.Log($""OnMove: {context.ReadValue<Vector2>()}"");
82+
}
83+
84+
// Invoked when ""Attack"" action is either started, performed or canceled.
85+
public void OnAttack(InputAction.CallbackContext context)
86+
{
87+
Debug.Log($""OnAttack: {context.ReadValue<float>()}"");
88+
}
89+
90+
#endregion
91+
}";
92+
4493
public struct Options
4594
{
4695
public string className { get; set; }
@@ -94,12 +143,22 @@ public static string GenerateWrapperCode(InputActionAsset asset, Options options
94143
}
95144

96145
// Begin class.
146+
writer.DocSummary($"Provides programmatic access to <see cref=\"InputActionAsset\" />, " +
147+
"<see cref=\"InputActionMap\" />, <see cref=\"InputAction\" /> and " +
148+
"<see cref=\"InputControlScheme\" /> instances defined " +
149+
$"in asset \"{options.sourceAssetPath}\".");
150+
writer.DocRemarks("This class is source generated and any manual edits will be discarded if the associated asset is reimported or modified.");
151+
writer.DocExample(kClassExample);
152+
97153
writer.WriteLine($"public partial class @{options.className}: IInputActionCollection2, IDisposable");
98154
writer.BeginBlock();
99155

156+
writer.DocSummary("Provides access to the underlying asset instance.");
100157
writer.WriteLine($"public InputActionAsset asset {{ get; }}");
158+
writer.WriteLine();
101159

102160
// Default constructor.
161+
writer.DocSummary("Constructs a new instance.");
103162
writer.WriteLine($"public @{options.className}()");
104163
writer.BeginBlock();
105164
writer.WriteLine($"asset = InputActionAsset.FromJson(@\"{asset.ToJson().Replace("\"", "\"\"")}\");");
@@ -131,74 +190,88 @@ public static string GenerateWrapperCode(InputActionAsset asset, Options options
131190
writer.EndBlock();
132191
writer.WriteLine();
133192

193+
writer.DocSummary("Destroys this asset and all associated <see cref=\"InputAction\"/> instances.");
134194
writer.WriteLine("public void Dispose()");
135195
writer.BeginBlock();
136196
writer.WriteLine("UnityEngine.Object.Destroy(asset);");
137197
writer.EndBlock();
138198
writer.WriteLine();
139199

200+
var classNamePrefix = typeof(InputActionAsset).Namespace + "." + nameof(InputActionAsset) + ".";
201+
writer.DocInherit(classNamePrefix + nameof(InputActionAsset.bindingMask));
140202
writer.WriteLine("public InputBinding? bindingMask");
141203
writer.BeginBlock();
142204
writer.WriteLine("get => asset.bindingMask;");
143205
writer.WriteLine("set => asset.bindingMask = value;");
144206
writer.EndBlock();
145207
writer.WriteLine();
146208

209+
writer.DocInherit(classNamePrefix + nameof(InputActionAsset.devices));
147210
writer.WriteLine("public ReadOnlyArray<InputDevice>? devices");
148211
writer.BeginBlock();
149212
writer.WriteLine("get => asset.devices;");
150213
writer.WriteLine("set => asset.devices = value;");
151214
writer.EndBlock();
152215
writer.WriteLine();
153216

217+
writer.DocInherit(classNamePrefix + nameof(InputActionAsset.controlSchemes));
154218
writer.WriteLine("public ReadOnlyArray<InputControlScheme> controlSchemes => asset.controlSchemes;");
155219
writer.WriteLine();
156220

221+
writer.DocInherit(classNamePrefix + nameof(InputActionAsset.Contains) + "(InputAction)");
157222
writer.WriteLine("public bool Contains(InputAction action)");
158223
writer.BeginBlock();
159224
writer.WriteLine("return asset.Contains(action);");
160225
writer.EndBlock();
161226
writer.WriteLine();
162227

228+
writer.DocInherit(classNamePrefix + nameof(InputActionAsset.GetEnumerator) + "()");
163229
writer.WriteLine("public IEnumerator<InputAction> GetEnumerator()");
164230
writer.BeginBlock();
165231
writer.WriteLine("return asset.GetEnumerator();");
166232
writer.EndBlock();
167233
writer.WriteLine();
168234

235+
writer.DocInherit(nameof(IEnumerable) + "." + nameof(IEnumerable.GetEnumerator) + "()");
169236
writer.WriteLine("IEnumerator IEnumerable.GetEnumerator()");
170237
writer.BeginBlock();
171238
writer.WriteLine("return GetEnumerator();");
172239
writer.EndBlock();
173240
writer.WriteLine();
174241

242+
writer.DocInherit(classNamePrefix + nameof(InputActionAsset.Enable) + "()");
175243
writer.WriteLine("public void Enable()");
176244
writer.BeginBlock();
177245
writer.WriteLine("asset.Enable();");
178246
writer.EndBlock();
179247
writer.WriteLine();
180248

249+
writer.DocInherit(classNamePrefix + nameof(InputActionAsset.Disable) + "()");
181250
writer.WriteLine("public void Disable()");
182251
writer.BeginBlock();
183252
writer.WriteLine("asset.Disable();");
184253
writer.EndBlock();
185254
writer.WriteLine();
186255

256+
writer.DocInherit(classNamePrefix + nameof(InputActionAsset.bindings));
187257
writer.WriteLine("public IEnumerable<InputBinding> bindings => asset.bindings;");
188258
writer.WriteLine();
189259

260+
writer.DocInherit(classNamePrefix + nameof(InputActionAsset.FindAction) + "(string, bool)");
190261
writer.WriteLine("public InputAction FindAction(string actionNameOrId, bool throwIfNotFound = false)");
191262
writer.BeginBlock();
192263
writer.WriteLine("return asset.FindAction(actionNameOrId, throwIfNotFound);");
193264
writer.EndBlock();
194265
writer.WriteLine();
195266

267+
writer.DocInherit(classNamePrefix + nameof(InputActionAsset.FindBinding) + "(InputBinding, out InputAction)");
196268
writer.WriteLine("public int FindBinding(InputBinding bindingMask, out InputAction action)");
197269
writer.BeginBlock();
198270
writer.WriteLine("return asset.FindBinding(bindingMask, out action);");
199271
writer.EndBlock();
200272

201273
// Action map accessors.
274+
var inputActionMapClassPrefix = typeof(InputActionMap).Namespace + "." + nameof(InputActionMap) + ".";
202275
foreach (var map in maps)
203276
{
204277
writer.WriteLine();
@@ -219,34 +292,48 @@ public static string GenerateWrapperCode(InputActionAsset asset, Options options
219292
}
220293

221294
// Struct wrapping access to action set.
295+
writer.DocSummary($"Provides access to input actions defined in input action map \"{map.name}\".");
222296
writer.WriteLine($"public struct {mapTypeName}");
223297
writer.BeginBlock();
224298

225-
// Constructor.
226299
writer.WriteLine($"private @{options.className} m_Wrapper;");
300+
writer.WriteLine();
301+
302+
// Constructor.
303+
writer.DocSummary("Construct a new instance of the input action map wrapper class.");
227304
writer.WriteLine($"public {mapTypeName}(@{options.className} wrapper) {{ m_Wrapper = wrapper; }}");
228305

229306
// Getter for each action.
230307
foreach (var action in map.actions)
231308
{
232309
var actionName = CSharpCodeHelpers.MakeIdentifier(action.name);
310+
writer.DocSummary($"Provides access to the underlying input action \"{mapName}/{actionName}\".");
233311
writer.WriteLine(
234312
$"public InputAction @{actionName} => m_Wrapper.m_{mapName}_{actionName};");
235313
}
236314

237315
// Action map getter.
316+
writer.DocSummary("Provides access to the underlying input action map instance.");
238317
writer.WriteLine($"public InputActionMap Get() {{ return m_Wrapper.m_{mapName}; }}");
239318

240319
// Enable/disable methods.
320+
writer.DocInherit(inputActionMapClassPrefix + nameof(InputActionMap.Enable) + "()");
241321
writer.WriteLine("public void Enable() { Get().Enable(); }");
322+
writer.DocInherit(inputActionMapClassPrefix + nameof(InputActionMap.Disable) + "()");
242323
writer.WriteLine("public void Disable() { Get().Disable(); }");
324+
writer.DocInherit(inputActionMapClassPrefix + nameof(InputActionMap.enabled));
243325
writer.WriteLine("public bool enabled => Get().enabled;");
244326

245327
// Implicit conversion operator.
328+
writer.DocSummary($"Implicitly converts an <see ref=\"{mapTypeName}\" /> to an <see ref=\"InputActionMap\" /> instance.");
246329
writer.WriteLine(
247330
$"public static implicit operator InputActionMap({mapTypeName} set) {{ return set.Get(); }}");
248331

249332
// AddCallbacks method.
333+
writer.DocSummary("Adds <see cref=\"InputAction.started\"/>, <see cref=\"InputAction.performed\"/> and <see cref=\"InputAction.canceled\"/> callbacks provided via <param cref=\"instance\" /> on all input actions contained in this map.");
334+
writer.DocParam("instance", "Callback instance.");
335+
writer.DocRemarks("If <paramref name=\"instance\" /> is <c>null</c> or <paramref name=\"instance\"/> have already been added this method does nothing.");
336+
writer.DocSeeAlso(mapTypeName);
250337
writer.WriteLine($"public void AddCallbacks(I{mapTypeName} instance)");
251338
writer.BeginBlock();
252339

@@ -268,6 +355,9 @@ public static string GenerateWrapperCode(InputActionAsset asset, Options options
268355
writer.WriteLine();
269356

270357
// UnregisterCallbacks method.
358+
writer.DocSummary("Removes <see cref=\"InputAction.started\"/>, <see cref=\"InputAction.performed\"/> and <see cref=\"InputAction.canceled\"/> callbacks provided via <param cref=\"instance\" /> on all input actions contained in this map.");
359+
writer.DocRemarks("Calling this method when <paramref name=\"instance\" /> have not previously been registered has no side-effects.");
360+
writer.DocSeeAlso(mapTypeName);
271361
writer.WriteLine($"private void UnregisterCallbacks(I{mapTypeName} instance)");
272362
writer.BeginBlock();
273363
foreach (var action in map.actions)
@@ -283,6 +373,8 @@ public static string GenerateWrapperCode(InputActionAsset asset, Options options
283373
writer.WriteLine();
284374

285375
// RemoveCallbacks method.
376+
writer.DocSummary($"Unregisters <param cref=\"instance\" /> and unregisters all input action callbacks via <see cref=\"{mapTypeName}.UnregisterCallbacks(I{mapTypeName})\" />.");
377+
writer.DocSeeAlso($"{mapTypeName}.UnregisterCallbacks(I{mapTypeName})");
286378
writer.WriteLine($"public void RemoveCallbacks(I{mapTypeName} instance)");
287379
writer.BeginBlock();
288380
writer.WriteLine($"if (m_Wrapper.m_{mapTypeName}CallbackInterfaces.Remove(instance))");
@@ -291,9 +383,13 @@ public static string GenerateWrapperCode(InputActionAsset asset, Options options
291383
writer.WriteLine();
292384

293385
// SetCallbacks method.
386+
writer.DocSummary($"Replaces all existing callback instances and previously registered input action callbacks associated with them with callbacks provided via <param cref=\"instance\" />.");
387+
writer.DocRemarks($"If <paramref name=\"instance\" /> is <c>null</c>, calling this method will only unregister all existing callbacks but not register any new callbacks.");
388+
writer.DocSeeAlso($"{mapTypeName}.AddCallbacks(I{mapTypeName})");
389+
writer.DocSeeAlso($"{mapTypeName}.RemoveCallbacks(I{mapTypeName})");
390+
writer.DocSeeAlso($"{mapTypeName}.UnregisterCallbacks(I{mapTypeName})");
294391
writer.WriteLine($"public void SetCallbacks(I{mapTypeName} instance)");
295392
writer.BeginBlock();
296-
297393
////REVIEW: this would benefit from having a single callback on InputActions rather than three different endpoints
298394

299395
writer.WriteLine($"foreach (var item in m_Wrapper.m_{mapTypeName}CallbackInterfaces)");
@@ -306,6 +402,7 @@ public static string GenerateWrapperCode(InputActionAsset asset, Options options
306402
writer.EndBlock();
307403

308404
// Getter for instance of struct.
405+
writer.DocSummary($"Provides a new <see cref=\"{mapTypeName}\" /> instance referencing this action map.");
309406
writer.WriteLine($"public {mapTypeName} @{mapName} => new {mapTypeName}(this);");
310407
}
311408

@@ -315,6 +412,8 @@ public static string GenerateWrapperCode(InputActionAsset asset, Options options
315412
var identifier = CSharpCodeHelpers.MakeIdentifier(scheme.name);
316413

317414
writer.WriteLine($"private int m_{identifier}SchemeIndex = -1;");
415+
writer.DocSummary("Provides access to the input control scheme.");
416+
writer.DocSeeAlso(typeof(InputControlScheme).Namespace + "." + nameof(InputControlScheme));
318417
writer.WriteLine($"public InputControlScheme {identifier}Scheme");
319418
writer.BeginBlock();
320419
writer.WriteLine("get");
@@ -326,15 +425,23 @@ public static string GenerateWrapperCode(InputActionAsset asset, Options options
326425
}
327426

328427
// Generate interfaces.
428+
var inputActionClassReference = typeof(InputAction).Namespace + "." + nameof(InputAction) + ".";
329429
foreach (var map in maps)
330430
{
331431
var typeName = CSharpCodeHelpers.MakeTypeName(map.name);
432+
writer.DocSummary($"Interface to implement callback methods for all input action callbacks associated with input actions defined by \"{map.name}\" which allows adding and removing callbacks.");
433+
writer.DocSeeAlso($"{typeName}Actions.AddCallbacks(I{typeName}Actions)");
434+
writer.DocSeeAlso($"{typeName}Actions.RemoveCallbacks(I{typeName}Actions)");
332435
writer.WriteLine($"public interface I{typeName}Actions");
333436
writer.BeginBlock();
334437

335438
foreach (var action in map.actions)
336439
{
337440
var methodName = CSharpCodeHelpers.MakeTypeName(action.name);
441+
writer.DocSummary($"Method invoked when associated input action \"{action.name}\" is either <see cref=\"UnityEngine.InputSystem.InputAction.started\" />, <see cref=\"UnityEngine.InputSystem.InputAction.performed\" /> or <see cref=\"UnityEngine.InputSystem.InputAction.canceled\" />.");
442+
writer.DocSeeAlso(string.Concat(inputActionClassReference, "started"));
443+
writer.DocSeeAlso(string.Concat(inputActionClassReference, "performed"));
444+
writer.DocSeeAlso(string.Concat(inputActionClassReference, "canceled"));
338445
writer.WriteLine($"void On{methodName}(InputAction.CallbackContext context);");
339446
}
340447

@@ -399,6 +506,65 @@ public void WriteIndent()
399506
buffer.Append(' ');
400507
}
401508
}
509+
510+
public void DocSummary(string text)
511+
{
512+
DocElement("summary", text);
513+
}
514+
515+
public void DocParam(string paramName, string text)
516+
{
517+
WriteLine($"/// <param name=\"{paramName}\">{text}</param>");
518+
}
519+
520+
public void DocRemarks(string text)
521+
{
522+
DocElement("remarks", text);
523+
}
524+
525+
public void DocInherit(string cref)
526+
{
527+
DocReference("inheritdoc", cref);
528+
}
529+
530+
public void DocSeeAlso(string cref)
531+
{
532+
DocReference("seealso", cref: cref);
533+
}
534+
535+
public void DocExample(string code)
536+
{
537+
DocComment("<example>");
538+
DocComment("<code>");
539+
540+
foreach (var line in code.Split('\n'))
541+
DocComment(line.Replace("<", "&lt;").Replace(">", "&gt;"));
542+
543+
DocComment("</code>");
544+
DocComment("</example>");
545+
}
546+
547+
private void DocComment(string text)
548+
{
549+
WriteLine(string.Concat("/// ", text));
550+
}
551+
552+
private void DocElement(string tag, string text)
553+
{
554+
DocComment($"<{tag}>");
555+
DocComment(text);
556+
DocComment($"</{tag}>");
557+
}
558+
559+
private void DocReference(string tag, string cref)
560+
{
561+
DocInlineElement(tag, "cref", cref);
562+
}
563+
564+
private void DocInlineElement(string tag, string property, string value)
565+
{
566+
DocComment($"<{tag} {property}=\"{value}\" />");
567+
}
402568
}
403569

404570
// Updates the given file with wrapper code generated for the given action sets.

0 commit comments

Comments
 (0)