// $Header: /cvs/gled-1.2/GledCore/Glasses/Eventor.cxx,v 1.9 2005/03/11 17:50:15 matevz Exp $

// Copyright (C) 1999-2005, Matevz Tadel. All rights reserved.
// This file is part of GLED, released under GNU General Public License version 2.
// For the licensing terms see $GLEDSYS/LICENSE or http://www.gnu.org/.

//________________________________________________________________________
// Eventor
//
// Base-class for glasses that wish to acquire their own threads.
//
//________________________________________________________________________

#include "Eventor.h"
#include <Ephra/Mountain.h>
#include <Glasses/ZKing.h>
#include <Glasses/ZQueen.h>
#include <Gled/GThread.h>
#include <Gled/GledMirDefs.h>


#include <signal.h>
#include <errno.h>

ClassImp(Eventor)

/**************************************************************************/

 void Eventor::_init()
{
  mTotalTime = mRunTime = 0;
  mBeatsToDo = -1; mBeatsDone = 0;
  mStampInterval = 100; mInterBeatMS = 0;

  mHost = 0;

  bUseDynCast = true; bSignalSafe = false;
  bContinuous = true; bMultix = false;
  bRunning = bSuspended = bPerforming = bXMultix = false;
}

/**************************************************************************/

 Mountain* Eventor::GetChaItOss()
{
  return mSaturn->GetChaItOss();
}

/**************************************************************************/

 void Eventor::AdEndarkenment()
{
  // !!!! if thread running clomp it
}

 void Eventor::AdUnfoldment()
{
  Operator::AdUnfoldment();
  mLocBeatsDone = mBeatsDone;

  // !!!! multix can change ... would better lock that!!!
  // anyway dislike the duplication in op_arg.
  // Too lazy to write the manual Set Methods?

  if(bXMultix && bRunning) {
    if(mHost == 0) {
      mHost = GetQueen()->GetKing()->GetSaturnInfo();
    }
    if(!bSuspended) {
      mSaturn->GetChaItOss()->Start(this);
    } else {
      mSaturn->GetChaItOss()->Start(this, true);
    }
  }
}

/**************************************************************************/
// Dance & Beat methods
/**************************************************************************/

 Operator::Arg* Eventor::PreDance(Operator::Arg* op_arg)
{
  // Eventor::PreDance() is called as the first thing from Mountain::OperatorBeat().
  // It is supposed to instantiate and set Operator::Arg* op_arg to meaningfull
  // values and return it.
  // If you sub-class the Operator::Arg, make sure to also perform the
  // house-keeping tasks performed here or call this method with non-zero
  // op_arg.
  // Return value of 0 signifies error and results in immediate termination
  // of the thread. No other methods are called.

  if(op_arg == 0) op_arg = new Operator::Arg;

  op_arg->fMultix	= bMultix;
  op_arg->fSignalSafe	= bSignalSafe;
  op_arg->fContinuous	= bContinuous;
  op_arg->fUseDynCast	= bUseDynCast;

  op_arg->fEventID = 0;

  return op_arg;
}

 void Eventor::PostDance(Operator::Arg* op_arg)
{
  // Eventor::PostDance() is called from Mountain::OperatorBeat() when Eventor
  // throws Operator::OE_Done to request termination of the thread.
  // If Operator::OE_Stop or Operator::OE_Break is thrown, this method
  // is *not* called, but either OnStop() or OnBreak().
}

/**************************************************************************/

 void Eventor::PreBeat(Operator::Arg* op_arg) throw(Operator::Exception)
{
  // Eventor::PreBeat() is called from Mountain::OperatorBeat() prior to
  // calling Operate.

  op_arg->fEventID = mLocBeatsDone + 1;
}

 void Eventor::PostBeat(Operator::Arg* op_arg) throw(Operator::Exception)
{
  // Eventor::PostBeat() is called from Mountain::OperatorBeat()
  // after Operate (unless an exception was thrown from Operate's traversal).

  ++mLocBeatsDone;
  bool done = (mBeatsToDo != -1 && mLocBeatsDone >= mBeatsToDo);
  if(mStampInterval == 0 || mLocBeatsDone % mStampInterval == 0 || done) {
    OP_EXE_OR_SP_MIR(this, SetBeatsDone, mLocBeatsDone);
  }
  if(done) {
    throw( Operator::Exception(this, Operator::OE_Done, "reached required beat count") );
  }
}

/**************************************************************************/
// Handlers for Start/Suspend/Exit
/**************************************************************************/

 void Eventor::OnStart(Operator::Arg* op_arg)
{
  OP_EXE_OR_SP_MIR(this, SetRunning, true);
  OP_EXE_OR_SP_MIR(this, SetXMultix, op_arg->fMultix);
  SetPerforming(true);
}

 void Eventor::OnSuspend(Operator::Arg* op_arg)
{
  OP_EXE_OR_SP_MIR(this, SetSuspended, true);
}

 void Eventor::OnResume(Operator::Arg* op_arg)
{
  OP_EXE_OR_SP_MIR(this, SetSuspended, false);
}

 void Eventor::OnExit(Operator::Arg* op_arg)
{
  if(bSuspended) {
    OP_EXE_OR_SP_MIR(this, SetSuspended, false);
  }
  OP_EXE_OR_SP_MIR(this, SetRunning, false);
  OP_EXE_OR_SP_MIR(this, SetTotalTime, (op_arg->fStop - op_arg->fStart).ToDouble());
  OP_EXE_OR_SP_MIR(this, SetRunTime, op_arg->fBeatSum.ToDouble());
  SetPerforming(false);
}

/**************************************************************************/
// Handlers for different exceptions
/**************************************************************************/

 void Eventor::OnContinue(Operator::Arg* op_arg, Operator::Exception& op_exc)
{
  // Called from Mountain::DancerBeat() upon catching "continue" exception.
}

 void Eventor::OnWait(Operator::Arg* op_arg, Operator::Exception& op_exc)
{
  // Called from Mountain::DancerBeat() upon catching "wait" exception.
}

 void Eventor::OnStop(Operator::Arg* op_arg, Operator::Exception& op_exc)
{
  // Called from Mountain::DancerBeat() upon catching "stop" exception.
}

 void Eventor::OnBreak(Operator::Arg* op_arg, Operator::Exception& op_exc)
{
  // Called from Mountain::DancerBeat() upon catching "break" exception.
}

/**************************************************************************/
// User interface for thread control
/**************************************************************************/

 void Eventor::Start()
{
  if(mHost == 0) {
    SetHost(GetQueen()->GetKing()->GetSaturnInfo());
  }

  if(!bMultix && mHost != mSaturn->GetSaturnInfo()) return;

  if(bRunning) {
    ISwarn("Eventor::Start already running");
    //return;
  }
  if(bSuspended) {
    ISwarn("Eventor::Start paused ... use Resume to continue");
    //return;
  }
  mSaturn->GetChaItOss()->Start(this);
}

 void Eventor::Stop()
{
  if(!bXMultix && mHost != mSaturn->GetSaturnInfo()) return;

  if(!bRunning) {
    ISwarn("Eventor::Stop not running");
    //return;
  }

  mSaturn->GetChaItOss()->Stop(this);
}

 void Eventor::Suspend()
{
  if(!bXMultix && mHost != mSaturn->GetSaturnInfo()) return;

  if(!bRunning) {
    ISwarn("Eventor::Suspend not running");
    //return;
  }

  if(bSuspended) {
    ISwarn("Eventor::Suspend already suspended");
    //return;
  }

  mSaturn->GetChaItOss()->Suspend(this);
}

 void Eventor::Resume()
{
  if(!bXMultix && mHost != mSaturn->GetSaturnInfo()) return;

  if(!bRunning) {
    ISwarn("Eventor::Resume not running");
    //return;
  }

  if(!bSuspended) {
    ISwarn("Eventor::Resume not paused");
    //return;
  }

  mSaturn->GetChaItOss()->Resume(this);
}

 void Eventor::Reset()
{
  mTotalTime = mRunTime = 0;
  mBeatsDone = mLocBeatsDone = 0; Stamp(FID());
}

 void Eventor::Cancel()
{
  if(!bXMultix && mHost != mSaturn->GetSaturnInfo()) return;

  if(!bRunning) {
    ISwarn("Eventor::Cancel not running");
    //return;
  }

  mSaturn->GetChaItOss()->Cancel(this);
}

/**************************************************************************/

 void Eventor::SetHost(SaturnInfo* host)
{
  WriteLock();
  try {
    if(bRunning)
      throw(string("Eventor::SetHost cannot change host while thread is running."));
    set_link_or_die((ZGlass*&)mHost, host, FID());
  }
  catch(...) {
    WriteUnlock();
    throw;
  }
  WriteUnlock();
}

/**************************************************************************/

#include "Eventor.c7"


ROOT page - Home page - Class index - Class Hierarchy - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.