Permalink
Browse files

Making devices that disappear, reappear with the same ID

For the Kiiroo ans XInput interfaces, the device list has been updated to leave the devices on the list, but with a (dissconnected) note next to them. If they reappear, they will continue to be used (assuming they are still selected).

Fixes #249
  • Loading branch information...
blackspherefollower authored and qdot committed Aug 24, 2017
1 parent 625a1b4 commit 33b2282fbdd8eaa678a82727256b1f629770be9d
@@ -1,14 +1,16 @@
using Buttplug.Core;
using Buttplug.Core.Messages;
using Buttplug.Server;
using JetBrains.Annotations;
using System;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using Buttplug.Core;
using Buttplug.Core.Messages;
using Buttplug.Server;
using JetBrains.Annotations;
using System.ComponentModel;
using System.Collections.Specialized;
namespace Buttplug.Components.Controls
{
@@ -17,8 +19,32 @@ namespace Buttplug.Components.Controls
/// </summary>
public partial class ButtplugDeviceControl : UserControl
{
private class DeviceList : ObservableCollection<ButtplugDeviceInfo>
public class DeviceListItem
{
public ButtplugDeviceInfo Info;
public bool Connected;
public DeviceListItem(ButtplugDeviceInfo aInfo)
{
Info = aInfo;
Connected = true;
}
public event PropertyChangedEventHandler PropertyChanged;
public override string ToString()
{
return $"{Info}" + (Connected ? string.Empty : " (disconnected)");
}
}
private class DeviceList : ObservableCollection<DeviceListItem>
{
public void UpdateList()
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
public event EventHandler<List<ButtplugDeviceInfo>> DeviceSelectionChanged;
@@ -54,16 +80,31 @@ private void OnMessageReceived(object aObj, MessageReceivedEventArgs aEvent)
switch (aEvent.Message)
{
case DeviceAdded m:
_devices.Add(new ButtplugDeviceInfo(m.DeviceIndex, m.DeviceName, m.DeviceMessages));
var devAdd = from dl in _devices
where dl.Info.Index == m.DeviceIndex
select dl;
if (devAdd.Any())
{
foreach (var dr in devAdd.ToList())
{
dr.Connected = true;
_devices.UpdateList();
}
}
else
{
_devices.Add(new DeviceListItem(new ButtplugDeviceInfo(m.DeviceIndex, m.DeviceName, m.DeviceMessages)));
}
break;
case DeviceRemoved d:
var device = from dl in _devices
where dl.Index == d.DeviceIndex
var devRem = from dl in _devices
where dl.Info.Index == d.DeviceIndex
select dl;
foreach (var dr in device.ToList())
foreach (var dr in devRem.ToList())
{
_devices.Remove(dr);
dr.Connected = false;
_devices.UpdateList();
}
break;
}
@@ -79,7 +120,10 @@ private void OperationCompletedHandler(object aObj, EventArgs aEvent)
private void SelectionChangedHandler(object aObj, EventArgs aEvent)
{
DeviceSelectionChanged?.Invoke(this, DeviceListBox.SelectedItems.Cast<ButtplugDeviceInfo>().ToList());
DeviceSelectionChanged?.Invoke(this,
DeviceListBox.SelectedItems.Cast<DeviceListItem>()
.Where(aLI => aLI.Connected)
.Select(aLI => aLI.Info).ToList());
}
private async void ScanButton_Click(object aSender, RoutedEventArgs aEvent)
@@ -13,6 +13,8 @@ public abstract class ButtplugDevice : IButtplugDevice
public string Identifier { get; }
public bool IsConnected { get { return !_isDisconnected; } }
[CanBeNull]
public event EventHandler DeviceRemoved;
@@ -13,6 +13,9 @@ public interface IButtplugDevice
[NotNull]
string Identifier { get; }
[NotNull]
bool IsConnected { get; }
[CanBeNull]
event EventHandler DeviceRemoved;
@@ -45,26 +45,26 @@ private static IEnumerable<string> GetAllowedMessageTypesAsStrings([NotNull] IBu
private void DeviceAddedHandler(object aObj, DeviceAddedEventArgs aEvent)
{
// If we get to 4 billion devices connected, this may be a problem.
var deviceIndex = (uint)Interlocked.Increment(ref _deviceIndexCounter);
// Devices can be turned off by the time they get to this point, at which point they end up null. Make sure the device isn't null.
if (aEvent.Device == null)
{
return;
}
var duplicates = from x in _devices.Values
where x.Identifier == aEvent.Device.Identifier
var duplicates = from x in _devices
where x.Value.Identifier == aEvent.Device.Identifier
select x;
if (duplicates.Any())
if (duplicates.Any() && (duplicates.Count() > 1 || duplicates.First().Value.IsConnected))
{
_bpLogger.Debug($"Already have device {aEvent.Device.Name} in Devices list");
return;
}
_bpLogger.Info($"Adding Device {aEvent.Device.Name} at index {deviceIndex}");
_devices.Add(deviceIndex, aEvent.Device);
// If we get to 4 billion devices connected, this may be a problem.
var deviceIndex = duplicates.Any() ? duplicates.First().Key : (uint)Interlocked.Increment(ref _deviceIndexCounter);
_bpLogger.Info((duplicates.Any() ? "Re-" : string.Empty) + $"Adding Device {aEvent.Device.Name} at index {deviceIndex}");
_devices[deviceIndex] = aEvent.Device;
aEvent.Device.DeviceRemoved += DeviceRemovedHandler;
var msg = new DeviceAdded(deviceIndex, aEvent.Device.Name, GetAllowedMessageTypesAsStrings(aEvent.Device).ToArray());
@@ -97,7 +97,6 @@ private void DeviceRemovedHandler(object aObj, EventArgs aEvent)
{
pair.Value.DeviceRemoved -= DeviceRemovedHandler;
_bpLogger.Info($"Device removed: {pair.Key} - {pair.Value.Name}");
_devices.Remove(pair.Key);
DeviceMessageReceived?.Invoke(this, new MessageReceivedEventArgs(new DeviceRemoved(pair.Key)));
}
}
@@ -141,6 +140,11 @@ public async Task<ButtplugMessage> SendMessage(ButtplugMessage aMsg)
var errorMsg = string.Empty;
foreach (var d in _devices.ToList())
{
if (!d.Value.IsConnected)
{
continue;
}
var r = await d.Value.ParseMessage(new StopDeviceCmd(d.Key, aMsg.Id));
if (r is Ok)
{
@@ -159,7 +163,7 @@ public async Task<ButtplugMessage> SendMessage(ButtplugMessage aMsg)
return new Error(errorMsg, Error.ErrorClass.ERROR_DEVICE, aMsg.Id);
case RequestDeviceList _:
_bpLogger.Debug("Got RequestDeviceList Message");
var msgDevices = _devices
var msgDevices = _devices.Where(aDevice => aDevice.Value.IsConnected)
.Select(aDevice => new DeviceMessageInfo(aDevice.Key, aDevice.Value.Name,
GetAllowedMessageTypesAsStrings(aDevice.Value).ToArray())).ToList();
return new DeviceList(msgDevices.ToArray(), id);

0 comments on commit 33b2282

Please sign in to comment.