private void StageProgram_StageChanged(object sender, StageChangedEventArgs e)
        {
            /* Get next stage, exit on null (END REACHED) */
            if (e.IsEndReached)
            {
                this.DispatcherInvoke(() => Stop());
                return;
            }
            var stage = e.Stage;

            /* Record marker */
            if (stage.Marker != null)
            {
                _markable?.Mark(stage.Marker.Value);
            }

            this.DispatcherInvoke(() =>
            {
                /* Update text */
                CueTextBlock.Text = stage.Cue;

                /* Update stage */
                if (stage is CptStage cptStage)
                {
                    var now   = CurrentTime;
                    var trial = new CptExperiment.CptTrial
                    {
                        Target       = cptStage.IsTarget,
                        Timestamp    = now,
                        Replied      = false,
                        ReactionTime = -1
                    };
                    _currentStage = new ActivedStage(now, cptStage, trial);
                    _trials.AddLast(trial);
                }
                else
                {
                    _currentStage = null;
                }

                /* Set focus */
                if (!IsFocused)
                {
                    Focus();
                }
            });
        }
 public ActivedStage(ulong timestamp, CptStage stage, CptExperiment.CptTrial trial)
 {
     Timestamp = timestamp;
     Stage     = stage;
     Trial     = trial;
 }