Repository: psychopy/psychopy

Issue:
Builder Calibration or Validation shortens time / skips first trial if duration is used 
If an experiment specifies trial length by duration (say 5 seconds), adding eye tracker Calibration or Validation Component before the trial causes the trial to be skipped. It is as if the timer for the trial is not being reset before the trial starts. 

Run attached example and you will not see any trial screen (experiment will just exit after validation). 
[singlescreen.zip](https://github.com/psychopy/psychopy/files/6783170/singlescreen.zip)
 


Discussion:
updated OP to indicate both Calibration and Validation components seem to have same isssue. @TEParsons, would you be able to look into this please?
Current work around is to add an empty Routine to the flow right before the trial routine, and after Validation. The empty routine seems to cause the trial timer to be set correctly. 
Looks like the problem is with the routine timer - it gets reset at the end of the previous routine, but I guess it doesn't for standalone routines, so rather than starting counting down to 0 at 5s it starts at like -70s (or however long the previous routines took)

Resolving patch:
diff --git a/psychopy/experiment/flow.py b/psychopy/experiment/flow.py
--- a/psychopy/experiment/flow.py
+++ b/psychopy/experiment/flow.py
@@ -233,6 +233,8 @@ def writeBody(self, script):
         for entry in self:
             self._currentRoutine = entry
             entry.writeMainCode(script)
+            if hasattr(entry, "writeRoutineEndCode"):
+                entry.writeRoutineEndCode(script)
         # tear-down code (very few components need this)
         for entry in self:
             self._currentRoutine = entry
diff --git a/psychopy/experiment/routines/_base.py b/psychopy/experiment/routines/_base.py
--- a/psychopy/experiment/routines/_base.py
+++ b/psychopy/experiment/routines/_base.py
@@ -140,6 +140,13 @@ def writeRoutineBeginCodeJS(self, buff, modular):
     def writeEachFrameCodeJS(self, buff, modular):
         return
 
+    def writeRoutineEndCode(self, buff):
+        # reset routineTimer at the *very end* of all non-nonSlip routines
+        code = ('# the Routine "%s" was not non-slip safe, so reset '
+                'the non-slip timer\n'
+                'routineTimer.reset()\n')
+        buff.writeIndentedLines(code % self.name)
+
     def writeRoutineEndCodeJS(self, buff, modular):
         return
 
@@ -440,14 +447,6 @@ def writeMainCode(self, buff):
         for event in self:
             event.writeRoutineEndCode(buff)
 
-        # reset routineTimer at the *very end* of all non-nonSlip routines
-        if not useNonSlip:
-            code = ('# the Routine "%s" was not non-slip safe, so reset '
-                    'the non-slip timer\n'
-                    'routineTimer.reset()\n')
-            buff.writeIndentedLines(code % self.name)
-
-
     def writeRoutineBeginCodeJS(self, buff, modular):
 
         # create the frame loop for this routine
@@ -582,6 +581,17 @@ def writeEachFrameCodeJS(self, buff, modular):
         buff.setIndentLevel(-1, relative=True)
         buff.writeIndentedLines("}\n")
 
+    def writeRoutineEndCode(self, buff):
+        # can we use non-slip timing?
+        maxTime, useNonSlip = self.getMaxTime()
+
+        # reset routineTimer at the *very end* of all non-nonSlip routines
+        if not useNonSlip:
+            code = ('# the Routine "%s" was not non-slip safe, so reset '
+                    'the non-slip timer\n'
+                    'routineTimer.reset()\n')
+            buff.writeIndentedLines(code % self.name)
+
     def writeRoutineEndCodeJS(self, buff, modular):
         # can we use non-slip timing?
         maxTime, useNonSlip = self.getMaxTime()


Test patch: