using System; using System.Collections.Generic; using log4net; using NUnit.Framework; using Oatc.OpenMI.Sdk.Backbone.IntegrationTests.Components; using OpenMI.Standard; namespace Oatc.OpenMI.Sdk.Backbone.IntegrationTests { [TestFixture] public class OutputDecoratorTest { private ILinkableComponent sourceComponent; private ILinkableComponent targetComponent1; private ILinkableComponent targetComponent2; [SetUp] public void SetUp() { sourceComponent = new AnalyticalFunctionComponent(); targetComponent1 = new AnalyticalFunctionComponent(); // connect items using decorator IOutputItemDecorator unitConverter = new UnitConverter(); unitConverter.DecoratedOutputItem = sourceComponent.OutputItems[0]; unitConverter.AddConsumer(targetComponent1.InputItems[0]); targetComponent2 = new AnalyticalFunctionComponent(); } // Example1: re-use existing unit converter in 2 different input exchange items [Test] [Ignore("Test is unfinished, added for OATC discusssion")] public void ReuseUnitConverterInTwoComponents() { ConnectExchangeItemsUsingExistingUnitConverter(sourceComponent, sourceComponent.OutputItems[0], targetComponent2.InputItems[0]); } public void ConnectExchangeItemsUsingExistingUnitConverter(ILinkableComponent sourceComponent, IOutputItem sourceItem, IInputItem targetItem) { foreach (var outputItem in sourceComponent.OutputItems) { if (!(outputItem is IOutputItemDecorator)) { continue; } var decorator = (IOutputItemDecorator)outputItem; if (decorator.DecoratedOutputItem != sourceItem) // TODO: add more check if needed { continue; } decorator.AddConsumer(targetItem); return; } } // Example2: render linkable component including it's decorators [Test] [Ignore("Test is unfinished, added for OATC discusssion")] public void RenderComponent() { RenderComponent(sourceComponent); } public void RenderComponent(ILinkableComponent component) { foreach (var outputItem in sourceComponent.OutputItems) { if (outputItem is IOutputItemDecorator) { DrawOtputItemDecorator((IOutputItemDecorator)outputItem); } else { DrawOutputExchangeItem(outputItem); } } } private void DrawOutputExchangeItem(IOutputItem item) { throw new NotImplementedException(); } private void DrawOtputItemDecorator(IOutputItemDecorator decorator) { throw new NotImplementedException(); } } }
Possible implementation of the decorator:
public class UnitConverter : OutputItem, IOutputItemDecorator { private new static readonly ILog log = LogManager.GetLogger(typeof (UnitConverter)); private IOutputItem decoratedOutputItem; private readonly IList<IArgument> arguments; public UnitConverter() { arguments = new List<IArgument>(); arguments.Add(new Argument("SourceUnit", new Unit("m").ToString(), true, "Source unit for conversion (set automatically when DecoratedOutputItem is set")); arguments.Add(new Argument("TargetUnit", new Unit("ft").ToString(), true, "Target unit for conversion")); } public IList<IArgument> Arguments { get { return arguments; } } public IOutputItem DecoratedOutputItem { get { return decoratedOutputItem; } set { decoratedOutputItem = value; } } public void Update() { log.InfoFormat("Converting units ..."); foreach (IInputItem targetItem in Consumers) { targetItem.Values = decoratedOutputItem.Values; // TODO: add conversion here } } }