//=========================================================================
// Summary  : */
// Filename : EventService.h
// Author   : */
// Project  : */
// Revision : 1
// Created  : 2000/08/19
// Modified : 2000/08/19
//=========================================================================
// Description :
//=========================================================================
#ifndef _EVENTSERVICE_H
#define _EVENTSERVICE_H

#include <sys/types.h>
#include "DynamicArray.h"
#include "Task.h"
#include "TaskInterface.h"


/*
CLASS
EventService

DESCRIPTION
Allows application to subscribe to one or more events from one or
more TaskInterface objects. For each subscribed event, the application
specifies a callback method to be invoked.

The specified callback method must have the following signature:

  void Task::callback(TaskInterface *client, EventCode eventCode);

The first argument is a pointer to the TaskInterface object that
published the event. The second argument is the EventCode of the
event.


AUTHOR
Tom O'Reilly
*/
class EventService {
public:

  EventService(const char *name, Task *task);

  ~EventService();

  const char *name() {
    return _name;
  }

  ///////////////////////////////////////////////////////////////////
  // Prototype for event callback methods
  typedef void (Task::*Callback)(TaskInterface *client,
				 EventCode eventCode);

  ///////////////////////////////////////////////////////////////////
  // Subscribe to specified event on specified TaskInterface, and
  // "register" callback to be invoked when event occurs.
  void subscribe(TaskInterface *taskInterface,
		 EventCode eventCode,
		 Callback callback);


  ///////////////////////////////////////////////////////////////////
  // Wait for event from subscribed TaskInterfaces, and invoke
  // appropriate calback
  void processEvent();

private:

  const char *_name;

  struct EventTableEntry {

    EventTableEntry(TaskInterface *client,
		    EventCode eventCode,
		    Callback callback) {
      _client = client;
      _eventCode = eventCode;
      _callback = callback;
      _localProxyPid = -1;
      _remoteProxyPid = -1;
    }

    EventTableEntry(TaskInterface *client,
		    EventCode eventCode,
		    Callback callback,
		    pid_t localProxyPid,
		    pid_t remoteProxyPid) {
      _client = client;
      _eventCode = eventCode;
      _callback = callback;
      _localProxyPid = localProxyPid;
      _remoteProxyPid = remoteProxyPid;
    }


    TaskInterface *_client;
    EventCode _eventCode;
    Callback _callback;
    pid_t _localProxyPid, _remoteProxyPid;
  };

  Task *_task;

  DynamicArray<EventTableEntry *> _eventTable;
};

#endif

