Move part of the input module to Cryville.Input.
This commit is contained in:
@@ -1,92 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public class AndroidTouchHandler : InputHandler {
|
||||
readonly AndroidTouchListener _listener;
|
||||
readonly AndroidJavaClass _systemClock;
|
||||
|
||||
public AndroidTouchHandler() {
|
||||
if (Environment.OSVersion.Platform != PlatformID.Unix)
|
||||
throw new NotSupportedException("Android touch is not supported on this device");
|
||||
_systemClock = new AndroidJavaClass("android.os.SystemClock");
|
||||
new AndroidJavaClass("com.unity3d.player.UnityPlayer")
|
||||
.GetStatic<AndroidJavaObject>("currentActivity")
|
||||
.Get<AndroidJavaObject>("mUnityPlayer")
|
||||
.Call("setOnTouchListener", _listener = new AndroidTouchListener(this));
|
||||
}
|
||||
|
||||
protected override void Activate() {
|
||||
_listener.Activated = true;
|
||||
}
|
||||
|
||||
protected override void Deactivate() {
|
||||
_listener.Activated = false;
|
||||
}
|
||||
|
||||
public override void Dispose(bool disposing) {
|
||||
if (disposing) {
|
||||
Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsNullable(int type) {
|
||||
if (type != 0) throw new ArgumentOutOfRangeException("type");
|
||||
return true;
|
||||
}
|
||||
|
||||
public override byte GetDimension(int type) {
|
||||
if (type != 0) throw new ArgumentOutOfRangeException("type");
|
||||
return 2;
|
||||
}
|
||||
|
||||
public override string GetTypeName(int type) {
|
||||
switch (type) {
|
||||
case 0: return "Android Touch";
|
||||
default: throw new ArgumentOutOfRangeException("type");
|
||||
}
|
||||
}
|
||||
|
||||
public override double GetCurrentTimestamp() {
|
||||
return _systemClock.CallStatic<long>("uptimeMillis") / 1000.0;
|
||||
}
|
||||
|
||||
class AndroidTouchListener : AndroidJavaProxy {
|
||||
public bool Activated { get; set; }
|
||||
|
||||
readonly AndroidTouchHandler _handler;
|
||||
|
||||
public AndroidTouchListener(AndroidTouchHandler handler) : base("android.view.View$OnTouchListener") {
|
||||
_handler = handler;
|
||||
}
|
||||
|
||||
#pragma warning disable IDE1006
|
||||
#pragma warning disable IDE0060
|
||||
public bool onTouch(AndroidJavaObject v, AndroidJavaObject e) {
|
||||
if (!Activated) return false;
|
||||
try {
|
||||
int pointerCount = e.Call<int>("getPointerCount");
|
||||
for (int i = 0; i < pointerCount; i++) {
|
||||
int id = e.Call<int>("getPointerId", i);
|
||||
double time = e.Call<long>("getEventTime") / 1000.0;
|
||||
int action = e.Call<int>("getActionMasked");
|
||||
Vector2 pos = UnityCameraUtils.ScreenToWorldPoint(new Vector2(
|
||||
e.Call<float>("getX", i),
|
||||
e.Call<float>("getY", i)
|
||||
));
|
||||
_handler.Feed(0, id, new InputVector(time, pos));
|
||||
if (action == 1 /*ACTION_UP*/ || action == 3 /*ACTION_CANCEL*/ || (action == 6 /*ACTION_POINTER_UP*/ && e.Call<int>("getActionIndex") == i)) {
|
||||
_handler.Feed(0, id, new InputVector(time));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Logger.Log("main", 4, "Input", "An error occured while handling an Android touch event: {0}", ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#pragma warning restore IDE0060
|
||||
#pragma warning restore IDE1006
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
using Cryville.Common.Reflection;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public delegate void InputEventDelegate(InputIdentifier id, InputVector vec);
|
||||
public abstract class InputHandler : IDisposable {
|
||||
InputEventDelegate m_onInput;
|
||||
public event InputEventDelegate OnInput {
|
||||
add {
|
||||
if (m_onInput == null) Activate();
|
||||
m_onInput -= value;
|
||||
m_onInput += value;
|
||||
}
|
||||
remove {
|
||||
if (m_onInput == null) return;
|
||||
m_onInput -= value;
|
||||
if (m_onInput == null) Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
~InputHandler() {
|
||||
Dispose(false);
|
||||
}
|
||||
public void Dispose() {
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected abstract void Activate();
|
||||
protected abstract void Deactivate();
|
||||
public abstract void Dispose(bool disposing);
|
||||
public abstract bool IsNullable(int type);
|
||||
public abstract byte GetDimension(int type);
|
||||
public abstract string GetTypeName(int type);
|
||||
public abstract double GetCurrentTimestamp();
|
||||
protected void Feed(int type, int id, InputVector vec) {
|
||||
var del = m_onInput;
|
||||
if (del != null) del(new InputIdentifier { Source = new InputSource { Handler = this, Type = type }, Id = id }, vec);
|
||||
}
|
||||
}
|
||||
|
||||
public struct InputSource : IEquatable<InputSource> {
|
||||
public InputHandler Handler { get; set; }
|
||||
public int Type { get; set; }
|
||||
public override bool Equals(object obj) {
|
||||
if (obj == null || !(obj is InputSource)) return false;
|
||||
return Equals((InputSource)obj);
|
||||
}
|
||||
public bool Equals(InputSource other) {
|
||||
return Handler == other.Handler && Type == other.Type;
|
||||
}
|
||||
public override int GetHashCode() {
|
||||
return Handler.GetHashCode() ^ Type;
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("{0}:{1}", TypeNameHelper.GetSimpleName(Handler.GetType()), Handler.GetTypeName(Type));
|
||||
}
|
||||
public static bool operator ==(InputSource lhs, InputSource rhs) {
|
||||
return lhs.Equals(rhs);
|
||||
}
|
||||
public static bool operator !=(InputSource lhs, InputSource rhs) {
|
||||
return !lhs.Equals(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
public struct InputIdentifier : IEquatable<InputIdentifier> {
|
||||
public InputSource Source { get; set; }
|
||||
public int Id { get; set; }
|
||||
public override bool Equals(object obj) {
|
||||
if (obj == null || !(obj is InputIdentifier)) return false;
|
||||
return Equals((InputIdentifier)obj);
|
||||
}
|
||||
public bool Equals(InputIdentifier other) {
|
||||
return Source == other.Source && Id == other.Id;
|
||||
}
|
||||
public override int GetHashCode() {
|
||||
return Source.GetHashCode() ^ ((Id << 16) | (Id >> 16));
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("{0},{1}", Source, Id);
|
||||
}
|
||||
public static bool operator ==(InputIdentifier lhs, InputIdentifier rhs) {
|
||||
return lhs.Equals(rhs);
|
||||
}
|
||||
public static bool operator !=(InputIdentifier lhs, InputIdentifier rhs) {
|
||||
return !lhs.Equals(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
public struct InputVector {
|
||||
public double Time { get; set; }
|
||||
public bool IsNull { get; set; }
|
||||
public Vector3 Vector { get; set; }
|
||||
public InputVector(double time) {
|
||||
Time = time;
|
||||
IsNull = true;
|
||||
Vector = default(Vector3);
|
||||
}
|
||||
public InputVector(double time, Vector3 vector) {
|
||||
Time = time;
|
||||
IsNull = false;
|
||||
Vector = vector;
|
||||
}
|
||||
public override string ToString() {
|
||||
if (IsNull) return string.Format("null@{0}", Time);
|
||||
else return string.Format("{0}@{1}", Vector.ToString("G9"), Time);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
using Cryville.Common.Logging;
|
||||
using Cryville.Common.Reflection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public class InputManager {
|
||||
static readonly HashSet<Type> HandlerRegistries = new HashSet<Type> {
|
||||
typeof(WindowsPointerHandler),
|
||||
typeof(AndroidTouchHandler),
|
||||
typeof(UnityKeyHandler<UnityKeyboardReceiver>),
|
||||
typeof(UnityKeyHandler<UnityMouseButtonReceiver>),
|
||||
typeof(UnityMouseHandler),
|
||||
typeof(UnityTouchHandler),
|
||||
};
|
||||
readonly HashSet<InputHandler> _handlers = new HashSet<InputHandler>();
|
||||
readonly Dictionary<Type, InputHandler> _typemap = new Dictionary<Type, InputHandler>();
|
||||
public InputManager() {
|
||||
foreach (var t in HandlerRegistries) {
|
||||
try {
|
||||
if (!typeof(InputHandler).IsAssignableFrom(t)) continue;
|
||||
var h = (InputHandler)Activator.CreateInstance(t);
|
||||
_typemap.Add(t, h);
|
||||
_handlers.Add(h);
|
||||
Logger.Log("main", 1, "Input", "Initialized {0}", TypeNameHelper.GetSimpleName(t));
|
||||
}
|
||||
catch (TargetInvocationException ex) {
|
||||
Logger.Log("main", 1, "Input", "Cannot initialize {0}: {1}", TypeNameHelper.GetSimpleName(t), ex.InnerException.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
public InputHandler GetHandler(string name) {
|
||||
return _typemap[Type.GetType(name)];
|
||||
}
|
||||
public void EnumerateHandlers(Action<InputHandler> cb) {
|
||||
foreach (var h in _handlers) cb(h);
|
||||
}
|
||||
}
|
||||
|
||||
public struct InputEvent {
|
||||
public InputIdentifier Id { get; set; }
|
||||
public InputVector From { get; set; }
|
||||
public InputVector To { get; set; }
|
||||
public override string ToString() {
|
||||
return string.Format("[{0}] {1} -> {2}", Id, From, To);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aaf7daeaf7afb3146b3eea2a07f88055
|
||||
timeCreated: 1611035810
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 466300df0840ba54d95240e3a800a642
|
||||
timeCreated: 1611373988
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,252 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
static class NativeMethods {
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct MONITORINFO {
|
||||
public int cbSize;
|
||||
public RECT rcMonitor;
|
||||
public RECT rcWork;
|
||||
public uint dwFlags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT {
|
||||
public int Left, Top, Right, Bottom;
|
||||
|
||||
public RECT(int left, int top, int right, int bottom) {
|
||||
Left = left;
|
||||
Top = top;
|
||||
Right = right;
|
||||
Bottom = bottom;
|
||||
}
|
||||
|
||||
public int X {
|
||||
get { return Left; }
|
||||
set {
|
||||
Right -= (Left - value);
|
||||
Left = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Y {
|
||||
get { return Top; }
|
||||
set {
|
||||
Bottom -= (Top - value);
|
||||
Top = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Height {
|
||||
get { return Bottom - Top; }
|
||||
set { Bottom = value + Top; }
|
||||
}
|
||||
|
||||
public int Width {
|
||||
get { return Right - Left; }
|
||||
set { Right = value + Left; }
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetTouchInputInfo(IntPtr hTouchInput, int cInputs, [Out] TOUCHINPUT[] pInputs, int cbSize);
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TOUCHINPUT {
|
||||
public int x;
|
||||
public int y;
|
||||
public IntPtr hSource;
|
||||
public int dwID;
|
||||
public TOUCHINPUT_Flags dwFlags;
|
||||
public TOUCHINPUT_Mask dwMask;
|
||||
public int dwTime;
|
||||
public IntPtr dwExtraInfo;
|
||||
public int cxContact;
|
||||
public int cyContact;
|
||||
}
|
||||
[Flags]
|
||||
public enum TOUCHINPUT_Flags : int {
|
||||
TOUCHEVENTF_MOVE = 0x0001,
|
||||
TOUCHEVENTF_DOWN = 0x0002,
|
||||
TOUCHEVENTF_UP = 0x0004,
|
||||
TOUCHEVENTF_INRANGE = 0x0008,
|
||||
TOUCHEVENTF_PRIMARY = 0x0010,
|
||||
TOUCHEVENTF_NOCOALESCE = 0x0020,
|
||||
TOUCHEVENTF_PEN = 0x0040,
|
||||
TOUCHEVENTF_PALM = 0x0080,
|
||||
}
|
||||
[Flags]
|
||||
public enum TOUCHINPUT_Mask : int {
|
||||
TOUCHINPUTMASKF_CONTACTAREA = 0x0004,
|
||||
TOUCHINPUTMASKF_EXTRAINFO = 0x0002,
|
||||
TOUCHINPUTMASKF_TIMEFROMSYSTEM = 0x0001,
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetPointerInfo(int pointerID, ref POINTER_INFO pPointerInfo);
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct POINTER_INFO {
|
||||
public POINTER_INPUT_TYPE pointerType;
|
||||
public UInt32 pointerId;
|
||||
public UInt32 frameId;
|
||||
public POINTER_FLAGS pointerFlags;
|
||||
public IntPtr sourceDevice;
|
||||
public IntPtr hwndTarget;
|
||||
public POINT ptPixelLocation;
|
||||
public POINT ptHimetricLocation;
|
||||
public POINT ptPixelLocationRaw;
|
||||
public POINT ptHimetricLocationRaw;
|
||||
public UInt32 dwTime;
|
||||
public UInt32 historyCount;
|
||||
public Int32 inputData;
|
||||
public UInt32 dwKeyStates;
|
||||
public UInt64 PerformanceCount;
|
||||
public POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
|
||||
}
|
||||
public enum POINTER_INPUT_TYPE {
|
||||
PT_POINTER = 0x00000001,
|
||||
PT_TOUCH = 0x00000002,
|
||||
PT_PEN = 0x00000003,
|
||||
PT_MOUSE = 0x00000004,
|
||||
PT_TOUCHPAD = 0x00000005,
|
||||
}
|
||||
[Flags]
|
||||
public enum POINTER_FLAGS {
|
||||
POINTER_FLAG_NONE = 0x00000000,
|
||||
POINTER_FLAG_NEW = 0x00000001,
|
||||
POINTER_FLAG_INRANGE = 0x00000002,
|
||||
POINTER_FLAG_INCONTACT = 0x00000004,
|
||||
POINTER_FLAG_FIRSTBUTTON = 0x00000010,
|
||||
POINTER_FLAG_SECONDBUTTON = 0x00000020,
|
||||
POINTER_FLAG_THIRDBUTTON = 0x00000040,
|
||||
POINTER_FLAG_FOURTHBUTTON = 0x00000080,
|
||||
POINTER_FLAG_FIFTHBUTTON = 0x00000100,
|
||||
POINTER_FLAG_PRIMARY = 0x00002000,
|
||||
POINTER_FLAG_CONFIDENCE = 0x00004000,
|
||||
POINTER_FLAG_CANCELED = 0x00008000,
|
||||
POINTER_FLAG_DOWN = 0x00010000,
|
||||
POINTER_FLAG_UPDATE = 0x00020000,
|
||||
POINTER_FLAG_UP = 0x00040000,
|
||||
POINTER_FLAG_WHEEL = 0x00080000,
|
||||
POINTER_FLAG_HWHEEL = 0x00100000,
|
||||
POINTER_FLAG_CAPTURECHANGED = 0x00200000,
|
||||
POINTER_FLAG_HASTRANSFORM = 0x00400000,
|
||||
}
|
||||
public enum POINTER_BUTTON_CHANGE_TYPE {
|
||||
POINTER_CHANGE_NONE,
|
||||
POINTER_CHANGE_FIRSTBUTTON_DOWN,
|
||||
POINTER_CHANGE_FIRSTBUTTON_UP,
|
||||
POINTER_CHANGE_SECONDBUTTON_DOWN,
|
||||
POINTER_CHANGE_SECONDBUTTON_UP,
|
||||
POINTER_CHANGE_THIRDBUTTON_DOWN,
|
||||
POINTER_CHANGE_THIRDBUTTON_UP,
|
||||
POINTER_CHANGE_FOURTHBUTTON_DOWN,
|
||||
POINTER_CHANGE_FOURTHBUTTON_UP,
|
||||
POINTER_CHANGE_FIFTHBUTTON_DOWN,
|
||||
POINTER_CHANGE_FIFTHBUTTON_UP,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINT {
|
||||
public int X;
|
||||
public int Y;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetPointerTouchInfo(int pointerId, ref POINTER_TOUCH_INFO touchInfo);
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINTER_TOUCH_INFO {
|
||||
public POINTER_INFO pointerInfo;
|
||||
public TOUCH_FLAGS touchFlags;
|
||||
public TOUCH_MASK touchMask;
|
||||
public RECT rcContact;
|
||||
public RECT rcContactRaw;
|
||||
public uint orientation;
|
||||
public uint pressure;
|
||||
}
|
||||
[Flags]
|
||||
public enum TOUCH_FLAGS {
|
||||
TOUCH_FLAG_NONE = 0x00000000,
|
||||
}
|
||||
[Flags]
|
||||
public enum TOUCH_MASK {
|
||||
TOUCH_MASK_NONE = 0x00000000,
|
||||
TOUCH_MASK_CONTACTAREA = 0x00000001,
|
||||
TOUCH_MASK_ORIENTATION = 0x00000002,
|
||||
TOUCH_MASK_PRESSURE = 0x00000004,
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr EnableMouseInPointer(bool value);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern uint GetCurrentThreadId();
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
|
||||
public delegate bool EnumWindowsProc(IntPtr hWnd,IntPtr lParam);
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool EnumThreadWindows(uint dwThreadId, EnumWindowsProc lpEnumFunc, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SetWindowLong")]
|
||||
public static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
|
||||
public static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint msg, IntPtr wParam,
|
||||
IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool RegisterTouchWindow(IntPtr hWnd, TOUCH_WINDOW_FLAGS ulFlags);
|
||||
[Flags]
|
||||
public enum TOUCH_WINDOW_FLAGS {
|
||||
TWF_FINETOUCH = 1,
|
||||
TWF_WANTPALM = 2,
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool UnregisterTouchWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern void CloseTouchInputHandle(IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
|
||||
|
||||
[DllImport("Kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern ushort GlobalAddAtom(string lpString);
|
||||
|
||||
[DllImport("Kernel32.dll")]
|
||||
public static extern ushort GlobalDeleteAtom(ushort nAtom);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int SetProp(IntPtr hWnd, string lpString, int hData);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int RemoveProp(IntPtr hWnd, string lpString);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern uint QueryPerformanceFrequency(out Int64 lpFrequency);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern uint QueryPerformanceCounter(out Int64 lpPerformanceCount);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6ff72ea2b7f71345aa19940faf026e8
|
||||
timeCreated: 1622589747
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,49 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public class SimpleInputConsumer {
|
||||
readonly InputManager _manager;
|
||||
readonly object _lock = new object();
|
||||
readonly Dictionary<InputIdentifier, InputVector> _vectors = new Dictionary<InputIdentifier, InputVector>();
|
||||
readonly List<InputEvent> _events = new List<InputEvent>();
|
||||
public SimpleInputConsumer(InputManager manager) { _manager = manager; }
|
||||
public void Activate() {
|
||||
lock (_lock) {
|
||||
_events.Clear();
|
||||
}
|
||||
_manager.EnumerateHandlers(h => h.OnInput += OnInput);
|
||||
}
|
||||
public void Deactivate() {
|
||||
_manager.EnumerateHandlers(h => h.OnInput -= OnInput);
|
||||
}
|
||||
protected void OnInput(InputIdentifier id, InputVector vec) {
|
||||
lock (_lock) {
|
||||
InputVector vec0;
|
||||
if (_vectors.TryGetValue(id, out vec0)) {
|
||||
_events.Add(new InputEvent {
|
||||
Id = id,
|
||||
From = vec0,
|
||||
To = vec,
|
||||
});
|
||||
if (vec.IsNull) _vectors.Remove(id);
|
||||
else _vectors[id] = vec;
|
||||
}
|
||||
else {
|
||||
_events.Add(new InputEvent {
|
||||
Id = id,
|
||||
From = new InputVector(vec.Time),
|
||||
To = vec,
|
||||
});
|
||||
_vectors.Add(id, vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void EnumerateEvents(Action<InputEvent> cb) {
|
||||
lock (_lock) {
|
||||
foreach (var ev in _events) cb(ev);
|
||||
_events.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public static class UnityCameraUtils {
|
||||
public static Vector2 ScreenToWorldPoint(Vector2 pos) {
|
||||
Vector3 i = pos;
|
||||
i.z = -Camera.main.transform.localPosition.z;
|
||||
i = Camera.main.ScreenToWorldPoint(i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93f60577ebaa5824dba5f322bbd1ad26
|
||||
timeCreated: 1618910605
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1b353deb73c51b409b15e54c54a6bb1
|
||||
timeCreated: 1611282071
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -623,7 +623,7 @@ namespace Cryville.Crtr {
|
||||
judge = new Judge(this, pruleset);
|
||||
etor.ContextJudge = judge;
|
||||
|
||||
inputProxy = new InputProxy(pruleset, judge);
|
||||
inputProxy = new InputProxy(pruleset, judge, screenSize);
|
||||
inputProxy.LoadFrom(_rscfg.inputs);
|
||||
if (!inputProxy.IsCompleted()) {
|
||||
throw new ArgumentException("Input config not completed\nPlease complete the input settings");
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Cryville.Crtr.Config {
|
||||
|
||||
m_genericConfigPanel.Target = _rscfg.generic;
|
||||
|
||||
var proxy = new InputProxy(ruleset.Root, null);
|
||||
var proxy = new InputProxy(ruleset.Root, null, new Vector2(Screen.width, Screen.height));
|
||||
proxy.LoadFrom(_rscfg.inputs);
|
||||
m_inputConfigPanel.proxy = proxy;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Unity;
|
||||
using Cryville.Common.Unity.Input;
|
||||
using Cryville.Input;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
@@ -77,7 +77,7 @@ namespace Cryville.Crtr.Config {
|
||||
void Update() {
|
||||
if (m_inputDialog.activeSelf) {
|
||||
_consumer.EnumerateEvents(ev => {
|
||||
AddSourceItem(ev.Id.Source);
|
||||
AddSourceItem(ev.Identifier.Source);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ namespace Cryville.Crtr.Config {
|
||||
if (proxy.IsUsed(tsrc)) {
|
||||
text.text += " <size=9>(Used)</size>";
|
||||
}
|
||||
else if (tsrc.Handler.GetDimension(src.Value.Type) < m_configScene.ruleset.Root.inputs[_sel].dim) {
|
||||
else if (tsrc.Handler.Dimension < m_configScene.ruleset.Root.inputs[_sel].dim) {
|
||||
text.text += " <size=9>(Not Applicable)</size>";
|
||||
}
|
||||
else flag = true;
|
||||
|
||||
@@ -6,6 +6,7 @@ using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
using Logger = Cryville.Common.Logging.Logger;
|
||||
using unity = UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class Console : MonoBehaviour {
|
||||
@@ -36,8 +37,8 @@ namespace Cryville.Crtr {
|
||||
|
||||
void Update() {
|
||||
if (
|
||||
Input.GetKeyDown(KeyCode.Return)
|
||||
|| Input.GetKeyDown(KeyCode.KeypadEnter)
|
||||
unity::Input.GetKeyDown(KeyCode.Return)
|
||||
|| unity::Input.GetKeyDown(KeyCode.KeypadEnter)
|
||||
) {
|
||||
Submit();
|
||||
InputBox.text = "";
|
||||
|
||||
@@ -3,8 +3,10 @@ using Cryville.Audio.Source;
|
||||
using Cryville.Common.Font;
|
||||
using Cryville.Common.Logging;
|
||||
using Cryville.Common.Unity;
|
||||
using Cryville.Common.Unity.Input;
|
||||
using Cryville.Common.Unity.UI;
|
||||
using Cryville.Input;
|
||||
using Cryville.Input.Unity;
|
||||
using Cryville.Input.Unity.Android;
|
||||
using FFmpeg.AutoGen;
|
||||
using Ionic.Zip;
|
||||
using Newtonsoft.Json;
|
||||
@@ -12,6 +14,7 @@ using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using Logger = Cryville.Common.Logging.Logger;
|
||||
using unity = UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public static class Game {
|
||||
@@ -58,7 +61,21 @@ namespace Cryville.Crtr {
|
||||
|
||||
GameDataPath = Settings.Default.GameDataPath;
|
||||
|
||||
Input.simulateMouseWithTouches = false;
|
||||
unity::Input.simulateMouseWithTouches = false;
|
||||
//InputManager.HandlerRegistries.Add(typeof(AndroidAccelerometerHandler));
|
||||
//InputManager.HandlerRegistries.Add(typeof(AndroidAccelerometerUncalibratedHandler));
|
||||
//InputManager.HandlerRegistries.Add(typeof(AndroidGameRotationVectorHandler));
|
||||
//InputManager.HandlerRegistries.Add(typeof(AndroidGravityHandler));
|
||||
//InputManager.HandlerRegistries.Add(typeof(AndroidGyroscopeHandler));
|
||||
//InputManager.HandlerRegistries.Add(typeof(AndroidLinearAccelerationHandler));
|
||||
//InputManager.HandlerRegistries.Add(typeof(AndroidMagneticFieldHandler));
|
||||
//InputManager.HandlerRegistries.Add(typeof(AndroidMagneticFieldUncalibratedHandler));
|
||||
//InputManager.HandlerRegistries.Add(typeof(AndroidRotationVectorHandler));
|
||||
InputManager.HandlerRegistries.Add(typeof(AndroidTouchHandler));
|
||||
InputManager.HandlerRegistries.Add(typeof(UnityGuiInputHandler<UnityKeyReceiver>));
|
||||
InputManager.HandlerRegistries.Add(typeof(UnityGuiInputHandler<UnityMouseReceiver>));
|
||||
InputManager.HandlerRegistries.Add(typeof(UnityMouseHandler));
|
||||
InputManager.HandlerRegistries.Add(typeof(UnityTouchHandler));
|
||||
InputManager = new InputManager();
|
||||
|
||||
#if UNITY_EDITOR_WIN
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Logging;
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Common.Reflection;
|
||||
using Cryville.Common.Unity.Input;
|
||||
using Cryville.Crtr.Config;
|
||||
using Cryville.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using RVector3 = UnityEngine.Vector3;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
using Logger = Cryville.Common.Logging.Logger;
|
||||
using RVector4 = UnityEngine.Vector4;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class InputProxy : IDisposable {
|
||||
readonly PdtEvaluator _etor;
|
||||
readonly PdtRuleset _ruleset;
|
||||
readonly Judge _judge;
|
||||
public InputProxy(PdtRuleset ruleset, Judge judge) {
|
||||
readonly InputVector _screenSize;
|
||||
public InputProxy(PdtRuleset ruleset, Judge judge, Vector2 screenSize) {
|
||||
for (int i = 0; i <= MAX_DEPTH; i++) {
|
||||
var vecsrc = new InputVectorSrc();
|
||||
_vecsrcs[i] = vecsrc;
|
||||
@@ -23,6 +26,7 @@ namespace Cryville.Crtr {
|
||||
_etor = judge != null ? judge._etor : ChartPlayer.etor;
|
||||
_ruleset = ruleset;
|
||||
_judge = judge;
|
||||
_screenSize = new InputVector(screenSize.x, screenSize.y);
|
||||
foreach (var i in ruleset.inputs) {
|
||||
_use.Add(i.Key, 0);
|
||||
_rev.Add(i.Key, new List<Identifier>());
|
||||
@@ -42,10 +46,15 @@ namespace Cryville.Crtr {
|
||||
public event EventHandler<ProxyChangedEventArgs> ProxyChanged;
|
||||
public void LoadFrom(Dictionary<string, RulesetConfig.InputEntry> config) {
|
||||
foreach (var cfg in config) {
|
||||
var handler = Game.InputManager.GetHandlerByTypeName(cfg.Value.handler);
|
||||
if (handler == null) {
|
||||
Logger.Log("main", 3, "Input", "Uninitialized or unknown handler in ruleset config: {0}", cfg.Value.handler);
|
||||
continue;
|
||||
}
|
||||
Set(new InputProxyEntry {
|
||||
Target = new Identifier(cfg.Key),
|
||||
Source = new InputSource {
|
||||
Handler = Game.InputManager.GetHandler(cfg.Value.handler),
|
||||
Handler = handler,
|
||||
Type = cfg.Value.type
|
||||
}
|
||||
});
|
||||
@@ -55,7 +64,7 @@ namespace Cryville.Crtr {
|
||||
config.Clear();
|
||||
foreach (var p in _tproxies) {
|
||||
config.Add((string)p.Key.Name, new RulesetConfig.InputEntry {
|
||||
handler = TypeNameHelper.GetNamespaceQualifiedName(p.Value.Source.Value.Handler.GetType()),
|
||||
handler = p.Value.Source.Value.Handler.GetType().AssemblyQualifiedName,
|
||||
type = p.Value.Source.Value.Type
|
||||
});
|
||||
}
|
||||
@@ -176,7 +185,7 @@ namespace Cryville.Crtr {
|
||||
|
||||
static readonly int _var_value = IdentifierManager.Shared.Request("value");
|
||||
const int MAX_DEPTH = 15;
|
||||
const int MAX_DIMENSION = 3;
|
||||
const int MAX_DIMENSION = 4;
|
||||
readonly InputVectorSrc[] _vecsrcs = new InputVectorSrc[MAX_DEPTH + 1];
|
||||
readonly InputVectorOp[] _vecops = new InputVectorOp[MAX_DEPTH + 1];
|
||||
unsafe class InputVectorSrc : PropSrc.FixedBuffer {
|
||||
@@ -186,9 +195,9 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
public bool IsNull { get; set; }
|
||||
public void Set(RVector3 vec) {
|
||||
public void Set(RVector4 vec) {
|
||||
fixed (byte* _ptr = buf) {
|
||||
*(RVector3*)_ptr = vec;
|
||||
*(RVector4*)_ptr = vec;
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
@@ -204,7 +213,7 @@ namespace Cryville.Crtr {
|
||||
_src.IsNull = true;
|
||||
}
|
||||
else {
|
||||
var vec = new RVector3();
|
||||
var vec = new RVector4();
|
||||
int dim;
|
||||
if (op.Type == PdtInternalType.Number) dim = 1;
|
||||
else if (op.Type == PdtInternalType.Vector) {
|
||||
@@ -228,19 +237,32 @@ namespace Cryville.Crtr {
|
||||
readonly Dictionary<InputIdentifier, float> _vect = new Dictionary<InputIdentifier, float>();
|
||||
readonly Dictionary<ProxiedInputIdentifier, PropSrc> _vecs = new Dictionary<ProxiedInputIdentifier, PropSrc>();
|
||||
double? _lockTime = null;
|
||||
unsafe void OnInput(InputIdentifier id, InputVector vec) {
|
||||
lock (_etor) {
|
||||
unsafe void OnInput(InputIdentifier id, InputFrame frame) {
|
||||
var rc = id.Source.Handler.ReferenceCue;
|
||||
if (rc.RelativeUnit == RelativeUnit.Pixel) {
|
||||
frame = rc.InverseTransform(frame, _screenSize);
|
||||
var vec = frame.Vector;
|
||||
vec.X /= _screenSize.X; vec.Y /= _screenSize.Y;
|
||||
vec.X -= 0.5f; vec.Y -= 0.5f;
|
||||
vec.X *= ChartPlayer.hitRect.width; vec.Y *= ChartPlayer.hitRect.height;
|
||||
frame.Vector = vec;
|
||||
}
|
||||
else frame = rc.InverseTransform(frame);
|
||||
bool locked = false;
|
||||
try {
|
||||
Profiler.BeginSample("InputProxy.OnInput");
|
||||
Monitor.Enter(_etor, ref locked);
|
||||
InputProxyEntry proxy;
|
||||
if (_sproxies.TryGetValue(id.Source, out proxy)) {
|
||||
_etor.ContextCascadeInsert();
|
||||
float ft, tt = (float)(_lockTime != null ? _lockTime.Value : (vec.Time - _timeOrigins[id.Source.Handler]));
|
||||
float ft, tt = (float)(_lockTime != null ? _lockTime.Value : (frame.Time - _timeOrigins[id.Source.Handler]));
|
||||
if (!_vect.TryGetValue(id, out ft)) ft = tt;
|
||||
if (vec.IsNull) {
|
||||
if (frame.IsNull) {
|
||||
_etor.ContextCascadeUpdate(_var_value, PropSrc.Null);
|
||||
OnInput(id, proxy.Target, ft, tt, true);
|
||||
}
|
||||
else {
|
||||
_vecsrcs[0].Set(vec.Vector);
|
||||
_vecsrcs[0].Set(new RVector4(frame.Vector.X, frame.Vector.Y, frame.Vector.Z, frame.Vector.W));
|
||||
_etor.ContextCascadeUpdate(_var_value, _vecsrcs[0]);
|
||||
OnInput(id, proxy.Target, ft, tt, false);
|
||||
}
|
||||
@@ -248,6 +270,10 @@ namespace Cryville.Crtr {
|
||||
_etor.ContextCascadeDiscard();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (locked) Monitor.Exit(_etor);
|
||||
Profiler.EndSample();
|
||||
}
|
||||
}
|
||||
static readonly int _var_fv = IdentifierManager.Shared.Request("input_vec_from");
|
||||
static readonly int _var_tv = IdentifierManager.Shared.Request("input_vec_to");
|
||||
@@ -295,7 +321,7 @@ namespace Cryville.Crtr {
|
||||
foreach (var s in _sproxies) {
|
||||
var src = s.Key;
|
||||
if (_activeCounts[src] == 0) {
|
||||
OnInput(new InputIdentifier { Source = src, Id = 0 }, new InputVector(_lockTime != null ? _lockTime.Value : src.Handler.GetCurrentTimestamp()));
|
||||
OnInput(new InputIdentifier { Source = src, Id = 0 }, new InputFrame(_lockTime != null ? _lockTime.Value : src.Handler.GetCurrentTimestamp()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Cryville.Crtr.Browsing;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using unity = UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class Menu : MonoBehaviour {
|
||||
@@ -45,7 +46,7 @@ namespace Cryville.Crtr {
|
||||
m_targetAnimator.SetTrigger("T_Main");
|
||||
}
|
||||
}
|
||||
if (Input.GetKeyDown(KeyCode.Escape)) {
|
||||
if (unity::Input.GetKeyDown(KeyCode.Escape)) {
|
||||
if (m_targetAnimator != null) Back();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
"name": "Cryville.Crtr",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:0bb40a8a1701f13479c68e3659a99bfd",
|
||||
"GUID:ae5eee924eae80345b704d2b7de05cc0",
|
||||
"GUID:5686e5ee69d0e084c843d61c240d7fdb",
|
||||
"GUID:13ba8ce62aa80c74598530029cb2d649",
|
||||
"GUID:2922aa74af3b2854e81b8a8b286d8206",
|
||||
|
||||
18
Assets/Plugins/Android/AndroidManifest.xml
Normal file
18
Assets/Plugins/Android/AndroidManifest.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.unity3d.player"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<application>
|
||||
<activity
|
||||
android:name="com.unity3d.player.UnityPlayerActivity"
|
||||
android:theme="@style/UnityThemeSelector">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
|
||||
</activity>
|
||||
</application>
|
||||
<uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS" />
|
||||
</manifest>
|
||||
7
Assets/Plugins/Android/AndroidManifest.xml.meta
Normal file
7
Assets/Plugins/Android/AndroidManifest.xml.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10f1d59c7d7d3354c9e06e18c37d6c46
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Plugins/Android/arm64-v8a/libAndroidInputProxy.so
Normal file
BIN
Assets/Plugins/Android/arm64-v8a/libAndroidInputProxy.so
Normal file
Binary file not shown.
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1fae26592ef751f47993715f379faed4
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: ARM64
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Plugins/Android/armeabi-v7a/libAndroidInputProxy.so
Normal file
BIN
Assets/Plugins/Android/armeabi-v7a/libAndroidInputProxy.so
Normal file
Binary file not shown.
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4328ea0ce04f49844a91172367c83c6c
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7548d5a078795b04b8c54524389ba0fe
|
||||
guid: 4406fa823b7746b47a76d810f5bedf6c
|
||||
folderAsset: yes
|
||||
timeCreated: 1611035780
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Input.Unity.Android {
|
||||
public abstract class AndroidInputHandler<TSelf> : InputHandler where TSelf : AndroidInputHandler<TSelf> {
|
||||
protected static TSelf Instance { get; private set; }
|
||||
|
||||
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;
|
||||
|
||||
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();
|
||||
|
||||
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");
|
||||
|
||||
NativeMethods.AndroidInputProxy_RegisterCallback(
|
||||
AndroidJNI.CallIntMethod(_i_T, _m_T_getId, _p_void),
|
||||
Callback
|
||||
);
|
||||
}
|
||||
|
||||
protected override void Activate() {
|
||||
if (_activated) return;
|
||||
_activated = true;
|
||||
AndroidJNI.CallVoidMethod(_i_T, _m_T_activate, _p_void);
|
||||
}
|
||||
|
||||
protected override void Deactivate() {
|
||||
if (!_activated) return;
|
||||
_activated = false;
|
||||
AndroidJNI.CallVoidMethod(_i_T, _m_T_deactivate, _p_void);
|
||||
}
|
||||
|
||||
public override void Dispose(bool disposing) {
|
||||
if (disposing) {
|
||||
Deactivate();
|
||||
AndroidJNI.DeleteGlobalRef(_i_T);
|
||||
AndroidJNI.DeleteGlobalRef(_t_T);
|
||||
}
|
||||
}
|
||||
|
||||
private protected abstract AndroidInputProxy_Callback Callback { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fd2d5f1c7ba0c74c9ce8775075750db
|
||||
guid: ed308f7b1ca3ed443b6eea2559c103c8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user