Rearrange platform specific plugins.

This commit is contained in:
2023-09-25 10:52:16 +08:00
parent 84acb2c12d
commit 825818679c
27 changed files with 30 additions and 6 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4406fa823b7746b47a76d810f5bedf6c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,71 @@
using System;
using UnityEngine;
namespace Cryville.Input.Unity.Android {
/// <summary>
/// An <see cref="InputHandler" /> that handles Android input.
/// </summary>
public abstract class AndroidInputHandler : InputHandler {
readonly IntPtr _t_T;
static readonly jvalue[] _p_void = new jvalue[0];
readonly IntPtr _i_T;
readonly IntPtr _m_T_activate;
readonly IntPtr _m_T_deactivate;
bool _activated;
/// <summary>
/// Creates an instance of the <see cref="AndroidInputHandler{TSelf}" /> class.
/// </summary>
/// <param name="className">The full name of the Java class that performs the low-level jobs.</param>
/// <exception cref="InvalidOperationException">An instance of this class have already been created.</exception>
/// <exception cref="NotSupportedException">Android input is not supported on the current device.</exception>
public AndroidInputHandler(string className) {
if (Environment.OSVersion.Platform != PlatformID.Unix)
throw new NotSupportedException("Android input is not supported on this device");
JavaStaticMethods.Init();
var _lt_T = AndroidJNI.FindClass(className);
_t_T = AndroidJNI.NewGlobalRef(_lt_T);
AndroidJNI.DeleteLocalRef(_lt_T);
var _m_T_init = AndroidJNI.GetMethodID(_t_T, "<init>", "()V");
var _li_T = AndroidJNI.NewObject(_t_T, _m_T_init, _p_void);
_i_T = AndroidJNI.NewGlobalRef(_li_T);
AndroidJNI.DeleteLocalRef(_li_T);
var _m_T_getId = AndroidJNI.GetMethodID(_t_T, "getId", "()I");
_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);
}
/// <inheritdoc />
protected override void Activate() {
if (_activated) return;
_activated = true;
AndroidJNI.CallVoidMethod(_i_T, _m_T_activate, _p_void);
}
/// <inheritdoc />
protected override void Deactivate() {
if (!_activated) return;
_activated = false;
AndroidJNI.CallVoidMethod(_i_T, _m_T_deactivate, _p_void);
}
/// <inheritdoc />
public override void Dispose(bool disposing) {
if (disposing) {
Deactivate();
AndroidJNI.DeleteGlobalRef(_i_T);
AndroidJNI.DeleteGlobalRef(_t_T);
}
}
internal abstract void OnFeed(int id, int action, long time, float x, float y, float z, float w);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ed308f7b1ca3ed443b6eea2559c103c8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
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<int, AndroidInputHandler> _handlers = new Dictionary<int, AndroidInputHandler>();
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);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9b69004cd86eb0b42bfa2bcf3d1f7e87
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,179 @@
using Cryville.Common.Logging;
using System;
using System.Text.RegularExpressions;
namespace Cryville.Input.Unity.Android {
/// <summary>
/// An <see cref="InputHandler" /> that handles Android sensor input.
/// </summary>
public abstract class AndroidSensorHandler : AndroidInputHandler {
/// <summary>
/// Creates an instance of the <see cref="AndroidSensorHandler{TSelf}" /> class.
/// </summary>
/// <param name="typeName">The name of the Java class nested in <c>world/cryville/input/unity/android/SensorProxy</c> that performs the low-level jobs.</param>
/// <param name="dimension">The dimension.</param>
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;
}
/// <inheritdoc />
public override bool IsNullable => false;
readonly byte m_dimension;
/// <inheritdoc />
public override byte Dimension => m_dimension;
readonly string m_typeName;
/// <inheritdoc />
public override string GetTypeName(int type) {
switch (type) {
case 0: return m_typeName;
default: throw new ArgumentOutOfRangeException("type");
}
}
/// <inheritdoc />
public override double GetCurrentTimestamp() {
return JavaStaticMethods.SystemClock_elapsedRealtimeNanos() / 1e9;
}
internal override 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);
}
catch (Exception ex) {
Logger.Log("main", 4, "Input", "An error occurred while handling an Android sensor event: {0}", ex);
}
}
}
/// <summary>
/// An <see cref="InputHandler" /> that handles Android accelerometer sensor input.
/// </summary>
public class AndroidAccelerometerHandler : AndroidSensorHandler {
/// <summary>
/// Creates an instance of the <see cref="AndroidAccelerometerHandler" /> class.
/// </summary>
public AndroidAccelerometerHandler() : base("Accelerometer", 3) { }
static readonly ReferenceCue _refCue = new ReferenceCue {
PhysicalDimension = new PhysicalDimension { Length = 1, Time = -2 },
};
/// <inheritdoc />
public override ReferenceCue ReferenceCue => _refCue;
}
/// <summary>
/// An <see cref="InputHandler" /> that handles Android accelerometer (uncalibrated) sensor input.
/// </summary>
public class AndroidAccelerometerUncalibratedHandler : AndroidSensorHandler {
/// <summary>
/// Creates an instance of the <see cref="AndroidAccelerometerUncalibratedHandler" /> class.
/// </summary>
public AndroidAccelerometerUncalibratedHandler() : base("AccelerometerUncalibrated", 3) { }
static readonly ReferenceCue _refCue = new ReferenceCue {
PhysicalDimension = new PhysicalDimension { Length = 1, Time = -2 },
};
/// <inheritdoc />
public override ReferenceCue ReferenceCue => _refCue;
}
/// <summary>
/// An <see cref="InputHandler" /> that handles Android game rotation vector sensor input.
/// </summary>
public class AndroidGameRotationVectorHandler : AndroidSensorHandler {
/// <summary>
/// Creates an instance of the <see cref="AndroidGameRotationVectorHandler" /> class.
/// </summary>
public AndroidGameRotationVectorHandler() : base("GameRotationVector", 4) { }
static readonly ReferenceCue _refCue = new ReferenceCue {
PhysicalDimension = new PhysicalDimension(),
};
/// <inheritdoc />
public override ReferenceCue ReferenceCue => _refCue;
}
/// <summary>
/// An <see cref="InputHandler" /> that handles Android gravity sensor input.
/// </summary>
public class AndroidGravityHandler : AndroidSensorHandler {
/// <summary>
/// Creates an instance of the <see cref="AndroidGravityHandler" /> class.
/// </summary>
public AndroidGravityHandler() : base("Gravity", 3) { }
static readonly ReferenceCue _refCue = new ReferenceCue {
PhysicalDimension = new PhysicalDimension { Length = 1, Time = -2 },
};
/// <inheritdoc />
public override ReferenceCue ReferenceCue => _refCue;
}
/// <summary>
/// An <see cref="InputHandler" /> that handles Android gyroscope sensor input.
/// </summary>
public class AndroidGyroscopeHandler : AndroidSensorHandler {
/// <summary>
/// Creates an instance of the <see cref="AndroidGyroscopeHandler" /> class.
/// </summary>
public AndroidGyroscopeHandler() : base("Gyroscope", 3) { }
static readonly ReferenceCue _refCue = new ReferenceCue {
PhysicalDimension = new PhysicalDimension { Time = -1 },
};
/// <inheritdoc />
public override ReferenceCue ReferenceCue => _refCue;
}
/// <summary>
/// An <see cref="InputHandler" /> that handles Android linear acceleration sensor input.
/// </summary>
public class AndroidLinearAccelerationHandler : AndroidSensorHandler {
/// <summary>
/// Creates an instance of the <see cref="AndroidLinearAccelerationHandler" /> class.
/// </summary>
public AndroidLinearAccelerationHandler() : base("LinearAcceleration", 3) { }
static readonly ReferenceCue _refCue = new ReferenceCue {
PhysicalDimension = new PhysicalDimension { Length = 1, Time = -2 },
};
/// <inheritdoc />
public override ReferenceCue ReferenceCue => _refCue;
}
/// <summary>
/// An <see cref="InputHandler" /> that handles Android magnetic field sensor input.
/// </summary>
public class AndroidMagneticFieldHandler : AndroidSensorHandler {
/// <summary>
/// Creates an instance of the <see cref="AndroidMagneticFieldHandler" /> class.
/// </summary>
public AndroidMagneticFieldHandler() : base("MagneticField", 3) { }
static readonly ReferenceCue _refCue = new ReferenceCue {
PhysicalDimension = new PhysicalDimension { Mass = 1, Time = -2, ElectricCurrent = -1 },
};
/// <inheritdoc />
public override ReferenceCue ReferenceCue => _refCue;
}
/// <summary>
/// An <see cref="InputHandler" /> that handles Android magnetic field (uncalibrated) sensor input.
/// </summary>
public class AndroidMagneticFieldUncalibratedHandler : AndroidSensorHandler {
/// <summary>
/// Creates an instance of the <see cref="AndroidMagneticFieldUncalibratedHandler" /> class.
/// </summary>
public AndroidMagneticFieldUncalibratedHandler() : base("MagneticFieldUncalibrated", 3) { }
static readonly ReferenceCue _refCue = new ReferenceCue {
PhysicalDimension = new PhysicalDimension { Mass = 1, Time = -2, ElectricCurrent = -1 },
};
/// <inheritdoc />
public override ReferenceCue ReferenceCue => _refCue;
}
/// <summary>
/// An <see cref="InputHandler" /> that handles Android rotation vector sensor input.
/// </summary>
public class AndroidRotationVectorHandler : AndroidSensorHandler {
/// <summary>
/// Creates an instance of the <see cref="AndroidRotationVectorHandler" /> class.
/// </summary>
public AndroidRotationVectorHandler() : base("RotationVector", 4) { }
static readonly ReferenceCue _refCue = new ReferenceCue {
PhysicalDimension = new PhysicalDimension(),
};
/// <inheritdoc />
public override ReferenceCue ReferenceCue => _refCue;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ad609064283f3454992d6cdc8885110f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,59 @@
using Cryville.Common.Logging;
using System;
namespace Cryville.Input.Unity.Android {
/// <summary>
/// An <see cref="InputHandler" /> that handles Android touch input.
/// </summary>
public class AndroidTouchHandler : AndroidInputHandler {
/// <summary>
/// Creates an instance of the <see cref="AndroidTouchHandler" /> class.
/// </summary>
public AndroidTouchHandler() : base("world/cryville/input/unity/android/TouchProxy") { }
/// <inheritdoc />
public override bool IsNullable => true;
/// <inheritdoc />
public override byte Dimension => 2;
static readonly ReferenceCue _refCue = new ReferenceCue {
PhysicalDimension = new PhysicalDimension { Length = 1 },
RelativeUnit = RelativeUnit.Pixel,
Flags = ReferenceFlag.FlipY,
Pivot = new InputVector(0, 1),
};
/// <inheritdoc />
public override ReferenceCue ReferenceCue => _refCue;
/// <inheritdoc />
public override string GetTypeName(int type) {
switch (type) {
case 0: return "Android Touch";
default: throw new ArgumentOutOfRangeException("type");
}
}
/// <inheritdoc />
public override double GetCurrentTimestamp() {
return JavaStaticMethods.SystemClock_uptimeMillis() / 1000.0;
}
internal override 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);
}
else {
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));
}
}
catch (Exception ex) {
Logger.Log("main", 4, "Input", "An error occurred while handling an Android touch event: {0}", ex);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 30eda6ba86d92084f8f038c661147f81
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
{
"name": "Cryville.Input.Unity.Android",
"rootNamespace": "Cryville.Input.Unity.Android",
"references": [],
"includePlatforms": [
"Android"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0bb40a8a1701f13479c68e3659a99bfd
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 89dfa18c4a1ae534096094086e3971ee
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,6 @@
package world.cryville.input.unity.android;
final class NativeMethods {
private NativeMethods() { }
public static native void feed(int hid, int id, int action, long time, float x, float y, float z, float t);
}

View File

@@ -0,0 +1,32 @@
fileFormatVersion: 2
guid: 1796f226463344b48bb9789967b38eda
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Android: Android
second:
enabled: 1
settings: {}
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,28 @@
package world.cryville.input.unity.android;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
import world.cryville.input.unity.android.NativeMethods;
public abstract class Proxy {
protected static UnityPlayerActivity activity;
static int _count;
int _id;
public Proxy() {
if (activity == null) activity = (UnityPlayerActivity)UnityPlayer.currentActivity;
_id = _count++;
}
public int getId() { return _id; }
public abstract void activate();
public abstract void deactivate();
protected void feed(int id, int action, long time) { NativeMethods.feed(_id, id, action, time, 0, 0, 0, 0); }
protected void feed(int id, int action, long time, float x) { NativeMethods.feed(_id, id, action, time, x, 0, 0, 0); }
protected void feed(int id, int action, long time, float x, float y) { NativeMethods.feed(_id, id, action, time, x, y, 0, 0); }
protected void feed(int id, int action, long time, float x, float y, float z) { NativeMethods.feed(_id, id, action, time, x, y, z, 0); }
protected void feed(int id, int action, long time, float x, float y, float z, float w) { NativeMethods.feed(_id, id, action, time, x, y, z, w); }
}

View File

@@ -0,0 +1,32 @@
fileFormatVersion: 2
guid: b60db87d680aebd4c8d9071ff17d3a56
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Android: Android
second:
enabled: 1
settings: {}
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,104 @@
package world.cryville.input.unity.android;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import java.lang.IllegalStateException;
import java.lang.IndexOutOfBoundsException;
import java.util.HashMap;
import java.util.List;
import world.cryville.input.unity.android.Proxy;
public abstract class SensorProxy extends Proxy implements SensorEventListener {
static SensorManager manager;
int dimension;
HashMap<Sensor, Integer> sensors;
List<Sensor> candidateSensors;
public SensorProxy(int type, int dim) throws IllegalStateException, IndexOutOfBoundsException {
if (manager == null) manager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE);
dimension = dim;
if (dimension < 0 || dimension > 4) throw new IndexOutOfBoundsException("Invalid dimension");
sensors = new HashMap<Sensor, Integer>();
candidateSensors = manager.getSensorList(type);
if (candidateSensors.size() == 0) throw new IllegalStateException("Sensor not found");
}
@Override
public void activate() {
int workingSensorCount = 0;
for (Sensor sensor : candidateSensors) {
if (manager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST)) {
sensors.put(sensor, workingSensorCount++);
}
}
}
@Override
public void deactivate() {
manager.unregisterListener(this);
sensors.clear();
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
@Override
public void onSensorChanged(SensorEvent event) {
Integer id = sensors.get(event.sensor);
if (id == null) return;
float[] v = event.values;
switch (dimension) {
case 0: feed(0, id, event.timestamp); break;
case 1: feed(0, id, event.timestamp, v[0]); break;
case 2: feed(0, id, event.timestamp, v[0], v[1]); break;
case 3: feed(0, id, event.timestamp, v[0], v[1], v[2]); break;
case 4: feed(0, id, event.timestamp, v[0], v[1], v[2], v[3]); break;
}
}
public static class Accelerometer extends SensorProxy {
public Accelerometer() { super(Sensor.TYPE_ACCELEROMETER, 3); }
}
public static class AccelerometerUncalibrated extends SensorProxy {
public AccelerometerUncalibrated() { super(Sensor.TYPE_ACCELEROMETER_UNCALIBRATED, 3); }
}
public static class GameRotationVector extends SensorProxy {
public GameRotationVector() { super(Sensor.TYPE_GAME_ROTATION_VECTOR, 4); }
}
public static class Gravity extends SensorProxy {
public Gravity() { super(Sensor.TYPE_GRAVITY, 3); }
}
public static class Gyroscope extends SensorProxy {
public Gyroscope() { super(Sensor.TYPE_GYROSCOPE, 3); }
}
public static class GyroscopeUncalibrated extends SensorProxy {
public GyroscopeUncalibrated() { super(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, 3); }
}
public static class LinearAcceleration extends SensorProxy {
public LinearAcceleration() { super(Sensor.TYPE_LINEAR_ACCELERATION, 3); }
}
public static class MagneticField extends SensorProxy {
public MagneticField() { super(Sensor.TYPE_MAGNETIC_FIELD, 3); }
}
public static class MagneticFieldUncalibrated extends SensorProxy {
public MagneticFieldUncalibrated() { super(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, 3); }
}
public static class RotationVector extends SensorProxy {
public RotationVector() { super(Sensor.TYPE_ROTATION_VECTOR, 4); }
}
}

View File

@@ -0,0 +1,32 @@
fileFormatVersion: 2
guid: c1acbb4fd13ca1249880dbc02ff3c9d4
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Android: Android
second:
enabled: 1
settings: {}
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,50 @@
package world.cryville.input.unity.android;
import android.view.MotionEvent;
import android.view.View;
import com.unity3d.player.UnityPlayer;
import java.lang.reflect.Field;
import world.cryville.input.unity.android.Proxy;
public final class TouchProxy extends Proxy implements View.OnTouchListener {
public TouchProxy() throws NoSuchFieldException, IllegalAccessException, SecurityException {
Field playerField = activity.getClass().getDeclaredField("mUnityPlayer");
playerField.setAccessible(true);
UnityPlayer player = (UnityPlayer)playerField.get(activity);
player.setOnTouchListener(this);
}
boolean activated;
@Override
public void activate() {
activated = true;
}
@Override
public void deactivate() {
activated = false;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (!activated) return false;
int pointerCount = event.getPointerCount();
int action = event.getActionMasked();
int actionIndex = event.getActionIndex();
long time = event.getEventTime();
for (int i = 0; i < pointerCount; i++) {
int id = event.getPointerId(i);
float x = event.getX(i);
float y = event.getY(i);
if (action == 5 || action == 6) {
feed(id, i == actionIndex ? action : -1, time, x, y);
}
else {
feed(id, action, time, x, y);
}
}
feed(0, -2, time);
return false;
}
}

View File

@@ -0,0 +1,32 @@
fileFormatVersion: 2
guid: 4bd9aa92ec47fbf4fa63a219cfe7e4ce
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Android: Android
second:
enabled: 1
settings: {}
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,27 @@
using System;
using UnityEngine;
namespace Cryville.Input.Unity.Android {
internal static class JavaStaticMethods {
static bool _init;
static IntPtr _t_SystemClock;
static IntPtr _m_SystemClock_elapsedRealtimeNanos;
static IntPtr _m_SystemClock_uptimeMillis;
static readonly jvalue[] _p_void = new jvalue[0];
public static void Init() {
if (_init) return;
_init = true;
var _lt_SystemClock = AndroidJNI.FindClass("android/os/SystemClock");
_t_SystemClock = AndroidJNI.NewGlobalRef(_lt_SystemClock);
_m_SystemClock_elapsedRealtimeNanos = AndroidJNI.GetStaticMethodID(_lt_SystemClock, "elapsedRealtimeNanos", "()J");
_m_SystemClock_uptimeMillis = AndroidJNI.GetStaticMethodID(_lt_SystemClock, "uptimeMillis", "()J");
AndroidJNI.DeleteLocalRef(_lt_SystemClock);
}
public static long SystemClock_elapsedRealtimeNanos() {
return AndroidJNI.CallStaticLongMethod(_t_SystemClock, _m_SystemClock_elapsedRealtimeNanos, _p_void);
}
public static long SystemClock_uptimeMillis() {
return AndroidJNI.CallStaticLongMethod(_t_SystemClock, _m_SystemClock_uptimeMillis, _p_void);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a5eec7567c416414cad01bedd2b1786b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,19 @@
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 static class NativeMethods {
[DllImport("AndroidInputProxy")]
[PreserveSig]
public static extern int AndroidInputProxy_Poll(out ProxiedInputFrame frame);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d66e4c88d885f4a49bdb1c6b5783281e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: