#region Copyright /* * Copyright (c) 2005,2006,2007, OpenMI Association * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the OpenMI Association nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY "OpenMI Association" ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL "OpenMI Association" BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #endregion using System; using System.Collections; using OpenMI.Standard; namespace RTCTools.OpenMI.Sdk.Backbone { /// /// The LinkableComponent provides the OpenMI interface to the wrapped engine. /// This is a trivial implementation of OpenMI.Standard.ILinkableComponent, refer there for further details. /// public abstract class LinkableComponent:MarshalByRefObject,ILinkableComponent { private ArrayList _acceptingLinks = new ArrayList(); private ArrayList _providingLinks = new ArrayList(); private ArrayList _inputExchangeItems = new ArrayList(); private ArrayList _outputExchangeItems = new ArrayList(); private Hashtable _eventTable = new Hashtable(); /// /// Called before computation /// public abstract void Prepare(); /// /// Returns computed values /// /// The timestamp/timespan for which to return values /// The linkID describing on which link values to return /// The computed values public abstract IValueSet GetValues(ITime time, string LinkID); /// /// Adds a link /// /// The link public virtual void AddLink (ILink NewLink) { if (NewLink.SourceComponent==this) { for (int iNewDO = 0; iNewDO < NewLink.DataOperationsCount; iNewDO++) { IDataOperation newDataOperation = NewLink.GetDataOperation(iNewDO); foreach (ILink link in _providingLinks) { for (int iExistingDO = 0; iExistingDO < link.DataOperationsCount; iExistingDO++) { IDataOperation existingDataOperation = link.GetDataOperation(iExistingDO); if (newDataOperation == existingDataOperation) { Event warning = new Event(EventType.Warning); warning.Description = "DataOperation " + newDataOperation.ID + " has already been used. " + "It's argument values will overrule the values set previously for this operation."; warning.Sender = this; SendEvent(warning); } } } } _providingLinks.Add(NewLink); } if (NewLink.TargetComponent==this) { _acceptingLinks.Add(NewLink); } } /// /// Removes a link /// /// The link ID public virtual void RemoveLink(string LinkID) { ILink Link = GetLink (LinkID); if (Link != null) { _acceptingLinks.Remove (Link); _providingLinks.Remove (Link); } } /// /// Returns the accepting links /// /// The accepting links public virtual ILink[] GetAcceptingLinks() { return (ILink[] ) _acceptingLinks.ToArray(typeof(ILink)); } /// /// Returns the providing links /// /// The providing links public virtual ILink[] GetProvidingLinks() { return (ILink[] ) _providingLinks.ToArray(typeof(ILink)); } /// /// Returns the number of links /// public virtual int LinkCount { get { return _acceptingLinks.Count+_providingLinks.Count; } } /// /// Gets a link /// /// The link ID /// The link public virtual ILink GetLink(string LinkID) { for (int i = 0; i < _acceptingLinks.Count; i++) { if (((ILink)_acceptingLinks[i]).ID.Equals(LinkID)) { return (ILink) _acceptingLinks[i]; } } for (int i = 0; i < _providingLinks.Count; i++) { if (((ILink)_providingLinks[i]).ID.Equals(LinkID)) { return (ILink) _providingLinks[i]; } } return null; } /// /// Subscribes to an event /// /// The listener /// The event type public virtual void Subscribe(IListener Listener, EventType EventType) { if (!_eventTable.ContainsKey(EventType)) { _eventTable[EventType] = new ArrayList(); } ((ArrayList)_eventTable[EventType]).Add(Listener); } /// /// Unsubscribes to an event /// /// The listener /// The event type public virtual void UnSubscribe(IListener Listener, EventType EventType) { if (_eventTable.ContainsKey(EventType)) { ArrayList list = (ArrayList) _eventTable[EventType]; if (list.Contains(Listener)) list.Remove(Listener); } } /// /// Sends an event /// /// The event public virtual void SendEvent(IEvent theEvent) { EventType EventType = theEvent.Type; if (_eventTable.ContainsKey(EventType)) { ArrayList list = (ArrayList) _eventTable[EventType]; foreach (IListener listener in list) { listener.OnEvent(theEvent); } } } /// /// Returns a published event type /// /// The event index /// The published event public abstract EventType GetPublishedEventType(int providedEventTypeIndex); /// /// Returns the number of published events /// /// The number of published events public abstract int GetPublishedEventTypeCount(); /// /// Check if the current instance equals another instance of this class. /// ///The instance to compare the current instance with. ///true if the instances are the same instance or have the same content. public override bool Equals(Object source) { if (source is LinkableComponent) { LinkableComponent component = (LinkableComponent) source; return (NullEquals(ComponentID, component.ComponentID) && NullEquals(ModelID, component.ModelID)); } return base.Equals (source); } private static bool NullEquals (object obj1, object obj2) { if ((obj1 != null) && (obj2 != null)) { return obj1.Equals (obj2); } else { return (obj1 == obj2); } } /// /// Dispose function /// public virtual void Dispose() { } /// /// Returns an input exchange item /// /// The input exchange item index /// The input exchange item public virtual IInputExchangeItem GetInputExchangeItem(int inputExchangeItemIndex) { return (IInputExchangeItem) _inputExchangeItems[inputExchangeItemIndex]; } /// /// Returns the component description /// public abstract string ComponentDescription {get;} /// /// Returns if the component is valid (contains valid data) /// /// True if the component is valid public abstract string Validate(); /// /// Returns the number of input exchange items /// public virtual int InputExchangeItemCount { get { return _inputExchangeItems.Count; } } /// /// Returns the time horizon, which is the simulation start and stop /// time for this component /// public abstract ITimeSpan TimeHorizon {get;} /// /// Returns the earliest time for which input is needed /// public abstract ITimeStamp EarliestInputTime {get;} /// /// Returns the component ID /// public abstract string ComponentID {get;} /// /// Returns an output exchange item /// /// The output exchange item index /// The output exchange item public virtual IOutputExchangeItem GetOutputExchangeItem(int outputExchangeItemIndex) { return (IOutputExchangeItem) _outputExchangeItems[outputExchangeItemIndex]; } /// /// Adds an input exchange item /// /// The input exchange item public virtual void AddInputExchangeItem(IInputExchangeItem exchangeItem) { _inputExchangeItems.Add(exchangeItem); } /// /// Adds an output exchange item /// /// The output exchange item public virtual void AddOutputExchangeItem(IOutputExchangeItem exchangeItem) { _outputExchangeItems.Add(exchangeItem); } /// /// Initializes the component with the given arguments /// /// The arguments public abstract void Initialize(IArgument[] properties); /// /// The model description /// public abstract string ModelDescription {get;} /// /// The model ID /// public abstract string ModelID {get;} /// /// The number of output exchange items /// public virtual int OutputExchangeItemCount { get {return _outputExchangeItems.Count;} } /// /// Finish clears up allocated memory and closes files /// After this method is called no other methods should /// be called on the LinkableComponent /// public abstract void Finish(); /// /// Returns a string describing this linkable component /// /// The description public override string ToString() { return ComponentID + " - " + ModelID; } /// /// Returns true if the linkable component has listeners /// /// True is linkable component has listeners public virtual bool HasListeners() { foreach (EventType eventType in _eventTable.Keys) { ArrayList list = (ArrayList) _eventTable[eventType]; if (list.Count>0) return true; } return false; } /// /// Get Hash Code. /// ///Hash Code for the current instance public override int GetHashCode() { return _acceptingLinks.GetHashCode() + _eventTable.GetHashCode() + _inputExchangeItems.GetHashCode()+ _outputExchangeItems.GetHashCode() + _providingLinks.GetHashCode(); } } }