/**
 * @file RtecEventComm.idl
 *
 * @brief Define the RtecEventComm module
 *
 * TAO's Real-time Event Service is described in:
 *
 * http://doc.ece.uci.edu/~coryan/EC/
 *
 * @author Carlos O'Ryan <coryan@uci.edu>
 * @author Tim Harrison <harrison@cs.wustl.edu>
 */
#ifndef TAO_RTEC_EVENTCOMM_IDL
#define TAO_RTEC_EVENTCOMM_IDL

#include "TimeBase.idl"

// Remove the prefix definition...
// @@ TODO Is this the "Right Thing"? AFAIK the spec does not mention
// if pragmas should survive the file scope...
#pragma prefix ""

#include "RtecDefaultEventData.idl"

/**
 * @namespace RtecEventComm
 *
 * @brief Interfaces and data structures used by the event service
 *   clients
 */
module RtecEventComm
{
  /// The event data
  typedef RtecEventData EventData;

  /// Shortcut for the time structures.
  typedef TimeBase::TimeT Time;

  typedef long EventSourceID;
  typedef long _EventType;

  /**
   * @struct EventHeader
   *
   * @brief Define the structure of an event header
   *
   * The event header is the portion of the event examined by the
   * event service for filtering purposes.
   *
   * Events can be filtered based on their type and SourceID, though
   * the latest is a misnomer, over time it has evolved into a 'source
   * class' or 'event domain' field, i.e. multiple sources can have
   * the same 'ID' and the same source can generate events with
   * different IDs.
   */
  struct EventHeader
  {
    /// The event type.
    /**
     * Notice that the 'type' of the event may or may not be related
     * to the data type in its contents.  I.e. it is perfectly
     * possible to send the same payload with different values in this
     * field.  In other words, this is just a filterable value, and
     * it is up to the application to define (or not) its relation to
     * the contents of the event.
     */
    _EventType type;

    /// Some way to identify the supplier.
    EventSourceID source;

    /// The "Time To Live" counter.
    /**
     * Each time an EC process the event it decreases the TTL field,
     * when it gets to zero the message is no longer forwarded.
     */
    long ttl;

    /// Applications can use this field to time-stamp the event at the
    /// source.
    /**
     * @todo Because the filtering language uses EventHeaders as
     * filtering expressions (yeah, it sucks) we also use this field
     * to pass timeout values into the EC filter.
     */
    Time creation_time;

#ifndef TAO_LACKS_EVENT_CHANNEL_TIMESTAMPS
    //@{
    /** @name Benchmarking timestamps
     *
     * The following timestamps are used to benchmark the Event
     * Channel, they should not be used by the application and may be
     * removed without notice.
     */
    Time ec_recv_time;
    Time ec_send_time;
    //@}
#endif /* TAO_LACKS_EVENT_CHANNEL_TIMESTAMPS */
  };

  /**
   * @struct Event
   *
   * @brief The basic events delivered by the Event Service.
   *
   * The event service uses this structure to pass events around.
   */
  struct Event
  {
    /// The header, used for filtering
    EventHeader header;

    /// The payload, the event service treats this as an opaque data
    /// field.
    EventData data;
  };
  /// The real argument to the push() operations.
  /**
   * For performance reasons TAO's Real-time Event Service uses
   * sequences of events
   */
  typedef sequence<Event> EventSet;

  /**
   * @interface PushConsumer
   *
   * @brief Define the interface used by consumers to receive events.
   *
   * Applications usually implement this interface to subscribe for
   * events.
   */
  interface PushConsumer
  {
    /// Main event delivery callback
    oneway void push (in EventSet data);

    /// Callback method to indicate a disconnection.
    /**
     * If the event service is destroyed while a consumer is still
     * connected then the following callback operation is invoked on
     * the consumer.
     *
     * The same operation is used by suppliers to disconnect from the
     * Event Channel, but it is invoked via their
     * RtecEventChannelAdmin::ProxyPushConsumer peer.
     */
    void disconnect_push_consumer ();
  };

  /**
   * @interface PushSupplier
   *
   * @brief Defines the interface used by suppliers to receive
   *        callbacks from the Event Channel.
   */
  interface PushSupplier
  {
    /// Callback method to indicate a disconnection.
    /**
     * If the event service is destroyed while a supplier is still
     * connected then the following callback operation is invoked on
     * the supplier.
     *
     * The same operation is used by consumers to disconnect from the
     * Event Channel, but it is invoked via their
     * RtecEventChannelAdmin::ProxyPushSupplier peer.
     */
    void disconnect_push_supplier ();
  };
};

#endif /* TAO_RTEC_EVENTCOMM_IDL */
