#include "Eventor.h"
#include "Eventor.c7"
#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; mLocBeatsDone = 0;
mStampInterval = 100; mInterBeatMS = 0;
mHost = 0;
bMultix = false; bSignalSafe = false;
bContinuous = true; bUseDynCast = true;
bTrapILL = bTrapBUS = bTrapFPE = bTrapSEGV = false;
bRunning = bSuspended = bPerforming = bXMultix = false;
mEventID = 0;
mInternalTime = 0;
mEpochType = ET_DanceStart;
mTimeSource = TS_System;
mTimeStep = 1;
mTimeEpoch = 0;
}
Mountain* Eventor::GetChaItOss()
{
return mSaturn->GetChaItOss();
}
void Eventor::AdEndarkenment()
{
}
void Eventor::AdUnfoldment()
{
Operator::AdUnfoldment();
mLocBeatsDone = mBeatsDone;
if(bXMultix && bRunning) {
if(mHost == 0) {
mHost = GetQueen()->GetKing()->GetSaturnInfo();
}
if(!bSuspended) {
mSaturn->GetChaItOss()->Start(this);
} else {
mSaturn->GetChaItOss()->Start(this, true);
}
}
}
Operator::Arg* Eventor::PreDance(Operator::Arg* op_arg)
{
if(op_arg == 0) op_arg = new Operator::Arg;
op_arg->fEventor = this;
op_arg->fMultix = bMultix;
op_arg->fSignalSafe = bSignalSafe;
op_arg->fContinuous = bContinuous;
op_arg->fUseDynCast = bUseDynCast;
return op_arg;
}
void Eventor::PostDance(Operator::Arg* op_arg)
{
}
void Eventor::PreBeat(Operator::Arg* op_arg) throw(Operator::Exception)
{
switch(mTimeSource)
{
case TS_System:
mInternalTime = op_arg->fBeatStart.ToDouble() - mTimeEpoch;
break;
case TS_IntStep:
mInternalTime += mTimeStep;
break;
}
mTimeStack.clear();
mTimeStack.push_back(mInternalTime);
}
void Eventor::PostBeat(Operator::Arg* op_arg) throw(Operator::Exception)
{
++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") );
}
}
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);
if ((op_arg->fMultix && IsSunOrFireSpace()) || !op_arg->fMultix)
{
switch(mEpochType)
{
case ET_Manual:
mInternalTime = mTimeEpoch;
break;
case ET_DanceStart:
mTimeEpoch = op_arg->fStart.ToDouble();
if (!op_arg->fMultix)
OP_EXE_OR_SP_MIR(this, SetTimeEpoch, mTimeEpoch);
break;
}
}
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);
}
void Eventor::OnContinue(Operator::Arg* op_arg, Operator::Exception& op_exc)
{
}
void Eventor::OnWait(Operator::Arg* op_arg, Operator::Exception& op_exc)
{
}
void Eventor::OnStop(Operator::Arg* op_arg, Operator::Exception& op_exc)
{
}
void Eventor::OnBreak(Operator::Arg* op_arg, Operator::Exception& op_exc)
{
}
void Eventor::OnBreak(Operator::Arg* op_arg, const TString& msg)
{
}
void Eventor::OnTerminalSignal(Operator::Arg* op_arg, Int_t sid)
{
}
void Eventor::Start()
{
static const Exc_t _eh("Eventor::Start ");
if(mHost == 0) {
SetHost(GetQueen()->GetKing()->GetSaturnInfo());
}
if(!bMultix && mHost != mSaturn->GetSaturnInfo()) return;
if(bRunning) {
ISwarn(_eh + "already running.");
}
if(bSuspended) {
ISwarn(_eh + "paused; use Resume to continue.");
}
mSaturn->GetChaItOss()->Start(this);
}
void Eventor::Stop()
{
static const Exc_t _eh("Eventor::Stop ");
if(!bXMultix && mHost != mSaturn->GetSaturnInfo()) return;
if(!bRunning) {
ISwarn(_eh + "not running.");
}
mSaturn->GetChaItOss()->Stop(this);
}
void Eventor::Suspend()
{
static const Exc_t _eh("Eventor::Suspend ");
if(!bXMultix && mHost != mSaturn->GetSaturnInfo()) return;
if(!bRunning) {
ISwarn(_eh + "not running.");
}
if(bSuspended) {
ISwarn(_eh + "already suspended.");
}
mSaturn->GetChaItOss()->Suspend(this);
}
void Eventor::Resume()
{
static const Exc_t _eh("Eventor::Resume ");
if(!bXMultix && mHost != mSaturn->GetSaturnInfo()) return;
if(!bRunning) {
ISwarn(_eh + "not running.");
}
if(!bSuspended) {
ISwarn(_eh + "not paused.");
}
mSaturn->GetChaItOss()->Resume(this);
}
void Eventor::Reset()
{
mTotalTime = mRunTime = 0;
mBeatsDone = mLocBeatsDone = 0;
mEventID = 0;
mInternalTime = 0;
Stamp(FID());
}
void Eventor::Cancel()
{
static const Exc_t _eh("Eventor::Cancel ");
if(!bXMultix && mHost != mSaturn->GetSaturnInfo()) return;
if(!bRunning) {
ISwarn(_eh + "not running.");
}
mSaturn->GetChaItOss()->Cancel(this);
}
void Eventor::ResetRecursively()
{
static const Exc_t _eh("Eventor::ResetRecursively ");
if(bRunning)
throw(_eh + "called during operation.");
Reset();
PARENT_GLASS::ResetRecursively();
}
void Eventor::SetHost(SaturnInfo* host)
{
static const Exc_t _eh("Eventor::SetHost ");
WriteLock();
try {
if(bRunning)
throw(_eh + "cannot change host while thread is running.");
set_link_or_die(mHost.ref_link(), host, FID());
}
catch(...) {
WriteUnlock();
throw;
}
WriteUnlock();
}
void Eventor::SetTrapAll()
{
bTrapILL = bTrapBUS = bTrapFPE = bTrapSEGV = true;
Stamp(FID());
}
Double_t Eventor::GetEventTime()
{
return mTimeStack.back();
}
void Eventor::PushEventTime(Double_t time)
{
mTimeStack.push_back(time);
}
void Eventor::PopEventTime()
{
mTimeStack.pop_back();
}