//-----------------------------------------------------------------------------
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
//                         Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//
//-----------------------------------------------------------------------------
//
// Description:
//      cdev Transaction Object class (for service developer only)
//
// Author:  Jie Chen
//
// Revision History:
//   cdevExecObj.cc,v
// Revision 1.2  1997/03/03  17:36:02  chen
// add buffering to channel access connection
//
// Revision 1.1  1995/12/08  15:34:37  chen
// execution object
//
//
#include <cdevRequestObject.h>
#include "cdevExecObj.h"

// Note: How to determine to buffer an exeution object?
//       If an execution object belongs to a group with 
//       an immediate execution mode, this object will not be
//       buffered. If an execution object belongs to a group
//       with a deferred execution mode, this execution object
//       will be buffered


cdevExecObj::cdevExecObj (void)
:system_ (0), reqObj_ (0), outData_ (0), resultData_ (0),
 userCallback_ (0), status_ (-1)
{
#ifdef _TRACE_OBJECTS
  printf ("Create cdevExecObj Class Object\n");
#endif
  deferredGroup_ = 0;
  entryPtr_ = 0;
}

cdevExecObj::cdevExecObj (cdevSystem*        system,
			  cdevRequestObject* obj,
			  cdevData*          out,
			  cdevData*          result,
			  cdevCallback*      callback,
			  cdevGroup*         execg,
			  void*              arg)
:system_ (system), reqObj_ (obj), outData_ (out),
 resultData_ (result), userCallback_ (callback), status_ (1), arg_ (arg)
{
#ifdef _TRACE_OBJECTS
  printf ("Create cdevExecObj Class Object\n");
#endif
  if (execg == 0) {
    int i = 0;
    cdevGroup*  activeGroups [MAX_NUM_GROUPS];
    int         numActiveGrps = 0;
    for (i = 0; i < MAX_NUM_GROUPS; i++) {
      activeGroups [i] = 0;
    }
    // system could return empty groups
    system_->activeGroups (activeGroups, numActiveGrps);
    // only store execution object in the inner most group
    // Whether to buffer this execution object has been determined
    // by request object
    if (numActiveGrps != 0) {
      entryPtr_ = (activeGroups[0])->addExecObj (this);
      deferredGroup_ = activeGroups[0];
    }
  }
  else {
    deferredGroup_ = execg;
    entryPtr_ = execg->addExecObj (this);
  }
  
}

cdevExecObj::~cdevExecObj (void)
{
#ifdef _TRACE_OBJECTS
  printf ("Delete cdevExecObj class object\n");
#endif
  // remove this execution object from the deferred group
  if (deferredGroup_) {
    if (deferredGroup_->remEobj_) 
      *entryPtr_ = 0;
  }
  status_ = -1;
  deferredGroup_ = 0;
  if (outData_) delete outData_;
  // don't worry about callback which cannot be detructed by any means since
  // everything is inside a group
}

int
cdevExecObj::status (void) const
{
  return status_;
}
