Skip to content
This repository has been archived by the owner on Apr 19, 2022. It is now read-only.

Add lazy initialization to AdcController #31

Merged
merged 1 commit into from
Nov 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions source/Windows.Devices.Adc/AdcChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@ namespace Windows.Devices.Adc
/// </summary>
public sealed class AdcChannel : IAdcChannel, IDisposable
{
// this is used as the lock object
// a lock is required because multiple threads can access the channel
[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
private readonly object _syncLock = new object();

[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
private readonly int _channelNumber;

[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
private AdcController _adcController;

// this is used as the lock object
// a lock is required because multiple threads can access the AdcChannel
private object _syncLock = new object();
[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
private bool _disposed;

internal AdcChannel(AdcController controller, int channelNumber)
{
Expand Down Expand Up @@ -63,7 +70,7 @@ public int ReadValue()
lock (_syncLock)
{
// check if pin has been disposed
if (_disposedValue) { throw new ObjectDisposedException(); }
if (_disposed) { throw new ObjectDisposedException(); }

return NativeReadValue();
}
Expand All @@ -72,16 +79,14 @@ public int ReadValue()
private void ThowIfDisposed()
{
// check if pin has been disposed
if (_disposedValue)
if (_disposed)
{
throw new ObjectDisposedException();
}
}

#region IDisposable Support

private bool _disposedValue;

private void Dispose(bool disposing)
{
if (_adcController != null)
Expand All @@ -93,7 +98,7 @@ private void Dispose(bool disposing)

}

_disposedValue = true;
_disposed = true;
}
}

Expand All @@ -104,7 +109,7 @@ public void Dispose()
{
lock (_syncLock)
{
if (!_disposedValue)
if (!_disposed)
{
Dispose(true);
GC.SuppressFinalize(this);
Expand Down
75 changes: 61 additions & 14 deletions source/Windows.Devices.Adc/AdcController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,66 @@ namespace Windows.Devices.Adc
/// </summary>
public sealed class AdcController : IAdcController
{
private readonly int _deviceId;
// this is used as the lock object
// a lock is required because multiple threads can access the AdcController
[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
private readonly object _syncLock = new object();

[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
private readonly int _controllerId;

[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
private AdcChannelMode _channelMode;

// need to store the ADC controllers that are open
internal static Hashtable s_deviceCollection = new Hashtable();
// backing field for DeviceCollection
[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
private Hashtable s_deviceCollection;

/// <summary>
/// Device collection associated with this <see cref="AdcController"/>.
/// </summary>
/// <remarks>
/// This collection is for internal use only.
/// </remarks>
internal Hashtable DeviceCollection
{
get
{
if (s_deviceCollection == null)
{
lock (_syncLock)
{
if (s_deviceCollection == null)
{
s_deviceCollection = new Hashtable();
}
}
}

return s_deviceCollection;
}

set
{
s_deviceCollection = value;
}
}

internal AdcController(string adcController)
{
// check if this device is already opened
if (!s_deviceCollection.Contains(adcController))
if (!AdcControllerManager.ControllersCollection.Contains(adcController))
josesimoes marked this conversation as resolved.
Show resolved Hide resolved
{
// the ADC id is an ASCII string with the format 'ADCn'
// need to grab 'n' from the string and convert that to the integer value from the ASCII code (do this by subtracting 48 from the char value)
_deviceId = adcController[3] - 48;
_controllerId = adcController[3] - '0';

// call native init to allow HAL/PAL inits related with ADC hardware
// this is also used to check if the requested ADC actually exists
NativeInit();

// add ADC controller to collection
s_deviceCollection.Add(adcController, this);
AdcControllerManager.ControllersCollection.Add(adcController, this);
}
else
{
Expand Down Expand Up @@ -121,18 +160,26 @@ public int ResolutionInBits {
/// </returns>
public static AdcController GetDefault()
{
string controllers = GetDeviceSelector();
string[] devices = controllers.Split(',');
string controllersAqs = GetDeviceSelector();
string[] controllers = controllersAqs.Split(',');

if(devices.Length > 0)
if(controllers.Length > 0)
{
if (s_deviceCollection.Contains(devices[0]))
//////////////////////////////////////////////////////////////////
// note that, by design, the default controller is //
// the first one in the collection returned from the native end //
//////////////////////////////////////////////////////////////////

if (AdcControllerManager.ControllersCollection.Contains(controllers[0]))
josesimoes marked this conversation as resolved.
Show resolved Hide resolved
{
// this is already open
return (AdcController)s_deviceCollection[devices[0]];
// controller is already open
return (AdcController)AdcControllerManager.ControllersCollection[controllers[0]];
}
else
{
// there is no controller yet, create one
return new AdcController(controllers[0]);
}

return new AdcController(devices[0]);
}

// the system has no ADC controller
Expand Down
48 changes: 48 additions & 0 deletions source/Windows.Devices.Adc/AdcControllerManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// Copyright (c) 2018 The nanoFramework project contributors
// See LICENSE file in the project root for full license information.
//

using System.Collections;

namespace Windows.Devices.Adc
{
internal sealed class AdcControllerManager
{
private static readonly object _syncLock = new object();

// backing field for ControllersCollection
// to store the controllers that are open
private static Hashtable s_controllersCollection;

/// <summary>
/// <see cref="AdcController"/> collection.
/// </summary>
/// <remarks>
/// This collection is for internal use only.
/// </remarks>
internal static Hashtable ControllersCollection
{
get
{
if (s_controllersCollection == null)
{
lock (_syncLock)
{
if (s_controllersCollection == null)
{
s_controllersCollection = new Hashtable();
}
}
}

return s_controllersCollection;
}

set
{
s_controllersCollection = value;
}
}
}
}
3 changes: 2 additions & 1 deletion source/Windows.Devices.Adc/Windows.Devices.Adc.nfproj
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
<Compile Include="AdcChannel.cs" />
<Compile Include="AdcChannelMode.cs" />
<Compile Include="AdcController.cs" />
<Compile Include="AdcControllerManager.cs" />
<Compile Include="IAdcChannel.cs" />
<Compile Include="IAdcController.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand Down Expand Up @@ -81,4 +82,4 @@
</PropertyGroup>
<Error Condition="!Exists('..\packages\Nerdbank.GitVersioning.2.2.33\build\Nerdbank.GitVersioning.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Nerdbank.GitVersioning.2.2.33\build\Nerdbank.GitVersioning.targets'))" />
</Target>
</Project>
</Project>