diff --git a/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidInputHandler.cs b/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidInputHandler.cs index 5d45edd..0ba8327 100644 --- a/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidInputHandler.cs +++ b/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidInputHandler.cs @@ -5,7 +5,13 @@ namespace Cryville.Input.Unity.Android { /// /// An that handles Android input. /// - public abstract class AndroidInputHandler : InputHandler { + /// The type that inherits this class. + public abstract class AndroidInputHandler : InputHandler where TSelf : AndroidInputHandler { + /// + /// The instance of this class. + /// + protected static TSelf Instance { get; private set; } + readonly IntPtr _t_T; static readonly jvalue[] _p_void = new jvalue[0]; readonly IntPtr _i_T; @@ -22,8 +28,11 @@ namespace Cryville.Input.Unity.Android { /// An instance of this class have already been created. /// Android input is not supported on the current device. public AndroidInputHandler(string className) { + if (Instance != null) + throw new InvalidOperationException("AndroidInputHandler already created"); if (Environment.OSVersion.Platform != PlatformID.Unix) throw new NotSupportedException("Android input is not supported on this device"); + Instance = (TSelf)this; JavaStaticMethods.Init(); @@ -40,7 +49,10 @@ namespace Cryville.Input.Unity.Android { _m_T_activate = AndroidJNI.GetMethodID(_t_T, "activate", "()V"); _m_T_deactivate = AndroidJNI.GetMethodID(_t_T, "deactivate", "()V"); - AndroidInputPoller.Instance.Register(AndroidJNI.CallIntMethod(_i_T, _m_T_getId, _p_void), this); + NativeMethods.AndroidInputProxy_RegisterCallback( + AndroidJNI.CallIntMethod(_i_T, _m_T_getId, _p_void), + Callback + ); } /// @@ -66,6 +78,6 @@ namespace Cryville.Input.Unity.Android { } } - internal abstract void OnFeed(int id, int action, long time, float x, float y, float z, float w); + private protected abstract AndroidInputProxy_Callback Callback { get; } } } diff --git a/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidInputPoller.cs b/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidInputPoller.cs deleted file mode 100644 index 0da9218..0000000 --- a/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidInputPoller.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Collections.Generic; -using System.Threading; - -namespace Cryville.Input.Unity.Android { - internal class AndroidInputPoller { - static AndroidInputPoller m_instance; - public static AndroidInputPoller Instance { - get { - if (m_instance == null) m_instance = new AndroidInputPoller(); - return m_instance; - } - } - - readonly Thread _thread; - private AndroidInputPoller() { - _thread = new Thread(ThreadLogic) { IsBackground = true, Priority = ThreadPriority.AboveNormal }; - _thread.Start(); - } - - readonly Dictionary _handlers = new Dictionary(); - public void Register(int id, AndroidInputHandler handler) { - _handlers[id] = handler; - } - - void ThreadLogic() { - while (true) { - while (NativeMethods.AndroidInputProxy_Poll(out var frame) == 1) { - _handlers[frame.hid].OnFeed(frame.id, frame.action, frame.time, frame.x, frame.y, frame.z, frame.w); - } - Thread.Sleep(1); - } - } - } -} diff --git a/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidInputPoller.cs.meta b/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidInputPoller.cs.meta deleted file mode 100644 index 4ecf355..0000000 --- a/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidInputPoller.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9b69004cd86eb0b42bfa2bcf3d1f7e87 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidSensorHandler.cs b/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidSensorHandler.cs index 38402b0..7b0d056 100644 --- a/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidSensorHandler.cs +++ b/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidSensorHandler.cs @@ -1,3 +1,4 @@ +using Cryville.Common.Interop; using Cryville.Common.Logging; using System; using System.Text.RegularExpressions; @@ -6,9 +7,9 @@ namespace Cryville.Input.Unity.Android { /// /// An that handles Android sensor input. /// - public abstract class AndroidSensorHandler : AndroidInputHandler { + public abstract class AndroidSensorHandler : AndroidInputHandler where TSelf : AndroidSensorHandler { /// - /// Creates an instance of the class. + /// Creates an instance of the class. /// /// The name of the Java class nested in world/cryville/input/unity/android/SensorProxy that performs the low-level jobs. /// The dimension. @@ -38,11 +39,14 @@ namespace Cryville.Input.Unity.Android { return JavaStaticMethods.SystemClock_elapsedRealtimeNanos() / 1e9; } - internal override void OnFeed(int id, int action, long time, float x, float y, float z, float w) { + private protected sealed override AndroidInputProxy_Callback Callback { get { return OnFeed; } } + + [MonoPInvokeCallback] + static void OnFeed(int id, int action, long time, float x, float y, float z, float w) { try { double timeSecs = time / 1e9; - Feed(0, id, new InputFrame(timeSecs, new InputVector(x, y, z, w))); - Batch(timeSecs); + Instance.Feed(0, id, new InputFrame(timeSecs, new InputVector(x, y, z, w))); + Instance.Batch(timeSecs); } catch (Exception ex) { Shared.Logger.Log(4, "Input", "An error occurred while handling an Android sensor event: {0}", ex); @@ -53,7 +57,7 @@ namespace Cryville.Input.Unity.Android { /// /// An that handles Android accelerometer sensor input. /// - public class AndroidAccelerometerHandler : AndroidSensorHandler { + public class AndroidAccelerometerHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// @@ -67,7 +71,7 @@ namespace Cryville.Input.Unity.Android { /// /// An that handles Android accelerometer (uncalibrated) sensor input. /// - public class AndroidAccelerometerUncalibratedHandler : AndroidSensorHandler { + public class AndroidAccelerometerUncalibratedHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// @@ -81,7 +85,7 @@ namespace Cryville.Input.Unity.Android { /// /// An that handles Android game rotation vector sensor input. /// - public class AndroidGameRotationVectorHandler : AndroidSensorHandler { + public class AndroidGameRotationVectorHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// @@ -95,7 +99,7 @@ namespace Cryville.Input.Unity.Android { /// /// An that handles Android gravity sensor input. /// - public class AndroidGravityHandler : AndroidSensorHandler { + public class AndroidGravityHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// @@ -109,7 +113,7 @@ namespace Cryville.Input.Unity.Android { /// /// An that handles Android gyroscope sensor input. /// - public class AndroidGyroscopeHandler : AndroidSensorHandler { + public class AndroidGyroscopeHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// @@ -121,9 +125,23 @@ namespace Cryville.Input.Unity.Android { public override ReferenceCue ReferenceCue => _refCue; } /// + /// An that handles Android gyroscope (uncalibrated) sensor input. + /// + public class AndroidGyroscopeUncalibratedHandler : AndroidSensorHandler { + /// + /// Creates an instance of the class. + /// + public AndroidGyroscopeUncalibratedHandler() : base("GyroscopeUncalibrated", 3) { } + static readonly ReferenceCue _refCue = new ReferenceCue { + PhysicalDimension = new PhysicalDimension { Time = -1 }, + }; + /// + public override ReferenceCue ReferenceCue => _refCue; + } + /// /// An that handles Android linear acceleration sensor input. /// - public class AndroidLinearAccelerationHandler : AndroidSensorHandler { + public class AndroidLinearAccelerationHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// @@ -137,7 +155,7 @@ namespace Cryville.Input.Unity.Android { /// /// An that handles Android magnetic field sensor input. /// - public class AndroidMagneticFieldHandler : AndroidSensorHandler { + public class AndroidMagneticFieldHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// @@ -151,7 +169,7 @@ namespace Cryville.Input.Unity.Android { /// /// An that handles Android magnetic field (uncalibrated) sensor input. /// - public class AndroidMagneticFieldUncalibratedHandler : AndroidSensorHandler { + public class AndroidMagneticFieldUncalibratedHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// @@ -165,7 +183,7 @@ namespace Cryville.Input.Unity.Android { /// /// An that handles Android rotation vector sensor input. /// - public class AndroidRotationVectorHandler : AndroidSensorHandler { + public class AndroidRotationVectorHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// diff --git a/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidTouchHandler.cs b/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidTouchHandler.cs index 26e88e3..5a5ebfa 100644 --- a/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidTouchHandler.cs +++ b/Assets/Plugins/Android/Cryville.Input.Unity.Android/AndroidTouchHandler.cs @@ -1,3 +1,4 @@ +using Cryville.Common.Interop; using Cryville.Common.Logging; using System; @@ -5,7 +6,7 @@ namespace Cryville.Input.Unity.Android { /// /// An that handles Android touch input. /// - public class AndroidTouchHandler : AndroidInputHandler { + public class AndroidTouchHandler : AndroidInputHandler { /// /// Creates an instance of the class. /// @@ -39,16 +40,19 @@ namespace Cryville.Input.Unity.Android { return JavaStaticMethods.SystemClock_uptimeMillis() / 1000.0; } - internal override void OnFeed(int id, int action, long time, float x, float y, float z, float w) { + private protected override AndroidInputProxy_Callback Callback { get { return OnFeed; } } + + [MonoPInvokeCallback] + static void OnFeed(int id, int action, long time, float x, float y, float z, float w) { try { double timeSecs = time / 1000.0; if (action == -2) { - Batch(timeSecs); + Instance.Batch(timeSecs); } else { - Feed(0, id, new InputFrame(timeSecs, new InputVector(x, y))); + Instance.Feed(0, id, new InputFrame(timeSecs, new InputVector(x, y))); if (action == 1 /*ACTION_UP*/ || action == 3 /*ACTION_CANCEL*/ || action == 6 /*ACTION_POINTER_UP*/) - Feed(0, id, new InputFrame(timeSecs)); + Instance.Feed(0, id, new InputFrame(timeSecs)); } } catch (Exception ex) { diff --git a/Assets/Plugins/Android/Cryville.Input.Unity.Android/NativeMethods.cs b/Assets/Plugins/Android/Cryville.Input.Unity.Android/NativeMethods.cs index 306c078..5b3a2ec 100644 --- a/Assets/Plugins/Android/Cryville.Input.Unity.Android/NativeMethods.cs +++ b/Assets/Plugins/Android/Cryville.Input.Unity.Android/NativeMethods.cs @@ -1,19 +1,9 @@ using System.Runtime.InteropServices; namespace Cryville.Input.Unity.Android { - struct ProxiedInputFrame { - public int hid; - public int id; - public int action; - public long time; - public float x; - public float y; - public float z; - public float w; - }; + internal delegate void AndroidInputProxy_Callback(int id, int action, long time, float x, float y, float z, float w); internal static class NativeMethods { [DllImport("AndroidInputProxy")] - [PreserveSig] - public static extern int AndroidInputProxy_Poll(out ProxiedInputFrame frame); + public static extern void AndroidInputProxy_RegisterCallback(int hid, AndroidInputProxy_Callback cb); } } diff --git a/Assets/Plugins/Android/arm64-v8a/libAndroidInputProxy.so b/Assets/Plugins/Android/arm64-v8a/libAndroidInputProxy.so index 39ba9d9..ba2373b 100644 Binary files a/Assets/Plugins/Android/arm64-v8a/libAndroidInputProxy.so and b/Assets/Plugins/Android/arm64-v8a/libAndroidInputProxy.so differ diff --git a/Assets/Plugins/Android/armeabi-v7a/libAndroidInputProxy.so b/Assets/Plugins/Android/armeabi-v7a/libAndroidInputProxy.so index b2b2821..1659e58 100644 Binary files a/Assets/Plugins/Android/armeabi-v7a/libAndroidInputProxy.so and b/Assets/Plugins/Android/armeabi-v7a/libAndroidInputProxy.so differ