Skip to content

Commit

Permalink
Merge pull request #290 from Belphemur/fix_performance
Browse files Browse the repository at this point in the history
Fix performance
  • Loading branch information
Belphemur authored Jun 7, 2018
2 parents 8c32786 + b22da76 commit f7be786
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 23 deletions.
150 changes: 150 additions & 0 deletions SoundSwitch/Framework/Configuration/Device/DeviceInfoCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using NAudio.CoreAudioApi;

namespace SoundSwitch.Framework.Configuration.Device
{
public class DeviceInfoCollection : ICollection<DeviceInfo>
{
private readonly Dictionary<string, DeviceInfo> _deviceByName = new Dictionary<string, DeviceInfo>();
private readonly Dictionary<string, DeviceInfo> _deviceById = new Dictionary<string, DeviceInfo>();

private readonly HashSet<DeviceInfo> _original;

public DeviceInfoCollection(HashSet<DeviceInfo> devices)
{
_original = devices;
foreach (var deviceInfo in devices)
{
AddItem(deviceInfo);
}
}

/// <summary>
/// Intersect with MMDevices
/// </summary>
/// <param name="devices"></param>
/// <returns></returns>
public IEnumerable<MMDevice> IntersectWith(IEnumerable<MMDevice> devices)
{
var devicesResult = new Dictionary<string, MMDevice>();
foreach (var mmDevice in devices)
{
if (devicesResult.ContainsKey(mmDevice.ID))
continue;

if (!_deviceById.ContainsKey(mmDevice.ID) && !_deviceByName.ContainsKey(mmDevice.FriendlyName))
continue;

devicesResult.Add(mmDevice.ID, mmDevice);

}

return devicesResult.Values;

}

public IEnumerator<DeviceInfo> GetEnumerator()
{
return _deviceById.Values.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

public void Add(DeviceInfo item)
{
AddItem(item, true);
}

/// <summary>
/// Add Item and update or not the original
/// </summary>
/// <param name="item"></param>
/// <param name="updateOriginal"></param>
private void AddItem(DeviceInfo item, bool updateOriginal = false)
{
if (item == null)
{
return;
}

try
{
_deviceById.Add(item.Id, item);
}
catch (ArgumentException)
{
}

try
{
_deviceByName.Add(item.Name, item);
}
catch (ArgumentException)
{
}

if (updateOriginal)
{
_original.Add(item);
}
}

public void Clear()
{
_deviceById.Clear();
_deviceByName.Clear();
_original.Clear();
}

public bool Contains(DeviceInfo item)
{
return item != null && (_deviceById.ContainsKey(item.Id) || _deviceByName.ContainsKey(item.Name));
}

public void CopyTo(DeviceInfo[] array, int arrayIndex)
{
throw new System.NotImplementedException();
}

public bool Remove(DeviceInfo item)
{
if (item == null)
{
return false;
}

var result = _original.RemoveWhere((info => info?.Id == item.Id || info?.Name == item.Name)) > 0;

try
{
result &= _deviceById.Remove(item.Id);
}
catch (ArgumentException)
{

}

try
{
result &= _deviceByName.Remove(item.Name);
}
catch (ArgumentException)
{

}

return result;
}

public int Count => _deviceById.Count;

public bool IsReadOnly => false;
}
}
55 changes: 37 additions & 18 deletions SoundSwitch/Model/AppModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ private AppModel()
public TrayIcon TrayIcon { get; set; }
private CachedSound _customNotificationCachedSound;
private readonly DeviceCyclerManager _deviceCyclerManager;
private DeviceInfoCollection _deviceSelectedList;



public CachedSound CustomNotificationSound
{
Expand Down Expand Up @@ -102,15 +105,23 @@ public bool IncludeBetaVersions
}


public HashSet<DeviceInfo> SelectedDevices { get; } = AppConfigs.Configuration.SelectedDevices;
public DeviceInfoCollection SelectedDevices
{
get
{
if (_deviceSelectedList != null)
return _deviceSelectedList;
return _deviceSelectedList = new DeviceInfoCollection(AppConfigs.Configuration.SelectedDevices);
}
}

public ICollection<MMDevice> AvailablePlaybackDevices
{
get
{
using (var devices = ActiveAudioDeviceLister.GetPlaybackDevices())
{
return devices.Where((device) => SelectedDevices.Any((info => new DeviceInfo(device).Equals(info)))).ToList();
return SelectedDevices.IntersectWith(devices).ToList();
}
}
}
Expand All @@ -123,7 +134,7 @@ public ICollection<MMDevice> AvailableRecordingDevices
{
using (var devices = ActiveAudioDeviceLister.GetRecordingDevices())
{
return devices.Where((device) => SelectedDevices.Any((info => new DeviceInfo(device).Equals(info)))).ToList();
return SelectedDevices.IntersectWith(devices).ToList();
}
}
}
Expand Down Expand Up @@ -288,17 +299,19 @@ private int SaveState(object state)
/// <returns></returns>
public bool SelectDevice(MMDevice device)
{
var result = false;
DeviceListChanged eventChanged = null;
result = SelectedDevices.Add(new DeviceInfo(device));
eventChanged = new DeviceListChanged(SelectedDevices, (DeviceType)device.DataFlow);

if (result)
try
{
SelectedDeviceChanged?.Invoke(this, eventChanged);
AppConfigs.Configuration.Save();
SelectedDevices.Add(new DeviceInfo(device));
}
return result;
catch (ArgumentException)
{
return false;
}

SelectedDeviceChanged?.Invoke(this, new DeviceListChanged(SelectedDevices, (DeviceType)device.DataFlow));
AppConfigs.Configuration.Save();

return true;
}

/// <summary>
Expand All @@ -309,17 +322,23 @@ public bool SelectDevice(MMDevice device)
public bool UnselectDevice(MMDevice device)
{
var result = false;
var deviceToRemove = new DeviceInfo(device);
DeviceListChanged eventChanged = null;
result = SelectedDevices.RemoveWhere((info => info.Equals(deviceToRemove))) > 0;
eventChanged = new DeviceListChanged(SelectedDevices, (DeviceType)device.DataFlow);
try
{
result = SelectedDevices.Remove(new DeviceInfo(device));
}
catch (ArgumentException)
{
return false;
}

if (result)
{
SelectedDeviceChanged?.Invoke(this, eventChanged);
SelectedDeviceChanged?.Invoke(this,
new DeviceListChanged(SelectedDevices, (DeviceType) device.DataFlow));
AppConfigs.Configuration.Save();
}
return result;

return true;
}

#endregion
Expand Down
2 changes: 1 addition & 1 deletion SoundSwitch/Model/IAppModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public interface IAppModel
/// <summary>
/// Devices selected for Switching
/// </summary>
HashSet<DeviceInfo> SelectedDevices { get; }
DeviceInfoCollection SelectedDevices { get; }
/// <summary>
/// An union between the Active <see cref="IAudioDevice" /> of Windows and <see cref="SelectedPlaybackDevicesList" />
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions SoundSwitch/SoundSwitch.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@
<Compile Include="Framework\Banner\BannerData.cs" />
<Compile Include="Framework\Banner\BannerManager.cs" />
<Compile Include="Framework\Configuration\Device\DeviceInfo.cs" />
<Compile Include="Framework\Configuration\Device\DeviceInfoCollection.cs" />
<Compile Include="Framework\Configuration\IPCConfiguration.cs" />
<Compile Include="Framework\Configuration\AppConfigs.cs" />
<Compile Include="Framework\Configuration\ConfigurationManager.cs" />
Expand Down
8 changes: 4 additions & 4 deletions SoundSwitch/UI/Forms/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ public SettingsForm()

// Playback and Recording
var audioDeviceLister = new AudioDeviceLister(DeviceState.All);
PopulateAudioList(playbackListView, AppModel.Instance.SelectedDevices.Where((device) => device.Type == DataFlow.Render), audioDeviceLister.GetPlaybackDevices());
PopulateAudioList(recordingListView, AppModel.Instance.SelectedDevices.Where((device) => device.Type == DataFlow.Capture), audioDeviceLister.GetRecordingDevices());
PopulateAudioList(playbackListView, AppModel.Instance.SelectedDevices, audioDeviceLister.GetPlaybackDevices());
PopulateAudioList(recordingListView, AppModel.Instance.SelectedDevices, audioDeviceLister.GetRecordingDevices());

_loaded = true;
}
Expand Down Expand Up @@ -479,7 +479,7 @@ private ListViewItem GenerateListViewItem(MMDevice device, IEnumerable<DeviceInf
Tag = device
};
var selectedDevice = new DeviceInfo(device);
if (selected.Any((info => selectedDevice.Equals(info))))
if (selected.Contains(selectedDevice))
{
listViewItem.Checked = true;
listViewItem.Group = listView.Groups["selectedGroup"];
Expand Down Expand Up @@ -522,7 +522,7 @@ private void ListViewItemChecked(object sender, ItemCheckEventArgs e)
throw new ArgumentOutOfRangeException();
}
}
catch (Exception)
catch (Exception exception)
{
e.NewValue = e.CurrentValue;
}
Expand Down

0 comments on commit f7be786

Please sign in to comment.