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;
}
}