@@ -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
0 commit comments