Progress on adding Description attribute and printing types at runtime

This commit is contained in:
Neil Dorin
2020-04-16 21:10:45 -06:00
parent c5232ca6b8
commit ae23eec005
13 changed files with 117 additions and 17 deletions

View File

@@ -81,10 +81,22 @@ namespace PepperDash.Essentials
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl); "Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator); }, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
LoadDeviceTypesFromFactories();
if (!Debug.DoNotLoadOnNextBoot) if (!Debug.DoNotLoadOnNextBoot)
GoWithLoad(); GoWithLoad();
} }
/// <summary>
/// Instantiates each of the device factories to load thier device types
/// </summary>
void LoadDeviceTypesFromFactories()
{
// Instantiate the Device Factories
new CoreDeviceFactory();
new DmDeviceFactory();
}
/// <summary> /// <summary>
@@ -291,9 +303,6 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
public void LoadDevices() public void LoadDevices()
{ {
// Instantiate the Device Factories
new CoreDeviceFactory();
// Build the processor wrapper class // Build the processor wrapper class
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor")); DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor"));

View File

@@ -15,6 +15,7 @@ namespace PepperDash.Essentials.Core
/// <summary> /// <summary>
/// Serves as a generic wrapper class for all styles of IBasicCommuncation ports /// Serves as a generic wrapper class for all styles of IBasicCommuncation ports
/// </summary> /// </summary>
[Description("Generic communication wrapper class for any IBasicCommunication type")]
public class GenericComm : ReconfigurableBridgableDevice public class GenericComm : ReconfigurableBridgableDevice
{ {
EssentialsControlPropertiesConfig PropertiesConfig; EssentialsControlPropertiesConfig PropertiesConfig;

View File

@@ -10,6 +10,7 @@ using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core.CrestronIO namespace PepperDash.Essentials.Core.CrestronIO
{ {
[Description("Wrapper class for the C2N-RTHS sensor")]
public class C2nRthsController : CrestronGenericBridgeableBaseDevice public class C2nRthsController : CrestronGenericBridgeableBaseDevice
{ {
private readonly C2nRths _device; private readonly C2nRths _device;

View File

@@ -15,6 +15,7 @@ namespace PepperDash.Essentials.Core
/// <summary> /// <summary>
/// Wrapper class for CEN-IO-DIGIN-104 digital input module /// Wrapper class for CEN-IO-DIGIN-104 digital input module
/// </summary> /// </summary>
[Description("Wrapper class for the CEN-IO-DIGIN-104 diginal input module")]
public class CenIoDigIn104Controller : EssentialsDevice, IDigitalInputPorts public class CenIoDigIn104Controller : EssentialsDevice, IDigitalInputPorts
{ {
public CenIoDi104 Di104 { get; private set; } public CenIoDi104 Di104 { get; private set; }

View File

@@ -10,6 +10,7 @@ using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core.CrestronIO namespace PepperDash.Essentials.Core.CrestronIO
{ {
[Description("Wrapper class for the Crestron StatusSign device")]
public class StatusSignController : CrestronGenericBridgeableBaseDevice public class StatusSignController : CrestronGenericBridgeableBaseDevice
{ {
private readonly StatusSign _device; private readonly StatusSign _device;

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Config;
@@ -12,6 +13,7 @@ namespace PepperDash.Essentials.Core
/// <summary> /// <summary>
/// Defines the basic needs for an EssentialsDevice to enable it to be build by an IDeviceFactory class /// Defines the basic needs for an EssentialsDevice to enable it to be build by an IDeviceFactory class
/// </summary> /// </summary>
[Description("The base Essentials Device Class")]
public abstract class EssentialsDevice : Device public abstract class EssentialsDevice : Device
{ {
protected EssentialsDevice(string key) protected EssentialsDevice(string key)
@@ -27,6 +29,40 @@ namespace PepperDash.Essentials.Core
} }
} }
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class DescriptionAttribute : Attribute
{
private string _Description;
public DescriptionAttribute(string description)
{
Debug.Console(2, "Setting Description: {0}", description);
_Description = description;
}
public string Description
{
get { return _Description; }
}
}
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class ConfigSnippetAttribute : Attribute
{
private string _ConfigSnippet;
public ConfigSnippetAttribute(string configSnippet)
{
Debug.Console(2, "Setting Description {0}", configSnippet);
_ConfigSnippet = configSnippet;
}
public string ConfigSnippet
{
get { return _ConfigSnippet; }
}
}
/// <summary> /// <summary>
/// Devices the basic needs for a Device Factory /// Devices the basic needs for a Device Factory
/// </summary> /// </summary>
@@ -46,7 +82,10 @@ namespace PepperDash.Essentials.Core
{ {
foreach (var typeName in TypeNames) foreach (var typeName in TypeNames)
{ {
DeviceFactory.AddFactoryForType(typeName.ToLower(), BuildDevice); Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
var attributes = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
string description = attributes[0].Description;
DeviceFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildDevice);
} }
} }

View File

@@ -5,6 +5,7 @@ using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.GeneralIO; using Crestron.SimplSharpPro.GeneralIO;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Config;
@@ -13,24 +14,51 @@ using PepperDash.Essentials.Core.Touchpanels;
namespace PepperDash.Essentials.Core namespace PepperDash.Essentials.Core
{ {
public class DeviceFactoryWrapper
{
public CType CType { get; set; }
public string Description { get; set; }
public Func<DeviceConfig, IKeyed> FactoryMethod { get; set; }
public DeviceFactoryWrapper()
{
CType = null;
Description = "Not Available";
}
}
public class DeviceFactory public class DeviceFactory
{ {
/// <summary> /// <summary>
/// A dictionary of factory methods, keyed by config types, added by plugins. /// A dictionary of factory methods, keyed by config types, added by plugins.
/// These methods are looked up and called by GetDevice in this class. /// These methods are looked up and called by GetDevice in this class.
/// </summary> /// </summary>
static Dictionary<string, Func<DeviceConfig, IKeyed>> FactoryMethods = static Dictionary<string, DeviceFactoryWrapper> FactoryMethods =
new Dictionary<string, Func<DeviceConfig, IKeyed>>(StringComparer.OrdinalIgnoreCase); new Dictionary<string, DeviceFactoryWrapper>(StringComparer.OrdinalIgnoreCase);
/// <summary> /// <summary>
/// Adds a plugin factory method /// Adds a plugin factory method
/// </summary> /// </summary>
/// <param name="dc"></param> /// <param name="dc"></param>
/// <returns></returns> /// <returns></returns>
public static void AddFactoryForType(string type, Func<DeviceConfig, IKeyed> method) public static void AddFactoryForType(string typeName, Func<DeviceConfig, IKeyed> method)
{ {
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", type); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
DeviceFactory.FactoryMethods.Add(type, method); DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method});
}
public static void AddFactoryForType(string typeName, string description, CType cType, Func<DeviceConfig, IKeyed> method)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
if(FactoryMethods.ContainsKey(typeName))
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to add type: '{0}'. Already exists in DeviceFactory", typeName);
return;
}
var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method };
DeviceFactory.FactoryMethods.Add(typeName, wrapper);
} }
/// <summary> /// <summary>
@@ -52,34 +80,45 @@ namespace PepperDash.Essentials.Core
if (FactoryMethods.ContainsKey(typeName)) if (FactoryMethods.ContainsKey(typeName))
{ {
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from plugin", dc.Type); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from plugin", dc.Type);
return FactoryMethods[typeName](dc); return FactoryMethods[typeName].FactoryMethod(dc);
} }
return null; return null;
} }
/// <summary> /// <summary>
/// Prints the type names fromt the FactoryMethods collection. /// Prints the type names and associated metadata from the FactoryMethods collection.
/// </summary> /// </summary>
/// <param name="command"></param> /// <param name="command"></param>
public static void GetDeviceFactoryTypes(string filter) public static void GetDeviceFactoryTypes(string filter)
{ {
List<string> typeNames = new List<string>(); Dictionary<string, DeviceFactoryWrapper> types = new Dictionary<string, DeviceFactoryWrapper>();
if (!string.IsNullOrEmpty(filter)) if (!string.IsNullOrEmpty(filter))
{ {
typeNames = FactoryMethods.Keys.Where(k => k.Contains(filter)).ToList(); types = FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value);
} }
else else
{ {
typeNames = FactoryMethods.Keys.ToList(); types = FactoryMethods;
} }
Debug.Console(0, "Device Types:"); Debug.Console(0, "Device Types:");
foreach (var type in typeNames) foreach (var type in types)
{ {
Debug.Console(0, "type: '{0}'", type); var description = type.Value.Description;
var cType = "Not Specified by Plugin";
if(type.Value.CType != null)
{
cType = type.Value.CType.FullName;
}
Debug.Console(0,
@"Type: '{0}'
CType: '{1}'
Description: {2}", type.Key, cType, description);
} }
} }
} }
@@ -91,6 +130,8 @@ namespace PepperDash.Essentials.Core
{ {
public CoreDeviceFactory() public CoreDeviceFactory()
{ {
Debug.Console(1, "Essentials.Core Factory Adding Types...");
var genCommFactory = new GenericCommFactory() as IDeviceFactory; var genCommFactory = new GenericCommFactory() as IDeviceFactory;
genCommFactory.LoadTypeFactories(); genCommFactory.LoadTypeFactories();

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Config;
@@ -15,7 +16,7 @@ namespace PepperDash.Essentials.Core
public interface IDeviceFactory public interface IDeviceFactory
{ {
/// <summary> /// <summary>
/// Will be called when the plugin is loaded by Essentials. Must add any new types to the DeviceFactory using DeviceFactory.AddFactoryForType() for each new type /// Loads all the types to the DeviceFactory
/// </summary> /// </summary>
void LoadTypeFactories(); void LoadTypeFactories();
} }

View File

@@ -19,6 +19,7 @@ namespace PepperDash.Essentials.DM
/// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
/// ///
/// </summary> /// </summary>
[Description("Wrapper class for all DM-MD chassis variants from 8x8 to 128x128")]
public class DmChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingInputsOutputs, IRouting, IHasFeedback public class DmChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingInputsOutputs, IRouting, IHasFeedback
{ {
public DMChassisPropertiesConfig PropertiesConfig { get; set; } public DMChassisPropertiesConfig PropertiesConfig { get; set; }

View File

@@ -24,6 +24,8 @@ namespace PepperDash.Essentials.DM
{ {
public DmDeviceFactory() public DmDeviceFactory()
{ {
Debug.Console(1, "Essentials.DM Factory Adding Types...");
var dmChassisFactory = new DmChassisControllerFactory() as IDeviceFactory; var dmChassisFactory = new DmChassisControllerFactory() as IDeviceFactory;
dmChassisFactory.LoadTypeFactories(); dmChassisFactory.LoadTypeFactories();

View File

@@ -19,6 +19,7 @@ namespace PepperDash.Essentials.DM
/// <summary> /// <summary>
/// Represent both a transmitter and receiver pair of the HD-MD-400-C-E / HD-MD-300-C-E / HD-MD-200-C-E kits /// Represent both a transmitter and receiver pair of the HD-MD-400-C-E / HD-MD-300-C-E / HD-MD-200-C-E kits
/// </summary> /// </summary>
[Description("Wrapper class for all HD-MD variants")]
public class HdMdxxxCEController : CrestronGenericBridgeableBaseDevice, IRouting//, IComPorts public class HdMdxxxCEController : CrestronGenericBridgeableBaseDevice, IRouting//, IComPorts
{ {
/// <summary> /// <summary>

View File

@@ -17,6 +17,7 @@ using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.DM namespace PepperDash.Essentials.DM
{ {
[Description("Wrapper class for all DM-RMC variants")]
public abstract class DmRmcControllerBase : CrestronGenericBridgeableBaseDevice public abstract class DmRmcControllerBase : CrestronGenericBridgeableBaseDevice
{ {
public virtual StringFeedback VideoOutputResolutionFeedback { get; protected set; } public virtual StringFeedback VideoOutputResolutionFeedback { get; protected set; }

View File

@@ -148,6 +148,7 @@ namespace PepperDash.Essentials.DM
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
[Description("Wrapper class for all DM-TX variants")]
public abstract class DmTxControllerBase : CrestronGenericBridgeableBaseDevice public abstract class DmTxControllerBase : CrestronGenericBridgeableBaseDevice
{ {
public virtual void SetPortHdcpCapability(eHdcpCapabilityType hdcpMode, uint port) { } public virtual void SetPortHdcpCapability(eHdcpCapabilityType hdcpMode, uint port) { }