private void NextCue()
{
Cue cue;
if (this.requestedCueId.HasValue)
{
cue = this.cues[this.requestedCueId.Value];
this.requestedCueId = null;
RunCue(this.requestedCueId.Value, cue, true, false);
return;
}
if (this.cues.Count <= 0)
// Nothing to do
return;
if (this.iterationsLeft.HasValue && this.iterationsLeft.Value == 0)
// Done
return;
LockAllUsedDevices();
cue = AdvanceCue();
if (cue == null)
{
// Done
this.currentCueId.OnNext(null);
this.currentInstance = null;
ReleaseLocks();
return;
}
this.nextCuePos = GetNextCuePosition();
if (this.currentCuePos == this.cues.Count - 1)
{
// Last cue
if (this.iterationsLeft.HasValue)
this.iterationsLeft = this.iterationsLeft.Value - 1;
}
RunCue(this.currentCuePos, cue, false, !this.nextCuePos.HasValue);
if (this.nextCuePos.HasValue)
{
var nextCue = this.cues[this.nextCuePos.Value];
if (nextCue.Trigger == Cue.Triggers.Follow)
{
CancellationTokenSource triggerCancelSource;
if (this.triggerCancelSources.TryGetValue(nextCue, out triggerCancelSource))
{
triggerCancelSource.Cancel();
}
triggerCancelSource = new CancellationTokenSource();
this.triggerCancelSources[nextCue] = triggerCancelSource;
Task.Delay(nextCue.TriggerTimeMs, triggerCancelSource.Token).ContinueWith(x =>
{
if (!x.IsCanceled)
this.triggerNext.Set();
});
}
else if (nextCue.Trigger == Cue.Triggers.CueListTime)
{
//FIXME: How do we deal with this when we're playing the cuelist backwards?
int triggerDelay = nextCue.TriggerTimeMs - (int)this.cueListTime.ElapsedMilliseconds;
if (triggerDelay > 0)
{
CancellationTokenSource triggerCancelSource;
if (this.triggerCancelSources.TryGetValue(nextCue, out triggerCancelSource))
{
triggerCancelSource.Cancel();
}
triggerCancelSource = new CancellationTokenSource();
this.triggerCancelSources[nextCue] = triggerCancelSource;
Task.Delay(triggerDelay, triggerCancelSource.Token).ContinueWith(x =>
{
if (!x.IsCanceled)
this.triggerNext.Set();
});
}
}
}
}