Skip to content

Commit 6fa39d1

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

File tree

4 files changed

+89
-268
lines changed

4 files changed

+89
-268
lines changed

Devices/DeviceManager.cs

Lines changed: 87 additions & 61 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,23 +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-
69-
connectedList.Add(DummyInterface.Generator);
70-
//FIXME: android should add audio-scope here!!!
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+
}
7193
}
7294

7395
public void Start(bool async = true)
@@ -76,18 +98,21 @@ public void Start(bool async = true)
7698
pollThread.Name = "Devicemanager Startup poll";
7799

78100
//disable because of the crash by Wait
79-
//InterfaceManagerZeroConf.Instance.onConnect += OnHardwareConnect;
101+
//InterfaceManagerZeroConf.Instance.onConnect += OnInterfaceChanged;
80102
#if ANDROID
81103
InterfaceManagerXamarin.context = this.context;
82-
InterfaceManagerXamarin.Instance.onConnect += OnHardwareConnect;
104+
InterfaceManagerXamarin.Instance.onConnect += OnInterfaceChanged;
83105
#elif WINUSB
84-
InterfaceManagerWinUsb.Instance.onConnect += OnHardwareConnect;
106+
InterfaceManagerWinUsb.Instance.onConnect += OnInterfaceChanged;
85107
#elif IOS
86108
//Nothing for the moment
87109
#else
88-
InterfaceManagerLibUsb.Instance.onConnect += OnHardwareConnect;
110+
InterfaceManagerLibUsb.Instance.onConnect += OnInterfaceChanged;
89111
#endif
90112

113+
OnInterfaceChanged(DummyInterface.Generator, true);
114+
//FIXME: android should add audio-scope here!!!
115+
91116
pollThread.Start();
92117

93118
if (!async)
@@ -111,13 +136,13 @@ private void PollUponStart()
111136

112137
public void Stop()
113138
{
114-
if (mainDevice != null)
115-
mainDevice.DataSourceScope.Stop();
139+
if (activeDevice != null && activeDevice is IScope)
140+
(activeDevice as IScope).DataSourceScope.Stop();
116141

117142
if(pollThread != null)
118143
pollThread.Join(100);
119144

120-
InterfaceManagerZeroConf.Instance.Destroy();
145+
//InterfaceManagerZeroConf.Instance.Destroy();
121146
#if ANDROID
122147
//Nothing to do here, just keeping same ifdef structure as above
123148
#elif WINDOWS
@@ -133,83 +158,84 @@ public void Stop()
133158
#endif
134159
}
135160

136-
private void OnHardwareConnect(IHardwareInterface hardwareInterface, bool connected)
161+
private void OnInterfaceChanged(IHardwareInterface hardwareInterface, bool connected)
137162
{
138163
if(connected) {
139164
connectedList.Add(hardwareInterface);
140165

141166
#if WINDOWS
142167
lastSmartScopeDetectedThroughWinUsb = DateTime.Now;
143-
Logger.Debug(String.Format("Update winusb detection time to {0}", lastSmartScopeDetectedThroughWinUsb));
144168
#endif
145-
146-
Logger.Debug("DeviceManager: calling connectHandler after new Connect event");
147169
}
148170
else
149171
{
150172
if (connectedList.Contains(hardwareInterface))
151173
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-
174+
163175
#if WINDOWS
164176
lastSmartScopeDetectedThroughWinUsb = null;
165177
#endif
166-
167-
Logger.Debug("DeviceManager: calling connectHandler after new Disconnect event");
168178
}
169179

180+
/* If application handles interface preferences, pass it the updated
181+
* list of connected interfaces for it to decide who to call SetActiveDevice
182+
* with
183+
*/
170184
if (InterfaceChanged != null)
171185
InterfaceChanged(this, connectedList);
186+
/* Else activate the lastly connected interface */
172187
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-
}
188+
SetActiveDevice(connectedList.Last());
185189
}
186190

187-
public void SwitchMainDevice(IHardwareInterface iface)
191+
public void SetActiveDevice(IHardwareInterface iface)
188192
{
189193
if (!connectedList.Contains(iface))
190194
return;
191195

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

199-
//activate new device
200-
if (iface is DummyInterface)
201-
mainDevice = new DummyScope(iface as DummyInterface);
202-
else if(iface is ISmartScopeInterface) //real SmartScope
213+
if (DeviceType == null)
203214
{
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();
215+
Logger.Error("Unsupported interface type " + iface.GetType().FullName);
216+
return;
209217
}
210218

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

215241
#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)