You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 7 Next »

Problem

  • Converting IValueSet results to enumerations

Proposal

Additions to Standard
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);
    }
Optional change to Standard
    class ILinkableComponent
    {
        ......
        object GetValues(ITime time, string linkID);
        ......
    }

Example

Enumeration
    enum ReedGrowth { High = 0, Medium, Low, }
Example of it working
        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;
            }
        }
Wrapped LinkableComponent to allow Adaption
    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;
    }

Quantity for Reed Growth Enumeration
    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
    }
Adapter to make Reed Growth an enum
    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
    }
Original LinkableComponent with Reed Growth as a double
    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();
     }
Reed growth as double Output Exchange Item
    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();
    }
Reed Growth as double Quantity
    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
    }
Util to give me a IScalerSet from a double
    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
    }

  • No labels