From d748e102411443f255a26d962d2a701f856f4c2d Mon Sep 17 00:00:00 2001 From: SDraw Date: Wed, 1 Jun 2022 10:22:22 +0300 Subject: [PATCH] Update to LeapCSharp 5.9.0 --- ml_lme_cvr/Main.cs | 21 +-- ml_lme_cvr/Properties/AssemblyInfo.cs | 6 +- ml_lme_cvr/ml_lme_cvr.csproj | 2 +- ml_lme_cvr/ml_lme_cvr.csproj.user | 2 +- ml_lme_cvr/vendor/LeapCSharp/Connection.cs | 159 +++++++++++++++--- ml_lme_cvr/vendor/LeapCSharp/Controller.cs | 103 ++++++++++-- ml_lme_cvr/vendor/LeapCSharp/Device.cs | 24 ++- ml_lme_cvr/vendor/LeapCSharp/DeviceList.cs | 32 ++++ ml_lme_cvr/vendor/LeapCSharp/Events.cs | 27 +++ ml_lme_cvr/vendor/LeapCSharp/IController.cs | 7 + ml_lme_cvr/vendor/LeapCSharp/MemoryManager.cs | 10 +- 11 files changed, 341 insertions(+), 52 deletions(-) diff --git a/ml_lme_cvr/Main.cs b/ml_lme_cvr/Main.cs index 4dc91dd..cdd6834 100644 --- a/ml_lme_cvr/Main.cs +++ b/ml_lme_cvr/Main.cs @@ -21,7 +21,8 @@ public class LeapMotionExtension : MelonLoader.MelonMod public override void OnApplicationStart() { - ms_instance = this; + if(ms_instance == null) + ms_instance = this; DependenciesHandler.ExtractDependencies(); @@ -137,11 +138,11 @@ void OnSettingsEnableChange() if(Settings.Enabled) { m_leapController.StartConnection(); - m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_SCREENTOP); + m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_SCREENTOP, null); if(Settings.HmdMode) - m_leapController.SetPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD); + m_leapController.SetPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD, null); else - m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD); + m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD, null); } else m_leapController.StopConnection(); @@ -177,11 +178,11 @@ void OnSettingsHmdModeChange() { if(m_leapController != null) { - m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_SCREENTOP); + m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_SCREENTOP, null); if(Settings.HmdMode) - m_leapController.SetPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD); + m_leapController.SetPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD, null); else - m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD); + m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD, null); } if(m_leapControllerModel != null) @@ -249,11 +250,11 @@ void OnLeapDeviceInitialized(object p_sender, Leap.DeviceEventArgs p_args) { if(Settings.Enabled && (m_leapController != null)) { - m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_SCREENTOP); + m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_SCREENTOP, null); if(Settings.HmdMode) - m_leapController.SetPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD); + m_leapController.SetPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD, null); else - m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD); + m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD, null); } if(CohtmlHud.Instance != null) diff --git a/ml_lme_cvr/Properties/AssemblyInfo.cs b/ml_lme_cvr/Properties/AssemblyInfo.cs index 87549d8..3264695 100644 --- a/ml_lme_cvr/Properties/AssemblyInfo.cs +++ b/ml_lme_cvr/Properties/AssemblyInfo.cs @@ -1,10 +1,10 @@ using System.Reflection; [assembly: AssemblyTitle("LeapMotionExtension")] -[assembly: AssemblyVersion("1.0.4")] -[assembly: AssemblyFileVersion("1.0.4")] +[assembly: AssemblyVersion("1.0.5")] +[assembly: AssemblyFileVersion("1.0.5")] -[assembly: MelonLoader.MelonInfo(typeof(ml_lme_cvr.LeapMotionExtension), "LeapMotionExtension", "1.0.4", "SDraw", "https://github.com/SDraw/ml_mods_cvr")] +[assembly: MelonLoader.MelonInfo(typeof(ml_lme_cvr.LeapMotionExtension), "LeapMotionExtension", "1.0.5", "SDraw", "https://github.com/SDraw/ml_mods_cvr")] [assembly: MelonLoader.MelonGame(null, "ChilloutVR")] [assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)] [assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)] diff --git a/ml_lme_cvr/ml_lme_cvr.csproj b/ml_lme_cvr/ml_lme_cvr.csproj index eb42178..a906f0b 100644 --- a/ml_lme_cvr/ml_lme_cvr.csproj +++ b/ml_lme_cvr/ml_lme_cvr.csproj @@ -127,6 +127,6 @@ - copy /y "$(TargetPath)" "C:\Games\Steam\steamapps\common\ChilloutVR\Mods\ + copy /y "$(TargetPath)" "C:\Games\Steam\common\ChilloutVR\Mods\ \ No newline at end of file diff --git a/ml_lme_cvr/ml_lme_cvr.csproj.user b/ml_lme_cvr/ml_lme_cvr.csproj.user index 312c80c..2539084 100644 --- a/ml_lme_cvr/ml_lme_cvr.csproj.user +++ b/ml_lme_cvr/ml_lme_cvr.csproj.user @@ -1,6 +1,6 @@  - C:\Games\Steam\steamapps\common\ChilloutVR\MelonLoader\;C:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\ + C:\Games\Steam\common\ChilloutVR\MelonLoader\;C:\Games\Steam\common\ChilloutVR\ChilloutVR_Data\Managed\ \ No newline at end of file diff --git a/ml_lme_cvr/vendor/LeapCSharp/Connection.cs b/ml_lme_cvr/vendor/LeapCSharp/Connection.cs index 735dbc7..3c54b75 100644 --- a/ml_lme_cvr/vendor/LeapCSharp/Connection.cs +++ b/ml_lme_cvr/vendor/LeapCSharp/Connection.cs @@ -71,11 +71,21 @@ static Connection() private int _frameBufferLength = 60; //TODO, surface this value in LeapC, currently hardcoded! private IntPtr _leapConnection; - private bool _isRunning = false; + private volatile bool _isRunning = false; private Thread _polster; - //Policy and enabled features - private UInt64 _activePolicies = 0; + /// + /// Has the connection been set up in multi device aware mode + /// + private bool _multiDeviceAwareConnection = false; + + /// + /// Minimum service version that support setting the tracking mode on a per dervice basis + /// + private static LEAP_VERSION MinServiceVersionForMultiModeSupport = new LEAP_VERSION() { major = 5, minor = 4, patch = 4 }; + + //Policy and enabled features, indexed by device ID + private Dictionary _activePolicies = new Dictionary(); //Config change status private Dictionary _configRequests = new Dictionary(); @@ -173,6 +183,7 @@ public void Start(string serverNamespace = "Leap Service", bool multiDeviceAware config.server_namespace = Marshal.StringToHGlobalAnsi(serverNamespace); config.flags = multiDeviceAware ? (uint)eLeapConnectionFlag.eLeapConnectionFlag_MultipleDevicesAware : 0; config.size = (uint)Marshal.SizeOf(config); + _multiDeviceAwareConnection = multiDeviceAware; Start(config); } @@ -279,6 +290,7 @@ private void processMessages() LEAP_CONNECTION_MESSAGE _msg = new LEAP_CONNECTION_MESSAGE(); uint timeout = 150; + result = LeapC.PollConnection(_leapConnection, timeout, ref _msg); if (result != eLeapRS.eLeapRS_Success) @@ -325,9 +337,8 @@ private void processMessages() case eLeapEventType.eLeapEventType_Policy: LEAP_POLICY_EVENT policy_evt; StructMarshal.PtrToStruct(_msg.eventStructPtr, out policy_evt); - handlePolicyChange(ref policy_evt); + handlePolicyChange(ref policy_evt, _msg.deviceID); break; - case eLeapEventType.eLeapEventType_Tracking: LEAP_TRACKING_EVENT tracking_evt; StructMarshal.PtrToStruct(_msg.eventStructPtr, out tracking_evt); @@ -482,7 +493,16 @@ public void GetInterpolatedFrameFromTime(Frame toFill, Int64 time, Int64 sourceT public Frame GetInterpolatedFrame(Int64 time, Device device = null) { - Frame frame = new Frame(); + Frame frame; + if (device == null) + { + frame = new Frame(); + } + else + { + frame = new Frame(device.DeviceID); + } + GetInterpolatedFrame(frame, time, device); return frame; } @@ -638,7 +658,8 @@ private void handleDevice(ref LEAP_DEVICE_EVENT deviceMsg) (Device.DeviceType)deviceInfo.type, deviceInfo.status == (uint)eLeapDeviceStatus.eLeapDeviceStatus_Streaming, deviceInfo.status, - Marshal.PtrToStringAnsi(deviceInfo.serial)); + Marshal.PtrToStringAnsi(deviceInfo.serial), + deviceMsg.device.id); Marshal.FreeCoTaskMem(deviceInfo.serial); _devices.AddOrUpdate(apiDevice); @@ -663,6 +684,11 @@ private void handleLostDevice(ref LEAP_DEVICE_EVENT deviceMsg) { _devices.Remove(lost); + if (_activePolicies.ContainsKey(deviceMsg.device.id)) + { + _activePolicies.Remove(deviceMsg.device.id); + } + if (LeapDeviceLost != null) { LeapDeviceLost.DispatchOnContext(this, EventContext, new DeviceEventArgs(lost)); @@ -856,38 +882,117 @@ private void handleImage(ref LEAP_IMAGE_EVENT imageMsg, UInt32 deviceID) } } - private void handlePolicyChange(ref LEAP_POLICY_EVENT policyMsg) + private void handlePolicyChange(ref LEAP_POLICY_EVENT policyMsg, UInt32 deviceID) { // Avoid raising spurious policy change signals. - if (policyMsg.current_policy == _activePolicies) return; + if (_activePolicies.ContainsKey(deviceID)) + { + if (policyMsg.current_policy == _activePolicies[deviceID]) + { + return; + } + } if (LeapPolicyChange != null) { - LeapPolicyChange.DispatchOnContext(this, EventContext, new PolicyEventArgs(policyMsg.current_policy, _activePolicies)); + if (_activePolicies.ContainsKey(deviceID)) + { + LeapPolicyChange.DispatchOnContext(this, EventContext, + new PolicyEventArgs(policyMsg.current_policy, _activePolicies[deviceID], true, _devices.FindDeviceByID(deviceID))); + } + else + { + // We should get a policy flags event on device connection. This tells us the current policy. From our perspective we don't + // have a record of a 'previous' policy, so assume it's zero and raise an event + LeapPolicyChange.DispatchOnContext(this, EventContext, + new PolicyEventArgs(policyMsg.current_policy, 0, false, _devices.FindDeviceByID(deviceID))); + } } - _activePolicies = policyMsg.current_policy; + _activePolicies[deviceID] = policyMsg.current_policy; } - public void SetAndClearPolicy(Controller.PolicyFlag set, Controller.PolicyFlag clear) + public void SetAndClearPolicy(Controller.PolicyFlag set, Controller.PolicyFlag clear, Device device = null) { UInt64 setFlags = (ulong)FlagForPolicy(set); UInt64 clearFlags = (ulong)FlagForPolicy(clear); - eLeapRS result = LeapC.SetPolicyFlags(_leapConnection, setFlags, clearFlags); + eLeapRS result; + + if (device == null || !_multiDeviceAwareConnection) + { + result = LeapC.SetPolicyFlags(_leapConnection, setFlags, clearFlags); + } + else + { + if (!Controller.CheckRequiredServiceVersion(MinServiceVersionForMultiModeSupport, this)) + { + UnityEngine.Debug.LogWarning(String.Format("Your current tracking service does not support setting policy flags on a per device basis (min version is {0}.{1}.{2}). Please update your service: https://developer.leapmotion.com/tracking-software-download", + MinServiceVersionForMultiModeSupport.major, + MinServiceVersionForMultiModeSupport.minor, + MinServiceVersionForMultiModeSupport.patch)); + + return; + } + + result = LeapC.SetPolicyFlagsEx(_leapConnection, device.Handle, setFlags, clearFlags); + } + reportAbnormalResults("LeapC SetAndClearPolicy call was ", result); } - public void SetPolicy(Controller.PolicyFlag policy) + public void SetPolicy(Controller.PolicyFlag policy, Device device = null) { UInt64 setFlags = (ulong)FlagForPolicy(policy); - eLeapRS result = LeapC.SetPolicyFlags(_leapConnection, setFlags, 0); + + eLeapRS result; + + if (device == null || !_multiDeviceAwareConnection) + { + result = LeapC.SetPolicyFlags(_leapConnection, setFlags, 0); + } + else + { + if (!Controller.CheckRequiredServiceVersion(MinServiceVersionForMultiModeSupport, this)) + { + UnityEngine.Debug.LogWarning(String.Format("Your current tracking service does not support setting policy flags on a per device basis (min version is {0}.{1}.{2}). Please update your service: https://developer.leapmotion.com/tracking-software-download", + MinServiceVersionForMultiModeSupport.major, + MinServiceVersionForMultiModeSupport.minor, + MinServiceVersionForMultiModeSupport.patch)); + + return; + } + + result = LeapC.SetPolicyFlagsEx(_leapConnection, device.Handle, setFlags, 0); + } + reportAbnormalResults("LeapC SetPolicyFlags call was ", result); } - public void ClearPolicy(Controller.PolicyFlag policy) + public void ClearPolicy(Controller.PolicyFlag policy, Device device = null) { UInt64 clearFlags = (ulong)FlagForPolicy(policy); - eLeapRS result = LeapC.SetPolicyFlags(_leapConnection, 0, clearFlags); + + eLeapRS result; + + if (device == null || !_multiDeviceAwareConnection) + { + result = LeapC.SetPolicyFlags(_leapConnection, 0, clearFlags); + } + else + { + if (!Controller.CheckRequiredServiceVersion(MinServiceVersionForMultiModeSupport, this)) + { + UnityEngine.Debug.LogWarning(String.Format("Your current tracking service does not support clearing policy flags on a per device basis (min version is {0}.{1}.{2}). Please update your service: https://developer.leapmotion.com/tracking-software-download", + MinServiceVersionForMultiModeSupport.major, + MinServiceVersionForMultiModeSupport.minor, + MinServiceVersionForMultiModeSupport.patch)); + + return; + } + + result = LeapC.SetPolicyFlagsEx(_leapConnection, device.Handle, 0, clearFlags); + } + reportAbnormalResults("LeapC SetPolicyFlags call was ", result); } @@ -929,10 +1034,26 @@ static public eLeapPolicyFlag FlagForPolicy(Controller.PolicyFlag singlePolicy) /// /// @since 2.1.6 /// - public bool IsPolicySet(Controller.PolicyFlag policy) + public bool IsPolicySet(Controller.PolicyFlag policy, Device device = null) { UInt64 policyToCheck = (ulong)FlagForPolicy(policy); - return (_activePolicies & policyToCheck) == policyToCheck; + + uint deviceID = 0; + if (device != null) + { + deviceID = device.DeviceID; + } + + if (_activePolicies.ContainsKey(deviceID)) + { + return (_activePolicies[deviceID] & policyToCheck) == policyToCheck; + } + else + { + Logger.Log("Warning: an attempt has been made to check whether a policy flag is set for an unknown device"); + } + + return false; } public uint GetConfigValue(string config_key) diff --git a/ml_lme_cvr/vendor/LeapCSharp/Controller.cs b/ml_lme_cvr/vendor/LeapCSharp/Controller.cs index 6e5e7e3..4dfcfbb 100644 --- a/ml_lme_cvr/vendor/LeapCSharp/Controller.cs +++ b/ml_lme_cvr/vendor/LeapCSharp/Controller.cs @@ -514,10 +514,11 @@ public LEAP_VERSION ServiceVersion /// the argument minServiceVersion is smaller or equal to it /// /// The minimum service version to check against - /// - public bool CheckRequiredServiceVersion(LEAP_VERSION minServiceVersion) + /// The connection + /// True if the version of the running service is equal to or less than the minimum version specified + public static bool CheckRequiredServiceVersion(LEAP_VERSION minServiceVersion, Connection connection) { - LEAP_VERSION currentServiceVersion = _connection.GetCurrentServiceVersion(); + LEAP_VERSION currentServiceVersion = connection.GetCurrentServiceVersion(); // check that minServiceVersion is smaller or equal to the current service version if (minServiceVersion.major < currentServiceVersion.major) return true; @@ -529,6 +530,54 @@ public bool CheckRequiredServiceVersion(LEAP_VERSION minServiceVersion) return false; } + /// + /// Checks whether a minimum or required tracking service version is installed. + /// Gets the currently installed service version from the connection and checks whether + /// the argument minServiceVersion is smaller or equal to it + /// + /// The minimum service version to check against + /// True if the version of the running service is equal to or less than the minimum version specified + public bool CheckRequiredServiceVersion(LEAP_VERSION minServiceVersion) + { + return Controller.CheckRequiredServiceVersion(minServiceVersion, _connection); + } + + /// + /// Requests setting and clearing policy flags on a specific device + /// + /// A request to change a policy is subject to user approval and a policy + /// can be changed by the user at any time (using the Leap Motion settings dialog). + /// The desired policy flags must be set every time an application runs. + /// + /// Policy changes are completed asynchronously and, because they are subject + /// to user approval or system compatibility checks, may not complete successfully. Call + /// Controller.IsPolicySet() after a suitable interval to test whether + /// the change was accepted. + /// @since 2.1.6 (5.4.4 for specific device) + /// + public void SetAndClearPolicy(PolicyFlag set, PolicyFlag clear, string deviceSerial = "", Device device = null) + { + _connection.SetAndClearPolicy(set, clear, device); + } + + /// + /// Requests setting a policy on a specific device + /// + /// A request to change a policy is subject to user approval and a policy + /// can be changed by the user at any time (using the Leap Motion settings dialog). + /// The desired policy flags must be set every time an application runs. + /// + /// Policy changes are completed asynchronously and, because they are subject + /// to user approval or system compatibility checks, may not complete successfully. Call + /// Controller.IsPolicySet() after a suitable interval to test whether + /// the change was accepted. + /// @since 2.1.6 (5.4.4 for specific device) + /// + public void SetPolicy(PolicyFlag policy, Device device = null) + { + _connection.SetPolicy(policy, device); + } + /// /// Requests setting a policy. /// @@ -542,18 +591,28 @@ public bool CheckRequiredServiceVersion(LEAP_VERSION minServiceVersion) /// the change was accepted. /// @since 2.1.6 /// - public void SetAndClearPolicy(PolicyFlag set, PolicyFlag clear, string deviceSerial = "") + [Obsolete("Use the version of SetPolicy that also takes the device")] + public void SetPolicy(PolicyFlag policy) { - _connection.SetAndClearPolicy(set, clear); + SetPolicy(policy, null); } - public void SetPolicy(PolicyFlag policy) + /// + /// Requests clearing a policy on a specific device + /// + /// Policy changes are completed asynchronously and, because they are subject + /// to user approval or system compatibility checks, may not complete successfully. Call + /// Controller.IsPolicySet() after a suitable interval to test whether + /// the change was accepted. + /// @since 2.1.6 (5.4.4 for specific device) + /// + public void ClearPolicy(PolicyFlag policy, Device device = null) { - _connection.SetPolicy(policy); + _connection.ClearPolicy(policy, device); } /// - /// Requests clearing a policy. + /// Requests clearing a policy /// /// Policy changes are completed asynchronously and, because they are subject /// to user approval or system compatibility checks, may not complete successfully. Call @@ -561,13 +620,14 @@ public void SetPolicy(PolicyFlag policy) /// the change was accepted. /// @since 2.1.6 /// + [Obsolete("Use the version of ClearPolicy that also takes the device")] public void ClearPolicy(PolicyFlag policy) { - _connection.ClearPolicy(policy); + ClearPolicy(policy, null); } /// - /// Gets the active setting for a specific policy. + /// Gets the active setting for a specific device. /// /// Keep in mind that setting a policy flag is asynchronous, so changes are /// not effective immediately after calling setPolicyFlag(). In addition, a @@ -578,11 +638,30 @@ public void ClearPolicy(PolicyFlag policy) /// If the controller object is not connected to the Leap Motion software, then the default /// state for the selected policy is returned. /// - /// @since 2.1.6 + /// @since 2.1.6 (5.4.4 for specific device) /// + public bool IsPolicySet(PolicyFlag policy, Device device = null) + { + return _connection.IsPolicySet(policy, device); + } + + /// + /// Gets the active setting + /// + /// Keep in mind that setting a policy flag is asynchronous, so changes are + /// not effective immediately after calling setPolicyFlag(). In addition, a + /// policy request can be declined by the user. You should always set the + /// policy flags required by your application at startup and check that the + /// policy change request was successful after an appropriate interval. + /// + /// If the controller object is not connected to the Leap Motion software, then the default + /// state for the selected policy is returned. + /// + /// @since 2.1.6 + [Obsolete("Use the version of IsPolicySet that also takes the device")] public bool IsPolicySet(PolicyFlag policy) { - return _connection.IsPolicySet(policy); + return IsPolicySet(policy, null); } /// diff --git a/ml_lme_cvr/vendor/LeapCSharp/Device.cs b/ml_lme_cvr/vendor/LeapCSharp/Device.cs index 584a9d3..fdc31ce 100644 --- a/ml_lme_cvr/vendor/LeapCSharp/Device.cs +++ b/ml_lme_cvr/vendor/LeapCSharp/Device.cs @@ -49,7 +49,8 @@ public Device(IntPtr deviceHandle, DeviceType type, bool isStreaming, uint status, - string serialNumber) + string serialNumber, + uint deviceID) { Handle = deviceHandle; InternalHandle = internalHandle; @@ -60,9 +61,24 @@ public Device(IntPtr deviceHandle, Type = type; IsStreaming = isStreaming; SerialNumber = serialNumber; + DeviceID = deviceID; UpdateStatus((eLeapDeviceStatus)status); } + public Device(IntPtr deviceHandle, + IntPtr internalHandle, + float horizontalViewAngle, + float verticalViewAngle, + float range, + float baseline, + DeviceType type, + bool isStreaming, + uint status, + string serialNumber) : this(deviceHandle, internalHandle, horizontalViewAngle, + verticalViewAngle, range, baseline, type, isStreaming, status, serialNumber, 0) + { + } + /// /// For internal use only. /// @@ -228,6 +244,12 @@ public override string ToString() /// public string SerialNumber { get; private set; } + /// + /// Reports the ID assoicated with the device + /// + /// + public uint DeviceID { get; private set; } + /// /// Returns the internal status field of the current device /// diff --git a/ml_lme_cvr/vendor/LeapCSharp/DeviceList.cs b/ml_lme_cvr/vendor/LeapCSharp/DeviceList.cs index 127707c..5e13771 100644 --- a/ml_lme_cvr/vendor/LeapCSharp/DeviceList.cs +++ b/ml_lme_cvr/vendor/LeapCSharp/DeviceList.cs @@ -10,6 +10,7 @@ namespace Leap { using System; using System.Collections.Generic; + using System.Linq; /// /// The DeviceList class represents a list of Device objects. @@ -40,6 +41,20 @@ public Device FindDeviceByHandle(IntPtr deviceHandle) return null; } + /// + /// For internal use only. + /// + public Device FindDeviceByID(uint deviceID) + { + for (int d = 0; d < this.Count; d++) + { + if (this[d].DeviceID == deviceID) + return this[d]; + } + return null; + } + + [Obsolete("Multiple devices can now be streaming, use ActiveDevices instead.", false)] /// /// The device that is currently streaming tracking data. /// If no streaming devices are found, returns null @@ -66,6 +81,23 @@ public Device ActiveDevice } } + /// + /// The devices that are currently streaming tracking data. + /// If no streaming devices are found, returns null + /// + public IEnumerable ActiveDevices + { + get + { + for (int d = 0; d < Count; d++) + { + this[d].UpdateStatus(LeapInternal.eLeapDeviceStatus.eLeapDeviceStatus_Streaming); + } + + return this.Where(d => d.IsStreaming); + } + } + /// /// For internal use only. /// diff --git a/ml_lme_cvr/vendor/LeapCSharp/Events.cs b/ml_lme_cvr/vendor/LeapCSharp/Events.cs index e95ebf6..5671776 100644 --- a/ml_lme_cvr/vendor/LeapCSharp/Events.cs +++ b/ml_lme_cvr/vendor/LeapCSharp/Events.cs @@ -106,14 +106,41 @@ public LogEventArgs(MessageSeverity severity, Int64 timestamp, string message) : /// public class PolicyEventArgs : LeapEventArgs { + public PolicyEventArgs(UInt64 currentPolicies, UInt64 oldPolicies, bool oldPolicyIsValid, Device device) : base(LeapEvent.EVENT_POLICY_CHANGE) + { + this.currentPolicies = currentPolicies; + this.oldPolicies = oldPolicies; + this.device = device; + } + + [Obsolete("Use the constructor that takes the device and oldPolicyIsValid flag")] public PolicyEventArgs(UInt64 currentPolicies, UInt64 oldPolicies) : base(LeapEvent.EVENT_POLICY_CHANGE) { this.currentPolicies = currentPolicies; this.oldPolicies = oldPolicies; } + /// + /// Current policy flags + /// public UInt64 currentPolicies { get; set; } + + /// + /// Previous policy flags, if known + /// public UInt64 oldPolicies { get; set; } + + /// + /// Is the value for the old policy flags valid / known + /// @since 5.7.0 (plugin) + /// + public bool oldPolicyIsValid { get; set; } + + /// + /// The device associated with the policy flag change + /// @since 5.7.0 (plugin) + /// + public Device device { get; set; } } /// diff --git a/ml_lme_cvr/vendor/LeapCSharp/IController.cs b/ml_lme_cvr/vendor/LeapCSharp/IController.cs index fd2d236..62657eb 100644 --- a/ml_lme_cvr/vendor/LeapCSharp/IController.cs +++ b/ml_lme_cvr/vendor/LeapCSharp/IController.cs @@ -17,10 +17,17 @@ public interface IController : Frame GetTransformedFrame(LeapTransform trs, int history = 0); Frame GetInterpolatedFrame(Int64 time); + [Obsolete] void SetPolicy(Controller.PolicyFlag policy); + [Obsolete] void ClearPolicy(Controller.PolicyFlag policy); + [Obsolete] bool IsPolicySet(Controller.PolicyFlag policy); + void SetPolicy(Controller.PolicyFlag policy, Device device = null); + void ClearPolicy(Controller.PolicyFlag policy, Device device = null); + bool IsPolicySet(Controller.PolicyFlag policy, Device device = null); + long Now(); bool IsConnected { get; } diff --git a/ml_lme_cvr/vendor/LeapCSharp/MemoryManager.cs b/ml_lme_cvr/vendor/LeapCSharp/MemoryManager.cs index b462088..14529e8 100644 --- a/ml_lme_cvr/vendor/LeapCSharp/MemoryManager.cs +++ b/ml_lme_cvr/vendor/LeapCSharp/MemoryManager.cs @@ -47,8 +47,8 @@ public static class MemoryManager private static ConcurrentDictionary _activeMemory = new ConcurrentDictionary(); - private static ConcurrentDictionary> _pooledMemory = - new ConcurrentDictionary>(); + private static ConcurrentDictionary> _pooledMemory = + new ConcurrentDictionary>(); [MonoPInvokeCallback(typeof(Allocate))] public static IntPtr Pin(UInt32 size, eLeapAllocatorType typeHint, IntPtr state) @@ -63,11 +63,11 @@ public static IntPtr Pin(UInt32 size, eLeapAllocatorType typeHint, IntPtr state) }; //Attempt to find the pool that holds this type of allocation - Queue pool; + ConcurrentQueue pool; if (!_pooledMemory.TryGetValue(key, out pool)) { //Construct a new pool if none exists yet - pool = new Queue(); + pool = new ConcurrentQueue(); _pooledMemory[key] = pool; } @@ -75,7 +75,7 @@ public static IntPtr Pin(UInt32 size, eLeapAllocatorType typeHint, IntPtr state) object memory; if (EnablePooling && pool.Count > MinPoolSize) { - memory = pool.Dequeue(); + pool.TryDequeue(out memory); } else {