A game about forced loneliness, made by TACStudios
1#if UNITY_EDITOR || UNITY_IOS || PACKAGE_DOCS_GENERATION
2using System.Runtime.InteropServices;
3using AOT;
4using Unity.Collections.LowLevel.Unsafe;
5using UnityEngine.InputSystem.Layouts;
6using UnityEngine.InputSystem.LowLevel;
7using UnityEngine.InputSystem.Utilities;
8
9namespace UnityEngine.InputSystem.iOS.LowLevel
10{
11 /// <summary>
12 /// Describes the access for motion related features.
13 /// </summary>
14 /// <remarks>Enum values map values from CoreMotion.framework/Headers/CMAuthorization.h</remarks>
15 public enum MotionAuthorizationStatus
16 {
17 /// <summary>
18 /// The access status was not yet determined.
19 /// </summary>
20 NotDetermined = 0,
21
22 /// <summary>
23 /// Access was denied due system settings.
24 /// </summary>
25 Restricted,
26
27 /// <summary>
28 /// Access was denied by the user.
29 /// </summary>
30 Denied,
31
32 /// <summary>
33 /// Access was allowed by the user.
34 /// </summary>
35 Authorized
36 }
37
38 [StructLayout(LayoutKind.Sequential)]
39 internal struct iOSStepCounterState : IInputStateTypeInfo
40 {
41 public static FourCC kFormat = new FourCC('I', 'S', 'C', 'S');
42 public FourCC format => kFormat;
43
44 [InputControl(name = "stepCounter", layout = "Integer")]
45 public int stepCounter;
46 }
47
48 /// <summary>
49 /// Step Counter (also known as pedometer) sensor for iOS.
50 /// </summary>
51 /// <remarks>
52 /// You need to enable Motion Usage in Input System settings (see <see cref="InputSettings.iOSSettings.motionUsage"/>), to be allowed
53 /// to access the sensor on the user's device.
54 /// <example>
55 /// <code>
56 /// void Start()
57 /// {
58 /// InputSystem.EnableDevice(StepCounter.current);
59 /// }
60 ///
61 /// void OnGUI()
62 /// {
63 /// GUILayout.Label(StepCounter.current.stepCounter.ReadValue().ToString());
64 /// }
65 /// </code>
66 /// </example>
67 /// </remarks>
68 /// <seealso cref="InputSettings.iOSSettings.motionUsage"/>
69 [InputControlLayout(stateType = typeof(iOSStepCounterState), variants = "StepCounter", hideInUI = true)]
70 public class iOSStepCounter : StepCounter
71 {
72 private const int kCommandFailure = -1;
73 private const int kCommandSuccess = 1;
74
75 internal delegate void OnDataReceivedDelegate(int deviceId, int numberOfSteps);
76
77 [StructLayout(LayoutKind.Sequential)]
78 private struct iOSStepCounterCallbacks
79 {
80 internal OnDataReceivedDelegate onData;
81 }
82
83 [DllImport("__Internal")]
84 private static extern int _iOSStepCounterEnable(int deviceId, ref iOSStepCounterCallbacks callbacks, int sizeOfCallbacks);
85
86 [DllImport("__Internal")]
87 private static extern int _iOSStepCounterDisable(int deviceId);
88
89 [DllImport("__Internal")]
90 private static extern int _iOSStepCounterIsEnabled(int deviceId);
91
92 [DllImport("__Internal")]
93 private static extern int _iOSStepCounterIsAvailable();
94
95 [DllImport("__Internal")]
96 private static extern int _iOSStepCounterGetAuthorizationStatus();
97
98 [MonoPInvokeCallback(typeof(OnDataReceivedDelegate))]
99 private static void OnDataReceived(int deviceId, int numberOfSteps)
100 {
101 var stepCounter = (iOSStepCounter)InputSystem.GetDeviceById(deviceId);
102 InputSystem.QueueStateEvent(stepCounter, new iOSStepCounterState {stepCounter = numberOfSteps});
103 }
104
105#if UNITY_EDITOR
106 private bool m_Enabled = false;
107#endif
108 protected override unsafe long ExecuteCommand(InputDeviceCommand* commandPtr)
109 {
110 var t = commandPtr->type;
111 if (t == QueryEnabledStateCommand.Type)
112 {
113#if UNITY_EDITOR
114 ((QueryEnabledStateCommand*)commandPtr)->isEnabled = m_Enabled;
115#else
116 ((QueryEnabledStateCommand*)commandPtr)->isEnabled = _iOSStepCounterIsEnabled(deviceId) != 0;
117#endif
118 return kCommandSuccess;
119 }
120
121 if (t == EnableDeviceCommand.Type)
122 {
123 if (InputSystem.settings.iOS.motionUsage.enabled == false)
124 {
125 Debug.LogError("Please enable Motion Usage in Input Settings before using Step Counter.");
126 return kCommandFailure;
127 }
128#if UNITY_EDITOR
129 m_Enabled = true;
130 return kCommandSuccess;
131#else
132 var callbacks = new iOSStepCounterCallbacks();
133 callbacks.onData = OnDataReceived;
134 return _iOSStepCounterEnable(deviceId, ref callbacks, Marshal.SizeOf(callbacks));
135#endif
136 }
137
138 if (t == DisableDeviceCommand.Type)
139 {
140#if UNITY_EDITOR
141 m_Enabled = false;
142 return kCommandSuccess;
143#else
144 return _iOSStepCounterDisable(deviceId);
145#endif
146 }
147
148 if (t == QueryCanRunInBackground.Type)
149 {
150 ((QueryCanRunInBackground*)commandPtr)->canRunInBackground = true;
151 return kCommandSuccess;
152 }
153
154 if (t == RequestResetCommand.Type)
155 {
156#if UNITY_EDITOR
157 m_Enabled = false;
158#else
159 _iOSStepCounterDisable(deviceId);
160#endif
161 return kCommandSuccess;
162 }
163
164 return kCommandFailure;
165 }
166
167 /// <summary>
168 /// Does the phone support the pedometer?
169 /// </summary>
170 public static bool IsAvailable()
171 {
172#if UNITY_EDITOR
173 return false;
174#else
175 return _iOSStepCounterIsAvailable() != 0;
176#endif
177 }
178
179 /// <summary>
180 /// Indicates whether the app is authorized to gather data for step counter sensor.
181 /// </summary>
182 public static MotionAuthorizationStatus AuthorizationStatus
183 {
184 get
185 {
186#if UNITY_EDITOR
187 return MotionAuthorizationStatus.NotDetermined;
188#else
189 return (MotionAuthorizationStatus)_iOSStepCounterGetAuthorizationStatus();
190#endif
191 }
192 }
193 }
194}
195#endif