using Cryville.Common.Interop; using Cryville.Common.Logging; using System; using System.Text.RegularExpressions; namespace Cryville.Input.Unity.Android { /// /// An that handles Android sensor input. /// public abstract class AndroidSensorHandler : AndroidInputHandler where TSelf : AndroidSensorHandler { /// /// 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. public AndroidSensorHandler(string typeName, byte dimension) : base("world/cryville/input/unity/android/SensorProxy$" + typeName) { m_typeName = Regex.Replace(typeName, @"(?<=[a-z])(?=[A-Z])", " "); m_dimension = dimension; } /// public override bool IsNullable => false; readonly byte m_dimension; /// public override byte Dimension => m_dimension; readonly string m_typeName; /// public override string GetTypeName(int type) { switch (type) { case 0: return m_typeName; default: throw new ArgumentOutOfRangeException("type"); } } /// public override double GetCurrentTimestamp() { return JavaStaticMethods.SystemClock_elapsedRealtimeNanos() / 1e9; } 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; 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); } } } /// /// An that handles Android accelerometer sensor input. /// public class AndroidAccelerometerHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// public AndroidAccelerometerHandler() : base("Accelerometer", 3) { } static readonly ReferenceCue _refCue = new ReferenceCue { PhysicalDimension = new PhysicalDimension { Length = 1, Time = -2 }, }; /// public override ReferenceCue ReferenceCue => _refCue; } /// /// An that handles Android accelerometer (uncalibrated) sensor input. /// public class AndroidAccelerometerUncalibratedHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// public AndroidAccelerometerUncalibratedHandler() : base("AccelerometerUncalibrated", 3) { } static readonly ReferenceCue _refCue = new ReferenceCue { PhysicalDimension = new PhysicalDimension { Length = 1, Time = -2 }, }; /// public override ReferenceCue ReferenceCue => _refCue; } /// /// An that handles Android game rotation vector sensor input. /// public class AndroidGameRotationVectorHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// public AndroidGameRotationVectorHandler() : base("GameRotationVector", 4) { } static readonly ReferenceCue _refCue = new ReferenceCue { PhysicalDimension = new PhysicalDimension(), }; /// public override ReferenceCue ReferenceCue => _refCue; } /// /// An that handles Android gravity sensor input. /// public class AndroidGravityHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// public AndroidGravityHandler() : base("Gravity", 3) { } static readonly ReferenceCue _refCue = new ReferenceCue { PhysicalDimension = new PhysicalDimension { Length = 1, Time = -2 }, }; /// public override ReferenceCue ReferenceCue => _refCue; } /// /// An that handles Android gyroscope sensor input. /// public class AndroidGyroscopeHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// public AndroidGyroscopeHandler() : base("Gyroscope", 3) { } static readonly ReferenceCue _refCue = new ReferenceCue { PhysicalDimension = new PhysicalDimension { Time = -1 }, }; /// 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 { /// /// Creates an instance of the class. /// public AndroidLinearAccelerationHandler() : base("LinearAcceleration", 3) { } static readonly ReferenceCue _refCue = new ReferenceCue { PhysicalDimension = new PhysicalDimension { Length = 1, Time = -2 }, }; /// public override ReferenceCue ReferenceCue => _refCue; } /// /// An that handles Android magnetic field sensor input. /// public class AndroidMagneticFieldHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// public AndroidMagneticFieldHandler() : base("MagneticField", 3) { } static readonly ReferenceCue _refCue = new ReferenceCue { PhysicalDimension = new PhysicalDimension { Mass = 1, Time = -2, ElectricCurrent = -1 }, }; /// public override ReferenceCue ReferenceCue => _refCue; } /// /// An that handles Android magnetic field (uncalibrated) sensor input. /// public class AndroidMagneticFieldUncalibratedHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// public AndroidMagneticFieldUncalibratedHandler() : base("MagneticFieldUncalibrated", 3) { } static readonly ReferenceCue _refCue = new ReferenceCue { PhysicalDimension = new PhysicalDimension { Mass = 1, Time = -2, ElectricCurrent = -1 }, }; /// public override ReferenceCue ReferenceCue => _refCue; } /// /// An that handles Android rotation vector sensor input. /// public class AndroidRotationVectorHandler : AndroidSensorHandler { /// /// Creates an instance of the class. /// public AndroidRotationVectorHandler() : base("RotationVector", 4) { } static readonly ReferenceCue _refCue = new ReferenceCue { PhysicalDimension = new PhysicalDimension(), }; /// public override ReferenceCue ReferenceCue => _refCue; } }