Skip to content

Commit d9b4619

Browse files
author
Jasper van Bourgognie
committed
Refactored DeviceManager to be more generic for HackerSpecial
1 parent ebb915f commit d9b4619

File tree

4 files changed

+86
-266
lines changed

4 files changed

+86
-266
lines changed

Devices/DeviceManager.cs

Lines changed: 84 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@ public class DeviceManager
1717
{
1818
public event InterfaceChangeHandler InterfaceChanged;
1919
public event DeviceConnectHandler DeviceConnected;
20-
private IScope mainDevice = null;
21-
public IScope MainDevice { get { return mainDevice; } }
22-
public bool SmartScopeConnected { get { return mainDevice is SmartScope; } }
20+
private IDevice activeDevice = null;
21+
public IDevice ActiveDevice { get { return activeDevice; } }
2322
Thread pollThread;
2423
private List<IHardwareInterface> connectedList = new List<IHardwareInterface>(); //list of all connected devices, serial and type provided
25-
private List<IScope> deviceList = new List<IScope>(); // list of all devices which have actually been created.
2624

2725
public List<IHardwareInterface> ConnectedList { get { return this.connectedList; } }
26+
private Dictionary<Type, Type> InterfaceActivators = new Dictionary<Type, Type>() {
27+
{ typeof(DummyInterface), typeof(DummyScope) },
28+
{ typeof(ISmartScopeInterface), typeof(SmartScope) }
29+
};
2830

2931
#if WINDOWS
3032
Thread badDriverDetectionThread;
@@ -51,21 +53,43 @@ Context context
5153
#if ANDROID
5254
context,
5355
#endif
54-
null, null) { Start(); }
56+
null, null) { }
57+
58+
public DeviceManager(
59+
#if ANDROID
60+
Context context
61+
#endif
62+
DeviceConnectHandler deviceConnectHandler
63+
)
64+
: this(
65+
#if ANDROID
66+
context,
67+
#endif
68+
null, deviceConnectHandler) { }
5569

5670
public DeviceManager(
5771
#if ANDROID
5872
Context context,
5973
#endif
60-
InterfaceChangeHandler interfaceChangeHandler, DeviceConnectHandler deviceConnectHandler
74+
InterfaceChangeHandler interfaceChangeHandler, DeviceConnectHandler deviceConnectHandler,
75+
Dictionary<Type, Type> interfaceActivatorOverride = null
6176
)
6277
{
6378
#if ANDROID
6479
this.context = context;
6580
#endif
6681
this.DeviceConnected = deviceConnectHandler;
6782
this.InterfaceChanged = interfaceChangeHandler;
68-
83+
if (interfaceActivatorOverride != null)
84+
{
85+
foreach (var kvp in interfaceActivatorOverride)
86+
{
87+
if (kvp.Key is IHardwareInterface && kvp.Value is IDevice)
88+
{
89+
this.InterfaceActivators[kvp.Key] = kvp.Value;
90+
}
91+
}
92+
}
6993
connectedList.Add(DummyInterface.Generator);
7094
//FIXME: android should add audio-scope here!!!
7195
}
@@ -76,16 +100,16 @@ public void Start(bool async = true)
76100
pollThread.Name = "Devicemanager Startup poll";
77101

78102
//disable because of the crash by Wait
79-
//InterfaceManagerZeroConf.Instance.onConnect += OnHardwareConnect;
103+
//InterfaceManagerZeroConf.Instance.onConnect += OnInterfaceChanged;
80104
#if ANDROID
81105
InterfaceManagerXamarin.context = this.context;
82-
InterfaceManagerXamarin.Instance.onConnect += OnHardwareConnect;
106+
InterfaceManagerXamarin.Instance.onConnect += OnInterfaceChanged;
83107
#elif WINUSB
84-
InterfaceManagerWinUsb.Instance.onConnect += OnHardwareConnect;
108+
InterfaceManagerWinUsb.Instance.onConnect += OnInterfaceChanged;
85109
#elif IOS
86110
//Nothing for the moment
87111
#else
88-
InterfaceManagerLibUsb.Instance.onConnect += OnHardwareConnect;
112+
InterfaceManagerLibUsb.Instance.onConnect += OnInterfaceChanged;
89113
#endif
90114

91115
pollThread.Start();
@@ -111,13 +135,13 @@ private void PollUponStart()
111135

112136
public void Stop()
113137
{
114-
if (mainDevice != null)
115-
mainDevice.DataSourceScope.Stop();
138+
if (activeDevice != null && activeDevice is IScope)
139+
(activeDevice as IScope).DataSourceScope.Stop();
116140

117141
if(pollThread != null)
118142
pollThread.Join(100);
119143

120-
InterfaceManagerZeroConf.Instance.Destroy();
144+
//InterfaceManagerZeroConf.Instance.Destroy();
121145
#if ANDROID
122146
//Nothing to do here, just keeping same ifdef structure as above
123147
#elif WINDOWS
@@ -133,83 +157,84 @@ public void Stop()
133157
#endif
134158
}
135159

136-
private void OnHardwareConnect(IHardwareInterface hardwareInterface, bool connected)
160+
private void OnInterfaceChanged(IHardwareInterface hardwareInterface, bool connected)
137161
{
138162
if(connected) {
139163
connectedList.Add(hardwareInterface);
140164

141165
#if WINDOWS
142166
lastSmartScopeDetectedThroughWinUsb = DateTime.Now;
143-
Logger.Debug(String.Format("Update winusb detection time to {0}", lastSmartScopeDetectedThroughWinUsb));
144167
#endif
145-
146-
Logger.Debug("DeviceManager: calling connectHandler after new Connect event");
147168
}
148169
else
149170
{
150171
if (connectedList.Contains(hardwareInterface))
151172
connectedList.Remove(hardwareInterface);
152-
IScope device = deviceList.Where(x => x.HardwareInterface == hardwareInterface).FirstOrDefault();
153-
if (device != null)
154-
{
155-
//need to dispose smartscope here: when it's being unplugged
156-
Logger.Debug("DeviceManager: disposing device");
157-
if (device is SmartScope)
158-
(device as SmartScope).Dispose();
159-
160-
deviceList.Remove(device);
161-
}
162-
173+
163174
#if WINDOWS
164175
lastSmartScopeDetectedThroughWinUsb = null;
165176
#endif
166-
167-
Logger.Debug("DeviceManager: calling connectHandler after new Disconnect event");
168177
}
169178

179+
/* If application handles interface preferences, pass it the updated
180+
* list of connected interfaces for it to decide who to call SetActiveDevice
181+
* with
182+
*/
170183
if (InterfaceChanged != null)
171184
InterfaceChanged(this, connectedList);
185+
/* Else activate the lastly connected interface */
172186
else
173-
{
174-
//in case no event handlers are specified: connect real smartscope if none was active yet, or switch to dummymode
175-
if (connected && !(mainDevice is SmartScope))
176-
{
177-
//at this point, no real smartscope was attached, and a USB or ethernet scope was detected
178-
SwitchMainDevice(hardwareInterface);
179-
}
180-
else
181-
{
182-
SwitchMainDevice(null);
183-
}
184-
}
187+
SetActiveDevice(connectedList.Last());
185188
}
186189

187-
public void SwitchMainDevice(IHardwareInterface iface)
190+
public void SetActiveDevice(IHardwareInterface iface)
188191
{
189192
if (!connectedList.Contains(iface))
190193
return;
191194

192-
//when changing device -> first fire previous device
193-
if (mainDevice != null && mainDevice.HardwareInterface != iface)
195+
// Don't handle a second activation if the interface
196+
// has already been activated
197+
if (activeDevice != null && activeDevice.HardwareInterface == iface)
198+
return;
199+
200+
// Activate new device
201+
Type DeviceType = null;
202+
Type ifaceType = iface.GetType();
203+
foreach (Type t in this.InterfaceActivators.Keys)
194204
{
195-
if (DeviceConnected != null)
196-
DeviceConnected(mainDevice, false);
205+
if (ifaceType == t || ifaceType.IsSubclassOf(t) || ifaceType.GetInterfaces().Contains(t))
206+
{
207+
DeviceType = InterfaceActivators[t];
208+
break;
209+
}
197210
}
198211

199-
//activate new device
200-
if (iface is DummyInterface)
201-
mainDevice = new DummyScope(iface as DummyInterface);
202-
else if(iface is ISmartScopeInterface) //real SmartScope
212+
if (DeviceType == null)
203213
{
204-
//need to make sure a smartscope is created only once from an interface
205-
if (deviceList.Where(x => x.HardwareInterface == iface).Count() == 0)
206-
deviceList.Add(new SmartScope(iface as ISmartScopeInterface));
207-
208-
mainDevice = deviceList.Where(x => x.HardwareInterface == iface).First();
214+
Logger.Error("Unsupported interface type " + iface.GetType().FullName);
215+
return;
209216
}
210217

211-
if (DeviceConnected != null)
212-
DeviceConnected(mainDevice, true);
218+
try
219+
{
220+
IDevice newDevice = (IDevice)Activator.CreateInstance(DeviceType, iface);
221+
222+
if (activeDevice != null)
223+
{
224+
if (DeviceConnected != null)
225+
DeviceConnected(activeDevice, false);
226+
if (activeDevice is IDisposable)
227+
(activeDevice as IDisposable).Dispose();
228+
}
229+
230+
activeDevice = newDevice;
231+
if (DeviceConnected != null)
232+
DeviceConnected(activeDevice, true);
233+
}
234+
catch(Exception e)
235+
{
236+
Logger.Error("Failed to create device: " + e.Message);
237+
}
213238
}
214239

215240
#if WINDOWS

Devices/DummyScope.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ private struct DigitalTrigger {
178178

179179
#region constructor / initializer
180180

181-
internal DummyScope (DummyInterface iface) : base ()
181+
public DummyScope (DummyInterface iface) : base ()
182182
{
183183
this.hardwareInterface = iface;
184184
ChannelConfig = new Dictionary<AnalogChannel, DummyScopeChannelConfig>()

0 commit comments

Comments
 (0)