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