File size: 5,594 Bytes
18a519f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | using System;
using System.Runtime.InteropServices;
using UnityEngine.InputSystem.Utilities;
namespace UnityEngine.InputSystem.LowLevel
{
/// <summary>
/// Query the ID and the name of the user paired to the device the command is sent to.
/// </summary>
/// <remarks>
/// This command is only supported on platforms where devices can be paired to user accounts
/// at the platform level. Currently this is the case for Xbox and PS4. On Switch, <see
/// cref="InitiateUserAccountPairingCommand"/> is supported but the platform does not store
/// associations established between devices and users that way.
/// </remarks>
[StructLayout(LayoutKind.Explicit, Size = kSize)]
public unsafe struct QueryPairedUserAccountCommand : IInputDeviceCommandInfo
{
public static FourCC Type => new FourCC('P', 'A', 'C', 'C');
internal const int kMaxNameLength = 256;
internal const int kMaxIdLength = 256;
////REVIEW: is this too heavy to allocate on the stack?
internal const int kSize = InputDeviceCommand.kBaseCommandSize + 8 + kMaxNameLength * 2 + kMaxIdLength * 2;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1714:FlagsEnumsShouldHavePluralNames", Justification = "`Result` matches other command result names")]
[Flags]
public enum Result : long
{
// Leave bit #0 unused so as to not lead to possible confusion with GenericSuccess.
/// <summary>
/// The device is currently paired to a user account.
/// </summary>
DevicePairedToUserAccount = 1 << 1,
/// <summary>
/// The system is currently displaying a prompt for the user to select an account to
/// use the device with.
/// </summary>
UserAccountSelectionInProgress = 1 << 2,
/// <summary>
/// User account selection completed.
/// </summary>
UserAccountSelectionComplete = 1 << 3,
/// <summary>
/// The system had been displaying a prompt
/// </summary>
UserAccountSelectionCanceled = 1 << 4,
}
[FieldOffset(0)]
public InputDeviceCommand baseCommand;
/// <summary>
/// Handle of the user account at the platform level.
/// </summary>
/// <remarks>
/// Note that this is wide enough to store a pointer and does not necessarily need to be a plain integer.
/// How the backend determines handles for user accounts is up to the backend.
///
/// Be aware that a handle is not guaranteed to be valid beyond the current application run. For stable,
/// persistent user account handles,use <see cref="id"/>.
/// </remarks>
[FieldOffset(InputDeviceCommand.kBaseCommandSize)]
public ulong handle;
[FieldOffset(InputDeviceCommand.kBaseCommandSize + 8)]
internal fixed byte nameBuffer[kMaxNameLength * 2];
[FieldOffset(InputDeviceCommand.kBaseCommandSize + 8 + kMaxNameLength * 2)]
internal fixed byte idBuffer[kMaxNameLength * 2];
/// <summary>
/// Persistent ID of the user account the platform level.
/// </summary>
/// <remarks>
/// This ID is guaranteed to not change between application runs, device restarts, and the user
/// changing user names on the account.
///
/// Use this ID to associate persistent settings with.
/// </remarks>
public string id
{
get
{
fixed(byte* idBufferPtr = idBuffer)
return StringHelpers.ReadStringFromBuffer(new IntPtr(idBufferPtr), kMaxIdLength);
}
set
{
if (value == null)
throw new ArgumentNullException(nameof(value));
var length = value.Length;
if (length > kMaxIdLength)
throw new ArgumentException($"ID '{value}' exceeds maximum supported length of {kMaxIdLength} characters", nameof(value));
fixed(byte* idBufferPtr = idBuffer)
{
StringHelpers.WriteStringToBuffer(value, new IntPtr(idBufferPtr), kMaxIdLength);
}
}
}
/// <summary>
/// Name of the user account at the platform level.
/// </summary>
public string name
{
get
{
fixed(byte* nameBufferPtr = nameBuffer)
return StringHelpers.ReadStringFromBuffer(new IntPtr(nameBufferPtr), kMaxNameLength);
}
set
{
if (value == null)
throw new ArgumentNullException("value");
var length = value.Length;
if (length > kMaxNameLength)
throw new ArgumentException($"Name '{value}' exceeds maximum supported length of {kMaxNameLength} characters", nameof(value));
fixed(byte* nameBufferPtr = nameBuffer)
{
StringHelpers.WriteStringToBuffer(value, new IntPtr(nameBufferPtr), kMaxNameLength);
}
}
}
public FourCC typeStatic => Type;
public static QueryPairedUserAccountCommand Create()
{
return new QueryPairedUserAccountCommand
{
baseCommand = new InputDeviceCommand(Type, kSize),
};
}
}
}
|