#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();
}
}
}