You are viewing an old version of this page. View the current version.
Compare with Current
View Page History
« Previous
Version 3
Next »
Problem
- Converting IValueSet results to enumerations
Proposal
public interface IExchangeAdaptor
{
IExchangeItem ExchangeItemOriginal { set; get; }
IExchangeItem ExchangeItemNew { get; }
object Adapt(IValueSet value);
}
// Optional Extension for ILinkableComponent
interface IExchangeAdaptable
{
int SuggestedAdaptorsCount { get; }
IExchangeAdaptor AdaptorSugestion(int index);
}
Example
enum ReedGrowth { High = 0, Medium, Low, }
static void Adaptors()
{
ITime time = new TimeStamp(10.0);
string linkid = "wibble";
// has an output exchange item which returns Reed Growth as a height (IScalar/double)
ILinkableComponent iLC = new LinkableComponentReedGrowth();
IValueSet vs = iLC.GetValues(time, linkid);
double d = ((IScalarSet)vs).GetScalar(0);
string id = iLC.GetOutputExchangeItem(0).Quantity.ID;
string idd = iLC.GetOutputExchangeItem(0).Quantity.Description;
// make 3rd party Linkable component adaptable
LinkableComponentAdaptable iLCA = new LinkableComponentAdaptable(iLC);
// change Reed Growth to an enum ReedGrowth { High = 0, Medium, Low, }
int index = iLCA.MakeAdaption("ReedGrowthHeight", new ReedGrowthEnum());
ReedGrowth growth = (ReedGrowth)iLCA.GetValuesAdapted(time, linkid);
string ida = iLCA.GetOutputExchangeItem(index).Quantity.ID;
string idda = iLCA.GetOutputExchangeItem(index).Quantity.Description;
// Another proposed change:
// object GetValues(time, linkid, out bool adapted);
// if adapted false then IValueSet returned, else user needs to test against 'as' ie ...
object o = iLCA.GetValuesAdapted(time, linkid);
if (o is ReedGrowth)
{
ReedGrowth gr = (ReedGrowth)o;
bool badGrowth = gr == ReedGrowth.High;
}
}
class LinkableComponentAdaptable : ILinkableComponent
{
// Redirect to aggregated linkiable component all members ....
#region ILinkableComponent Members
#region IPublisher Members
// ... except ....
public LinkableComponentAdaptable(ILinkableComponent iLC)
{
_iLC = iLC;
}
public int OutputExchangeItemCount
{
get { return _iLC.OutputExchangeItemCount; }
}
public IOutputExchangeItem GetOutputExchangeItem(int index)
{
IOutputExchangeItem item = _iLC.GetOutputExchangeItem(index);
if (_adaptedExchangeItems.ContainsKey(item))
return (IOutputExchangeItem)_adaptedExchangeItems[item].ExchangeItemNew;
return item;
}
public IValueSet GetValues(ITime time, string linkID)
{
return _iLC.GetValues(time, linkID);
}
public object GetValuesAdapted(ITime time, string linkID)
{
IValueSet vs = _iLC.GetValues(time, linkID);
/*
* from linkid get iLink
* from iLink get sourceComponent
* from iLink get sourceQuantity.ID
* fudged below ....
*/
ILinkableComponent iSource = this; // fudge
string sourceQID = "ReedGrowthHeightEnum"; // fudge
int index = -1;
for (int n = 0; n < iSource.OutputExchangeItemCount; ++n)
{
if (iSource.GetOutputExchangeItem(n).Quantity.ID == sourceQID)
index = n;
}
if (index > -1)
{
IOutputExchangeItem item = _iLC.GetOutputExchangeItem(index);
if (_adaptedExchangeItems.ContainsKey(item))
return _adaptedExchangeItems[item].Adapt(vs);
}
return vs;
}
// New Members
public int MakeAdaption(string quantityId, IExchangeAdaptor adaptor)
{
for (int n = 0; n < OutputExchangeItemCount; ++n)
{
if (GetOutputExchangeItem(n).Quantity.ID == quantityId)
{
adaptor.ExchangeItemOriginal = GetOutputExchangeItem(n);
_adaptedExchangeItems.Add(GetOutputExchangeItem(n), adaptor);
return n;
}
}
return -1;
}
Dictionary<IOutputExchangeItem, IExchangeAdaptor> _adaptedExchangeItems = new Dictionary<IOutputExchangeItem, IExchangeAdaptor>();
ILinkableComponent _iLC;
}
class QuantityAsEnum : IQuantity
{
IQuantity _quantity;
public QuantityAsEnum(IQuantity q)
{
_quantity = q;
}
#region IQuantity Members
public string ID
{
get { return _quantity.ID + "Enum"; }
}
public string Description
{
get { return _quantity.Description + " Adapted to enumeration return value"; }
}
public org.OpenMI.Standard.ValueType ValueType
{
get { return _quantity.ValueType; }
}
public IDimension Dimension
{
get { return _quantity.Dimension; }
}
public IUnit Unit
{
get { return _quantity.Unit; }
}
#endregion
}
class ReedGrowthEnum : IExchangeAdaptor
{
double _high = 15;
double _low = 5;
IExchangeItem _original;
IExchangeItem _new;
#region IAdaptor Members
public object Adapt(IValueSet value)
{
ReedGrowth rg = ReedGrowth.Medium;
double d = ((IScalarSet)value).GetScalar(0);
if (d > _high)
rg = ReedGrowth.High;
if (d < _low)
rg = ReedGrowth.Low;
return rg;
}
public IExchangeItem ExchangeItemOriginal
{
set
{
_original = value;
if (value is IInputExchangeItem)
_new = new InputExchangeItem(new QuantityAsEnum(_original.Quantity), _original.ElementSet);
else if (value is IOutputExchangeItem)
_new = new OutputExchangeItem(new QuantityAsEnum(_original.Quantity), _original.ElementSet);
else
{
Debug.Assert(false);
}
}
get { return _original; }
}
public IExchangeItem ExchangeItemNew
{
get { return _new; }
}
#endregion
}
class LinkableComponentReedGrowth : ILinkableComponent
{
#region ILinkableComponent Members
#region IPublisher Members
public int OutputExchangeItemCount
{
get { return 1; }
}
public IOutputExchangeItem GetOutputExchangeItem(int index)
{
return index == 0 ? _reeds : null;
}
public IValueSet GetValues(ITime time, string linkID)
{
return new Double(12);
}
ReedGrowthHeight _reeds = new ReedGrowthHeight();
}
class ReedGrowthHeight : IOutputExchangeItem
{
#region IOutputExchangeItem Members
#region IExchangeItem Members
public IQuantity Quantity
{
get { return _quantity; }
}
public IElementSet ElementSet
{
get { return null; }
}
#endregion
ReedGrowthQuantity _quantity = new ReedGrowthQuantity();
}
class ReedGrowthQuantity : IQuantity
{
#region IQuantity Members
public string ID
{
get { return "ReedGrowthHeight"; }
}
public string Description
{
get { return "ReedGrowthHeight as a scalor"; }
}
public org.OpenMI.Standard.ValueType ValueType
{
get { return org.OpenMI.Standard.ValueType.Scalar; }
}
public IDimension Dimension
{
get { return null; }
}
public IUnit Unit
{
get { return null; }
}
#endregion
}
class Double : IScalarSet
{
double _double;
public Double(double d)
{
_double = d;
}
#region IScalarSet Members
public double GetScalar(int index)
{
return IsValid(index) ? _double : -999.999;
}
#endregion
#region IValueSet Members
public int Count
{
get { return 1; }
}
public bool IsValid(int index)
{
return index == 0;
}
#endregion
}