Skip to content

Commit

Permalink
Update according discussion
Browse files Browse the repository at this point in the history
Make interface IQueryComponentInformation internal for now (since not used for calling),
make ComponentInformation read-only, remove argument from QueryComponentInformation.
  • Loading branch information
pgrawehr committed Oct 29, 2022
1 parent 94e04af commit 535755c
Show file tree
Hide file tree
Showing 13 changed files with 106 additions and 41 deletions.
4 changes: 4 additions & 0 deletions src/System.Device.Gpio/System.Device.Gpio.csproj
Expand Up @@ -66,5 +66,9 @@
<Compile Remove="System\Device\Spi\SpiDevice.Windows.cs" />

</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<!-- Need this for record support in older runtimes -->
<Compile Remove="System\Device\IsExternalInit.cs" />
</ItemGroup>

</Project>
46 changes: 37 additions & 9 deletions src/System.Device.Gpio/System/Device/ComponentInformation.cs
Expand Up @@ -3,6 +3,9 @@

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;

Expand All @@ -23,6 +26,11 @@ public ComponentInformation(object instance, string name, string version)
{
}

public ComponentInformation(object instance, string name, ComponentState state)
: this(instance, name, string.Empty, state)
{
}

public ComponentInformation(object instance, string name, string version, ComponentState componentState)
{
if (instance == null)
Expand All @@ -35,6 +43,18 @@ public ComponentInformation(object instance, string name, string version, Compon

Version = version;
State = componentState;

if (string.IsNullOrWhiteSpace(Version))
{
var assembly = instance.GetType().Assembly;
var v = (AssemblyInformationalVersionAttribute?)assembly.GetCustomAttributes().FirstOrDefault(x => x is AssemblyInformationalVersionAttribute);

if (v != null)
{
Version = v.InformationalVersion;
}
}

_subComponents = new List<ComponentInformation>();
}

Expand All @@ -45,20 +65,17 @@ public string Type

public string Name
{
get;
set;
get; init;
}

public string Version
{
get;
set;
get; init;
}

public ComponentState State
{
get;
set;
get; init;
}

public IReadOnlyList<ComponentInformation> SubComponents => _subComponents.AsReadOnly();
Expand All @@ -73,23 +90,34 @@ public void AddSubComponent(ComponentInformation subComponent)
_subComponents.Add(subComponent);
}

private static string PrintComponentDescription(ComponentInformation component)
{
string v = string.Empty;
if (!string.IsNullOrWhiteSpace(component.Version))
{
v = $" Version {component.Version}";
}

return $"{{{component.Type}}} {component.Name}{v}{Environment.NewLine}";
}

protected virtual void SubComponentToString(StringBuilder output, int ident)
{
foreach (var component in _subComponents)
{
output.Append(new string(' ', ident));
output.Append('\u2514'); // border element
output.Append($"{{{component.Type}}} {component.Name}{Environment.NewLine}");
output.Append(PrintComponentDescription(component));
component.SubComponentToString(output, ident + 1);
}
}

public override string ToString()
{
StringBuilder b = new StringBuilder($"{{{Type}}} {Name}{Environment.NewLine}");
StringBuilder b = new StringBuilder(PrintComponentDescription(this));
SubComponentToString(b, 1);

return b.ToString();
return b.ToString().TrimEnd();
}
}
}
Expand Up @@ -281,8 +281,8 @@ protected override void Dispose(bool disposing)
}

/// <inheritdoc />
public override ComponentInformation QueryComponentInformation(bool onlyActive)
public override ComponentInformation QueryComponentInformation()
{
return _internalDriver.QueryComponentInformation(onlyActive);
return _internalDriver.QueryComponentInformation();
}
}
Expand Up @@ -766,7 +766,7 @@ protected override void Dispose(bool disposing)
}

/// <inheritdoc />
public override ComponentInformation QueryComponentInformation(bool onlyActive)
public override ComponentInformation QueryComponentInformation()
{
StringBuilder sb = new StringBuilder();
Initialize();
Expand All @@ -789,7 +789,7 @@ public override ComponentInformation QueryComponentInformation(bool onlyActive)

if (_interruptDriver != null)
{
ci.AddSubComponent(_interruptDriver.QueryComponentInformation(onlyActive));
ci.AddSubComponent(_interruptDriver.QueryComponentInformation());
}

return ci;
Expand Down
9 changes: 2 additions & 7 deletions src/System.Device.Gpio/System/Device/Gpio/GpioController.cs
Expand Up @@ -480,21 +480,16 @@ private static GpioDriver GetBestDriverForBoardOnWindows()
}

/// <inheritdoc />
public virtual ComponentInformation QueryComponentInformation(bool onlyActive)
public virtual ComponentInformation QueryComponentInformation()
{
ComponentInformation self = new ComponentInformation(this, "Generic GPIO Controller", string.Empty, ComponentState.Active);

if (_driver != null)
{
ComponentInformation driverInfo = _driver.QueryComponentInformation(onlyActive);
ComponentInformation driverInfo = _driver.QueryComponentInformation();
self.AddSubComponent(driverInfo);
}

if (!onlyActive)
{
// ...
}

return self;
}
}
2 changes: 1 addition & 1 deletion src/System.Device.Gpio/System/Device/Gpio/GpioDriver.cs
Expand Up @@ -144,7 +144,7 @@ protected virtual void Dispose(bool disposing)
}

/// <inheritdoc />
public virtual ComponentInformation QueryComponentInformation(bool onlyActive)
public virtual ComponentInformation QueryComponentInformation()
{
return new ComponentInformation(this, "Gpio Driver", string.Empty, ComponentState.Active);
}
Expand Down
Expand Up @@ -9,14 +9,14 @@ namespace System.Device
{
/// <summary>
/// Interface to support querying component information from a class
/// (declared internal for now, since it doesn't need exposing as long as the callers operate on the actual type of the components)
/// </summary>
public interface IQueryComponentInformation
internal interface IQueryComponentInformation
{
/// <summary>
/// Query information about a component and it's children.
/// </summary>
/// <param name="onlyActive">True to return only active components, false to also list possible alternatives or inactive drivers</param>
/// <returns>A tree of <see cref="ComponentInformation"/> instances.</returns>
public ComponentInformation QueryComponentInformation(bool onlyActive);
public ComponentInformation QueryComponentInformation();
}
}
22 changes: 22 additions & 0 deletions src/System.Device.Gpio/System/Device/IsExternalInit.cs
@@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.ComponentModel;

namespace System.Runtime.CompilerServices
{
/// <summary>
/// Reserved to be used by the compiler for tracking metadata.
/// This class should not be used by developers in source code.
/// This dummy class is required to compile records when targeting .NET Standard
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
#if BUILDING_IOT_DEVICE_BINDINGS
internal
#else
public
#endif
static class IsExternalInit
{
}
}
12 changes: 6 additions & 6 deletions src/devices/Board/Board.cs
Expand Up @@ -22,7 +22,7 @@ namespace Iot.Device.Board
/// There should be exactly one instance of a board class per hardware component in an application, but it is possible to work with multiple boards
/// at once (i.e. when having a GPIO expander connected to the Raspberry Pi)
/// </summary>
public abstract class Board : MarshalByRefObject, IDisposable, IQueryComponentInformation
public abstract class Board : MarshalByRefObject, IDisposable
{
// See comment at GetBestDriverForBoardOnWindows. This should get some specific factory pattern
private const string BaseBoardProductRegistryValue = @"SYSTEM\HardwareConfig\Current\BaseBoardProduct";
Expand Down Expand Up @@ -642,19 +642,19 @@ public static Board Create()
return board;
}

/// <inheritdoc />
public virtual ComponentInformation QueryComponentInformation(bool onlyActive)
/// <inheritdoc cref="GpioController.QueryComponentInformation"/>
public virtual ComponentInformation QueryComponentInformation()
{
ComponentInformation self = new ComponentInformation(this, "Generic Board", string.Empty, ComponentState.Active);
ComponentInformation self = new ComponentInformation(this, "Generic Board", ComponentState.Active);

var controller = CreateGpioController();

var controllerInfo = controller.QueryComponentInformation(onlyActive);
var controllerInfo = controller.QueryComponentInformation();
self.AddSubComponent(controllerInfo);

foreach (var e in _i2cBuses)
{
self.AddSubComponent(e.Value.QueryComponentInformation(onlyActive));
self.AddSubComponent(e.Value.QueryComponentInformation());
}

return self;
Expand Down
11 changes: 11 additions & 0 deletions src/devices/Board/CustomBoard.cs
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Device;
using System.Device.Gpio;
using System.Device.I2c;
using System.Device.Pwm;
Expand Down Expand Up @@ -70,5 +71,15 @@ protected override PwmChannel CreateSimplePwmChannel(int chip, int channel, int
{
return _pwmChannelCreator(channel);
}

/// <inheritdoc />
public override ComponentInformation QueryComponentInformation()
{
var ret = base.QueryComponentInformation();
return ret with
{
Name = "Custom Board"
};
}
}
}
11 changes: 7 additions & 4 deletions src/devices/Board/I2cBusManager.cs
Expand Up @@ -13,7 +13,7 @@ namespace Iot.Device.Board
/// <summary>
/// Manages an I2C bus instance
/// </summary>
public class I2cBusManager : I2cBus, IDisposable, IQueryComponentInformation
public class I2cBusManager : I2cBus, IDisposable
{
private readonly int _sdaPin;
private readonly int _sclPin;
Expand Down Expand Up @@ -123,10 +123,13 @@ protected override void Dispose(bool disposing)
base.Dispose(disposing);
}

/// <inheritdoc />
public ComponentInformation QueryComponentInformation(bool onlyActive)
/// <summary>
/// Query the component information (the tree of active drivers) for diagnostic purposes.
/// </summary>
/// <returns>A <see cref="ComponentInformation"/> instance</returns>
public ComponentInformation QueryComponentInformation()
{
return new ComponentInformation(this, $"I2C Bus Manager, Bus number {_bus}", string.Empty, ComponentState.Active);
return new ComponentInformation(this, $"I2C Bus Manager, Bus number {_bus}", ComponentState.Active);
}
}
}
12 changes: 7 additions & 5 deletions src/devices/Board/RaspberryPiBoard.cs
Expand Up @@ -9,6 +9,7 @@
using System.Device.I2c;
using System.Device.Pwm;
using System.Device.Spi;
using System.IO;
using System.Text;

namespace Iot.Device.Board
Expand Down Expand Up @@ -534,12 +535,13 @@ protected override void Dispose(bool disposing)
}

/// <inheritdoc />
public override ComponentInformation QueryComponentInformation(bool onlyActive)
public override ComponentInformation QueryComponentInformation()
{
ComponentInformation self = base.QueryComponentInformation(onlyActive);
self.Name = "Raspberry Pi Board";

return self;
ComponentInformation self = base.QueryComponentInformation();
return self with
{
Name = "Raspberry Pi"
};
}
}
}
4 changes: 2 additions & 2 deletions src/devices/Board/samples/Program.cs
Expand Up @@ -43,7 +43,7 @@ private static void WindowsDesktop()
const int led2 = 2;
using Board b = Board.Create();
Console.WriteLine("Hardware detected: ");
Console.WriteLine(b.QueryComponentInformation(true));
Console.WriteLine(b.QueryComponentInformation());
using GpioController controller = b.CreateGpioController();

if (controller.PinCount > 0)
Expand Down Expand Up @@ -133,7 +133,7 @@ private static void RaspberryPiTest()
{
using var raspi = Board.Create();
Console.WriteLine("Hardware detected: ");
Console.WriteLine(raspi.QueryComponentInformation(true));
Console.WriteLine(raspi.QueryComponentInformation());
PwmRaspiTest(raspi);
SpiRaspiTestWithSoftwareCs(raspi);
SpiRaspiTestWithHardwareCs(raspi);
Expand Down

0 comments on commit 535755c

Please sign in to comment.