def writeFrameCodeJS(self, buff): # some shortcuts store = self.params['store'].val storeCorr = self.params['storeCorrect'].val forceEnd = self.params['forceEndRoutine'].val allowedKeys = self.params['allowedKeys'].val.strip() buff.writeIndented("\n") buff.writeIndented("// *%s* updates\n" % self.params['name']) # writes an if statement to determine whether to draw etc self.writeStartTestCodeJS(buff) buff.writeIndented("%(name)s.status = psychoJS.STARTED;\n" % self.params) allowedKeysIsVar = (valid_var_re.match(str(allowedKeys)) and not allowedKeys == 'None') if allowedKeysIsVar: # if it looks like a variable, check that the variable is suitable # to eval at run-time raise CodeGenerationException( "Variables for allowKeys aren't supported for JS yet") #code = ("# AllowedKeys looks like a variable named `%s`\n" # "if not '%s' in locals():\n" # " logging.error('AllowedKeys variable `%s` is not defined.')\n" # " core.quit()\n" # "if not type(%s) in [list, tuple, np.ndarray]:\n" # " if not isinstance(%s, basestring):\n" # " logging.error('AllowedKeys variable `%s` is " # "not string- or list-like.')\n" # " core.quit()\n" % # allowedKeys) # #vals = (allowedKeys, allowedKeys, allowedKeys) #code += ( # " elif not ',' in %s: %s = (%s,)\n" % vals + # " else: %s = eval(%s)\n" % (allowedKeys, allowedKeys)) #buff.writeIndentedLines(code) # #keyListStr = "keyList=list(%s)" % allowedKeys # eval at run time buff.writeIndented("// keyboard checking is just starting\n") if store != 'nothing': if self.params['syncScreenRefresh'].val: print("PsychoJS doesn't support win.callOnFlip() for keyboard") # code = ("win.callOnFlip(%(name)s.clock.reset) # " screen flip\n") % self.params code = "%(name)s.clock.reset(); // now t=0\n" % self.params else: code = "%(name)s.clock.reset(); // now t=0\n" % self.params buff.writeIndented(code) if self.params['discard previous'].val: buff.writeIndented("psychoJS.event.clearEvents({eventType:'keyboard'});\n") # to get out of the if statement buff.setIndentLevel(-1, relative=True) buff.writeIndented("}\n") # test for stop (only if there was some setting for duration or stop) if self.params['stopVal'].val not in ['', None, -1, 'None']: # writes an if statement to determine whether to draw etc self.writeStopTestCodeJS(buff) buff.writeIndented("%(name)s.status = psychoJS.STOPPED;\n" % self.params) # to get out of the if statement buff.setIndentLevel(-1, relative=True) buff.writeIndented("if (%(name)s.status == psychoJS.STARTED) {\n" % self.params) buff.setIndentLevel(1, relative=True) # to get out of if statement dedentAtEnd = 1 # keep track of how far to dedent later # do we need a list of keys? (variable case is already handled) if allowedKeys in [None, "none", "None", "", "[]", "()"]: keyListStr = "" elif not allowedKeysIsVar: try: keyList = eval(allowedKeys) except Exception: raise CodeGenerationException( self.params["name"], "Allowed keys list is invalid.") # this means the user typed "left","right" not ["left","right"] if type(keyList) == tuple: keyList = list(keyList) elif isinstance(keyList, basestring): # a single string/key keyList = [keyList] keyListStr = "{keyList:%s}" % repr(keyList) # check for keypresses buff.writeIndented("theseKeys = psychoJS.event.getKeys(%s);\n" % keyListStr) if self.exp.settings.params['Enable Escape'].val: code = ('\n// check for quit:\n' 'if ("escape" in theseKeys) {\n' ' endExpNow = true;\n' '}\n') buff.writeIndentedLines(code) # how do we store it? if store != 'nothing' or forceEnd: # we are going to store something code = ("if (theseKeys.length > 0) {" " // at least one key was pressed\n") buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 if store == 'first key': # then see if a key has already been pressed code = ("if (%(name)s.keys == []) {" " // then this was the first keypress\n") % self.params buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # to undo this level of "if" code = ("%(name)s.keys = theseKeys[0]" " // just the first key pressed\n" "%(name)s.rt = %(name)s.clock.getTime();\n") buff.writeIndentedLines(code % self.params) elif store == 'last key': code = ("%(name)s.keys = theseKeys[theseKeys.length-1]" " // just the last key pressed\n" "%(name)s.rt = %(name)s.clock.getTime();\n") buff.writeIndentedLines(code % self.params) elif store == 'all keys': code = ("%(name)s.keys = concat(%(name)s.keys, theseKeys); // storing all keys\n" "%(name)s.rt = concat(%(name)s.rt, %(name)s.clock.getTime());\n") buff.writeIndentedLines(code % self.params) if storeCorr: code = ("// was this 'correct'?\n" "if ((%(name)s.keys == psychoJS.str(%(correctAns)s))" " || (%(name)s.keys == %(correctAns)s)) {\n" " %(name)s.corr = 1;\n" "} else {\n" " %(name)s.corr = 0;\n" "}\n") buff.writeIndentedLines(code % self.params) if forceEnd == True: code = ("// a response ends the routine\n" "continueRoutine = false;\n") buff.writeIndentedLines(code % self.params) for dedents in range(dedentAtEnd): buff.setIndentLevel(-1, relative=True) buff.writeIndented("}\n")
def writeFrameCode(self, buff): """Write the code that will be called every frame. """ # some shortcuts store = self.params['store'].val storeCorr = self.params['storeCorrect'].val forceEnd = self.params['forceEndRoutine'].val useBoxTimer = self.params['useBoxTimer'].val # check whether we need to test for allowed keys (or just take all) allowedKeys = self.params['allowedKeys'].val.strip() allowedKeysIsVar = valid_var_re.match( str(allowedKeys)) and not allowedKeys == 'None' if allowedKeysIsVar: # only insert this code if we think allowed keys is a variable. # check at run-time that the var is suitable to eval key = {'key': allowedKeys} code = ("# AllowedKeys looks like a variable named `%(key)s`\n" "if not '%(key)s' in locals():\n" " logging.error('AllowedKeys variable `%(key)s` " "is not defined.')\n" " core.quit()\n" + "if not type(%(key)s) in [list, tuple, np.ndarray]:\n" " if not isinstance(%(key)s, basestring):\n" " logging.error('AllowedKeys variable `%(key)s`" " is not string- or list-like.')\n" " core.quit()\n" + " elif not ',' in %s(key): %(key)s = (%(key)s,)\n" " else: %(key)s = eval(%(key)s)\n") buff.writeIndentedLines(code % key) keyListStr = "keyList=list(%s)" % allowedKeys # eval() @ run time # now create the string that will loop-continue if if allowedKeys in [None, "none", "None", "", "[]", "()"]: keyCheckStr = "" elif not allowedKeysIsVar: try: keyList = eval(allowedKeys) except Exception: raise CodeGenerationException( self.params["name"], "Allowed keys list is invalid.") # this means the user typed "left","right" not ["left","right"] if type(keyList) == tuple: keyList = list(keyList) elif isinstance(keyList, basestring): # a single string/key keyList = [keyList] keyCheckStr = "%s" % (repr(keyList)) # if just now starting on this frame: buff.writeIndented("# *%(name)s* updates\n" % self.params) # write start code # writes an if statement to determine whether to start self.writeStartTestCode(buff) code = ("%(name)s.status = STARTED\n" "%(name)s.clock.reset() # now t=0\n") buff.writeIndentedLines(code % self.params) if self.params['discard previous'].val: code = ("# clear %(name)s responses (in a loop - the Cedrus " "own function doesn't work well)\n" "%(name)s.poll_for_response()\n" "while len(%(name)s.response_queue):\n" " %(name)s.clear_response_queue()\n" " %(name)s.poll_for_response() #often there are " "more resps waiting!\n") buff.writeIndentedLines(code % self.params) if useBoxTimer: code = "%(name)s.reset_rt_timer()\n" buff.writeIndented(code % self.params) # to get out of the if statement buff.setIndentLevel(-1, relative=True) # test for stop (only if there was some setting for duration or stop) if self.params['stopVal'].val not in ['', None, -1, 'None']: # writes an if statement to determine whether to draw etc self.writeStopTestCode(buff) buff.writeIndented("%(name)s.status = STOPPED\n" % self.params) buff.setIndentLevel(-1, True) buff.writeIndented("if %(name)s.status == STARTED:\n" % self.params) buff.setIndentLevel(1, relative=True) # to get out of if statement dedentAtEnd = 1 # keep track of how far to dedent later code = ("theseKeys=[]\n" "theseRTs=[]\n" "# check for key presses\n" "%(name)s.poll_for_response()\n" "while len(%(name)s.response_queue):\n" " evt = %(name)s.get_next_response()\n") buff.writeIndentedLines(code % self.params) if len(keyCheckStr): code = (" if evt['key'] not in %s:\n" % keyList + " continue # we don't care about this key\n") buff.writeIndentedLines(code) code = (" if evt['pressed']:\n" " theseKeys.append(evt['key'])\n") buff.writeIndentedLines(code) if useBoxTimer: code = " theseRTs.append(evt['time']/1000.0)\n" buff.writeIndented(code) else: code = " theseRTs.append(%(name)s.clock.getTime())\n" buff.writeIndented(code % self.params) code = (" %(name)s.poll_for_response()\n" "%(name)s.clear_response_queue() # don't process again\n") buff.writeIndentedLines(code % self.params) # how do we store it? if store != 'nothing' or forceEnd: # we are going to store something code = "if len(theseKeys) > 0: # at least one key was pressed\n" buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 if store == 'first key': # then see if a key has already been pressed code = "if %(name)s.keys == []: # then this is first keypress\n" buff.writeIndented(code % self.params) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 code = ("%(name)s.keys = theseKeys[0] # the first key pressed\n" "%(name)s.rt = theseRTs[0]\n") buff.writeIndentedLines(code % self.params) elif store == 'last key': code = ("%(name)s.keys = theseKeys[-1] # the last key pressed\n" "%(name)s.rt = theseRTs[-1]\n") buff.writeIndentedLines(code % self.params) elif store == 'all keys': code = ("%(name)s.keys.extend(theseKeys) # storing all keys\n" "%(name)s.rt.extend(theseRTs)\n") buff.writeIndentedLines(code % self.params) else: print((store, type(store), str(store))) if storeCorr: code = ("# was this 'correct'?\n" "if (%(name)s.keys == str(%(correctAns)s)) or " "(%(name)s.keys == %(correctAns)s):\n" " %(name)s.corr = 1\n" "else:\n" " %(name)s.corr = 0\n") buff.writeIndentedLines(code % self.params) if forceEnd is True: code = ("# a response ends the routine\n" "continueRoutine = False\n") buff.writeIndentedLines(code) buff.setIndentLevel(-(dedentAtEnd), relative=True)
def writeFrameCode(self, buff): """Write the code that will be called every frame """ # some shortcuts store = self.params['store'].val storeCorr = self.params['storeCorrect'].val forceEnd = self.params['forceEndRoutine'].val allowedKeys = self.params['allowedKeys'].val.strip() buff.writeIndented("\n") buff.writeIndented("# *%s* updates\n" % self.params['name']) # writes an if statement to determine whether to draw etc self.writeStartTestCode(buff) buff.writeIndented("%(name)s.status = STARTED\n" % self.params) allowedKeysIsVar = (valid_var_re.match(str(allowedKeys)) and not allowedKeys == 'None') if allowedKeysIsVar: # if it looks like a variable, check that the variable is suitable # to eval at run-time code = ("# AllowedKeys looks like a variable named `{0}`\n" "if not type({0}) in [list, tuple, np.ndarray]:\n" " if not isinstance({0}, basestring):\n" " logging.error('AllowedKeys variable `{0}` is " "not string- or list-like.')\n" " core.quit()\n" .format(allowedKeys)) code += ( " elif not ',' in {0}: {0} = ({0},)\n" " else: {0} = eval({0})\n" .format(allowedKeys)) buff.writeIndentedLines(code) keyListStr = "keyList=list(%s)" % allowedKeys # eval at run time buff.writeIndented("# keyboard checking is just starting\n") if store != 'nothing': if self.params['syncScreenRefresh'].val: code = ("win.callOnFlip(%(name)s.clock.reset) # t=0 on next" " screen flip\n") % self.params else: code = "%(name)s.clock.reset() # now t=0\n" % self.params buff.writeIndented(code) if self.params['discard previous'].val: buff.writeIndented("event.clearEvents(eventType='keyboard')\n") # to get out of the if statement buff.setIndentLevel(-1, relative=True) # test for stop (only if there was some setting for duration or stop) if self.params['stopVal'].val not in ['', None, -1, 'None']: # writes an if statement to determine whether to draw etc self.writeStopTestCode(buff) buff.writeIndented("%(name)s.status = STOPPED\n" % self.params) # to get out of the if statement buff.setIndentLevel(-1, relative=True) buff.writeIndented("if %(name)s.status == STARTED:\n" % self.params) buff.setIndentLevel(1, relative=True) # to get out of if statement dedentAtEnd = 1 # keep track of how far to dedent later # do we need a list of keys? (variable case is already handled) if allowedKeys in [None, "none", "None", "", "[]", "()"]: keyListStr = "" elif not allowedKeysIsVar: try: keyList = eval(allowedKeys) except Exception: raise CodeGenerationException( self.params["name"], "Allowed keys list is invalid.") # this means the user typed "left","right" not ["left","right"] if type(keyList) == tuple: keyList = list(keyList) elif isinstance(keyList, basestring): # a single string/key keyList = [keyList] keyListStr = "keyList=%s" % repr(keyList) # check for keypresses buff.writeIndented("theseKeys = event.getKeys(%s)\n" % keyListStr) if self.exp.settings.params['Enable Escape'].val: code = ('\n# check for quit:\n' 'if "escape" in theseKeys:\n' ' endExpNow = True\n') buff.writeIndentedLines(code) # how do we store it? if store != 'nothing' or forceEnd: # we are going to store something code = "if len(theseKeys) > 0: # at least one key was pressed\n" buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 if store == 'first key': # then see if a key has already been pressed code = ("if %(name)s.keys == []: # then this was the first " "keypress\n") % self.params buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 code = ("%(name)s.keys = theseKeys[0] # just the first key pressed\n" "%(name)s.rt = %(name)s.clock.getTime()\n") buff.writeIndentedLines(code % self.params) elif store == 'last key': code = ("%(name)s.keys = theseKeys[-1] # just the last key pressed\n" "%(name)s.rt = %(name)s.clock.getTime()\n") buff.writeIndentedLines(code % self.params) elif store == 'all keys': code = ("%(name)s.keys.extend(theseKeys) # storing all keys\n" "%(name)s.rt.append(%(name)s.clock.getTime())\n") buff.writeIndentedLines(code % self.params) if storeCorr: code = ("# was this 'correct'?\n" "if (%(name)s.keys == str(%(correctAns)s)) or (%(name)s.keys == %(correctAns)s):\n" " %(name)s.corr = 1\n" "else:\n" " %(name)s.corr = 0\n") buff.writeIndentedLines(code % self.params) if forceEnd == True: code = ("# a response ends the routine\n" "continueRoutine = False\n") buff.writeIndentedLines(code % self.params) buff.setIndentLevel(-(dedentAtEnd), relative=True)
def writeRoutineStartCode(self, buff): """Write the code that will be called at the start of the routine """ code = ("{name}.oldButtonState = {name}.device.getAllButtons()[:]\n") buff.writeIndentedLines(code.format(**self.params)) allowedButtons = self.params['allowedButtons'].val.strip() allowedButtonsIsVar = (valid_var_re.match(str(allowedButtons)) and not allowedButtons == 'None') if allowedButtonsIsVar: # if it looks like a variable, check that the variable is suitable # to eval at run-time code = ("# AllowedKeys looks like a variable named `{0}`\n" #"print(\"{0}<{{}}> type:{{}}\".format({0}, type({0})))\n" "if not type({0}) in [list, tuple, np.ndarray]:\n") buff.writeIndentedLines(code.format(allowedButtons)) buff.setIndentLevel(1, relative=True) code = ("if type({0}) == int:\n") buff.writeIndentedLines(code.format(allowedButtons)) buff.setIndentLevel(1, relative=True) code = ("{0} = [{0}]\n") buff.writeIndentedLines(code.format(allowedButtons)) buff.setIndentLevel(-1, relative=True) code = ("elif not isinstance({0}, str):\n") buff.writeIndentedLines(code.format(allowedButtons)) buff.setIndentLevel(1, relative=True) code = ("logging.error('AllowedKeys variable `{0}` is " "not string- or list-like.')\n" "core.quit()\n") buff.writeIndentedLines(code.format(allowedButtons)) buff.setIndentLevel(-1, relative=True) code = ("elif not ',' in {0}: {0} = eval(({0},))\n" "else: {0} = eval({0})\n") buff.writeIndentedLines(code.format(allowedButtons)) buff.setIndentLevel(-1, relative=True) # do we need a list of buttons? (variable case is already handled) if allowedButtons in [None, "none", "None", "", "[]", "()"]: buttonList=[] elif not allowedButtonsIsVar: try: buttonList = eval(allowedButtons) except Exception: raise CodeGenerationException( self.params["name"], "Allowed buttons list is invalid.") if type(buttonList) == tuple: buttonList = list(buttonList) elif isinstance(buttonList, int): # a single string/key buttonList = [buttonList] #print("buttonList={}".format(buttonList)) if allowedButtonsIsVar: code = ("{name}.activeButtons={0}\n") buff.writeIndentedLines(code.format(allowedButtons, **self.params)) else: if buttonList == []: code = ("{name}.activeButtons=[i for i in range({name}.numButtons)]") buff.writeIndentedLines(code.format(allowedButtons, **self.params)) else: code = ("{name}.activeButtons={0}") buff.writeIndentedLines(code.format(buttonList, **self.params)) # create some lists to store recorded values positions and events if # we need more than one code = ("# setup some python lists for storing info about the " "%(name)s\n") if self.params['saveJoystickState'].val in ['every frame', 'on click']: code += ("%(name)s.x = []\n" "%(name)s.y = []\n" "%(name)s.buttonLogs = [[] for i in range(%(name)s.numButtons)]\n" "%(name)s.time = []\n") if self.params['clickable'].val: for clickableObjParam in self._clickableParamsList: code += "%(name)s.clicked_{} = []\n".format(clickableObjParam) code += "gotValidClick = False # until a click is received\n" if self.params['timeRelativeTo'].val.lower() == 'routine': code += "%(name)s.joystickClock.reset()\n" buff.writeIndentedLines(code % self.params)
def writeFrameCode(self, buff): """Write the code that will be called every frame """ # some shortcuts store = self.params['store'].val storeCorr = self.params['storeCorrect'].val forceEnd = self.params['forceEndRoutine'].val allowedKeys = self.params['allowedKeys'].val.strip() buff.writeIndented("\n") buff.writeIndented("# *%s* updates\n" % self.params['name']) # writes an if statement to determine whether to draw etc self.writeStartTestCode(buff) buff.writeIndented("%(name)s.status = STARTED\n" % self.params) allowedKeysIsVar = (valid_var_re.match(str(allowedKeys)) and not allowedKeys == 'None') if allowedKeysIsVar: # if it looks like a variable, check that the variable is suitable # to eval at run-time code = ("# AllowedKeys looks like a variable named `{0}`\n" "if not type({0}) in [list, tuple, np.ndarray]:\n") buff.writeIndentedLines(code.format(allowedKeys)) buff.setIndentLevel(1, relative=True) code = ("if type({0}) == int:\n") buff.writeIndentedLines(code.format(allowedKeys)) buff.setIndentLevel(1, relative=True) code = ("{0} = [{0}]\n") buff.writeIndentedLines(code.format(allowedKeys)) buff.setIndentLevel(-1, relative=True) code = ("elif not (isinstance({0}, str) " "or isinstance({0}, unicode)):\n") buff.writeIndentedLines(code.format(allowedKeys)) buff.setIndentLevel(1, relative=True) code = ("logging.error('AllowedKeys variable `{0}` is " "not string- or list-like.')\n" "core.quit()\n") buff.writeIndentedLines(code.format(allowedKeys)) buff.setIndentLevel(-1, relative=True) code = ( "elif not ',' in {0}: {0} = eval(({0},))\n" "else: {0} = eval({0})\n") buff.writeIndentedLines(code.format(allowedKeys)) buff.setIndentLevel(-1, relative=True) buff.writeIndented("# joyButtons checking is just starting\n") if store != 'nothing': if self.params['syncScreenRefresh'].val: code = ("win.callOnFlip(%(name)s.clock.reset) # t=0 on next" " screen flip\n") % self.params else: code = "%(name)s.clock.reset() # now t=0\n" % self.params buff.writeIndented(code) # to get out of the if statement buff.setIndentLevel(-1, relative=True) # test for stop (only if there was some setting for duration or stop) if self.params['stopVal'].val not in ['', None, -1, 'None']: # writes an if statement to determine whether to draw etc self.writeStopTestCode(buff) buff.writeIndented("%(name)s.status = STOPPED\n" % self.params) # to get out of the if statement buff.setIndentLevel(-1, relative=True) buff.writeIndented("if %(name)s.status == STARTED:\n" % self.params) buff.setIndentLevel(1, relative=True) # to get out of if statement dedentAtEnd = 1 # keep track of how far to dedent later # do we need a list of keys? (variable case is already handled) if allowedKeys in [None, "none", "None", "", "[]", "()"]: keyList=[] elif not allowedKeysIsVar: try: keyList = eval(allowedKeys) except Exception: raise CodeGenerationException( self.params["name"], "Allowed keys list is invalid.") # this means the user typed "left","right" not ["left","right"] if type(keyList) == tuple: keyList = list(keyList) elif isinstance(keyList, int): # a single string/key keyList = [keyList] code1 = ("{name}.newButtonState = {name}.device.getAllButtons()[:]\n" "{name}.pressedButtons = []\n" "{name}.releasedButtons = []\n" "{name}.newPressedButtons = []\n" "if {name}.newButtonState != {name}.oldButtonState:\n") code2 = ("{name}.pressedButtons = [i for i in range({name}.numButtons) " "if {name}.newButtonState[i] and not {name}.oldButtonState[i]]\n" "{name}.releasedButtons = [i for i in range({name}.numButtons) " "if not {name}.newButtonState[i] and {name}.oldButtonState[i]]\n" "{name}.oldButtonState = {name}.newButtonState\n" "{name}.newPressedButtons = " "[i for i in {0} if i in {name}.pressedButtons]\n" "[logging.data(\"joystick_{{}}_button: {{}}\".format(" "{name}.device_number,i)) for i in {name}.pressedButtons]\n" ) if allowedKeysIsVar: buff.writeIndentedLines(code1.format(allowedKeys, **self.params)) buff.setIndentLevel(+1, relative=True) buff.writeIndentedLines(code2.format(allowedKeys, **self.params)) buff.setIndentLevel(-1, relative=True) else: if keyList == []: buff.writeIndentedLines(code1.format(allowedKeys, **self.params)) buff.setIndentLevel(+1, relative=True) buff.writeIndentedLines(code2.format( "{name}.buttonNumbers".format(**self.params), **self.params)) buff.setIndentLevel(-1, relative=True) else: buff.writeIndentedLines(code1.format(allowedKeys, **self.params)) buff.setIndentLevel(+1, relative=True) buff.writeIndentedLines( code2.format("{}".format(keyList), **self.params)) buff.setIndentLevel(-1, relative=True) code = ( "theseKeys = %(name)s.newPressedButtons\n" ) buff.writeIndented(code % self.params) if self.exp.settings.params['Enable Escape'].val: code = ('\n# check for quit:\n' 'if "escape" in theseKeys:\n' ' endExpNow = True\n') # how do we store it? if store != 'nothing' or forceEnd: # we are going to store something code = "if len(theseKeys) > 0: # at least one key was pressed\n" buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 if store == 'first key': # then see if a key has already been pressed code = ("if %(name)s.keys == []: # then this was the first " "keypress\n") % self.params buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 code = ("%(name)s.keys = theseKeys[0] # just the first key pressed\n" "%(name)s.rt = %(name)s.clock.getTime()\n") buff.writeIndentedLines(code % self.params) elif store == 'last key': code = ("%(name)s.keys = theseKeys[-1] # just the last key pressed\n" "%(name)s.rt = %(name)s.clock.getTime()\n") buff.writeIndentedLines(code % self.params) elif store == 'all keys': code = ("%(name)s.keys.extend(theseKeys) # storing all keys\n" "%(name)s.rt.append(%(name)s.clock.getTime())\n") buff.writeIndentedLines(code % self.params) if storeCorr: code = ("# was this 'correct'?\n" "if (str(%(name)s.keys) == str(%(correctAns)s)):\n") buff.writeIndentedLines(code % self.params) buff.setIndentLevel(+1, relative=True) code = ("%(name)s.corr = 1\n") buff.writeIndentedLines(code % self.params) buff.setIndentLevel(-1, relative=True) code = ("else:\n") buff.writeIndentedLines(code % self.params) buff.setIndentLevel(+1, relative=True) code = ("%(name)s.corr = 0\n") buff.writeIndentedLines(code % self.params) buff.setIndentLevel(-1, relative=True) if forceEnd == True: code = ("# a response ends the routine\n" "continueRoutine = False\n") buff.writeIndentedLines(code % self.params) buff.setIndentLevel(-(dedentAtEnd), relative=True)
def writeFrameCode(self, buff): """Write the code that will be called every frame. """ # some shortcuts store = self.params['store'].val storeCorr = self.params['storeCorrect'].val forceEnd = self.params['forceEndRoutine'].val useBoxTimer = self.params['useBoxTimer'].val # check whether we need to test for allowed keys (or just take all) allowedKeys = self.params['allowedKeys'].val.strip() allowedKeysIsVar = valid_var_re.match( str(allowedKeys)) and not allowedKeys == 'None' if allowedKeysIsVar: # only insert this code if we think allowed keys is a variable. # check at run-time that the var is suitable to eval key = {'key': allowedKeys} code = ("# AllowedKeys looks like a variable named `%(key)s`\n" "if not '%(key)s' in locals():\n" " logging.error('AllowedKeys variable `%(key)s` " "is not defined.')\n" " core.quit()\n" + "if not type(%(key)s) in [list, tuple, np.ndarray]:\n" " if not isinstance(%(key)s, basestring):\n" " logging.error('AllowedKeys variable `%(key)s`" " is not string- or list-like.')\n" " core.quit()\n" + " elif not ',' in %s(key): %(key)s = (%(key)s,)\n" " else: %(key)s = eval(%(key)s)\n") buff.writeIndentedLines(code % key) keyListStr = "keyList=list(%s)" % allowedKeys # eval() @ run time # now create the string that will loop-continue if if allowedKeys in [None, "none", "None", "", "[]", "()"]: keyCheckStr = "" elif not allowedKeysIsVar: try: keyList = eval(allowedKeys) except Exception: raise CodeGenerationException(self.params["name"], "Allowed keys list is invalid.") # this means the user typed "left","right" not ["left","right"] if type(keyList) == tuple: keyList = list(keyList) elif isinstance(keyList, basestring): # a single string/key keyList = [keyList] keyCheckStr = "%s" % (repr(keyList)) # if just now starting on this frame: buff.writeIndented("# *%(name)s* updates\n" % self.params) # write start code # writes an if statement to determine whether to start self.writeStartTestCode(buff) code = ("%(name)s.status = STARTED\n" "%(name)s.clock.reset() # now t=0\n") buff.writeIndentedLines(code % self.params) if self.params['discard previous'].val: code = ("# clear %(name)s responses (in a loop - the Cedrus " "own function doesn't work well)\n" "%(name)s.poll_for_response()\n" "while len(%(name)s.response_queue):\n" " %(name)s.clear_response_queue()\n" " %(name)s.poll_for_response() #often there are " "more resps waiting!\n") buff.writeIndentedLines(code % self.params) if useBoxTimer: code = "%(name)s.reset_rt_timer()\n" buff.writeIndented(code % self.params) # to get out of the if statement buff.setIndentLevel(-1, relative=True) # test for stop (only if there was some setting for duration or stop) if self.params['stopVal'].val not in ['', None, -1, 'None']: # writes an if statement to determine whether to draw etc self.writeStopTestCode(buff) buff.writeIndented("%(name)s.status = FINISHED\n" % self.params) buff.setIndentLevel(-2, True) buff.writeIndented("if %(name)s.status == STARTED:\n" % self.params) buff.setIndentLevel(1, relative=True) # to get out of if statement dedentAtEnd = 1 # keep track of how far to dedent later code = ("theseKeys=[]\n" "theseRTs=[]\n" "# check for key presses\n" "%(name)s.poll_for_response()\n" "while len(%(name)s.response_queue):\n" " evt = %(name)s.get_next_response()\n") buff.writeIndentedLines(code % self.params) if len(keyCheckStr): code = (" if evt['key'] not in %s:\n" % keyList + " continue # we don't care about this key\n") buff.writeIndentedLines(code) code = (" if evt['pressed']:\n" " theseKeys.append(evt['key'])\n") buff.writeIndentedLines(code) if useBoxTimer: code = " theseRTs.append(evt['time']/1000.0)\n" buff.writeIndented(code) else: code = " theseRTs.append(%(name)s.clock.getTime())\n" buff.writeIndented(code % self.params) code = (" %(name)s.poll_for_response()\n" "%(name)s.clear_response_queue() # don't process again\n") buff.writeIndentedLines(code % self.params) # how do we store it? if store != 'nothing' or forceEnd: # we are going to store something code = "if len(theseKeys) > 0: # at least one key was pressed\n" buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 if store == 'first key': # then see if a key has already been pressed code = "if %(name)s.keys == []: # then this is first keypress\n" buff.writeIndented(code % self.params) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 code = ("%(name)s.keys = theseKeys[0] # the first key pressed\n" "%(name)s.rt = theseRTs[0]\n") buff.writeIndentedLines(code % self.params) elif store == 'last key': code = ("%(name)s.keys = theseKeys[-1] # the last key pressed\n" "%(name)s.rt = theseRTs[-1]\n") buff.writeIndentedLines(code % self.params) elif store == 'all keys': code = ("%(name)s.keys.extend(theseKeys) # storing all keys\n" "%(name)s.rt.extend(theseRTs)\n") buff.writeIndentedLines(code % self.params) else: print((store, type(store), str(store))) if storeCorr: code = ("# was this 'correct'?\n" "if (%(name)s.keys == str(%(correctAns)s)) or " "(%(name)s.keys == %(correctAns)s):\n" " %(name)s.corr = 1\n" "else:\n" " %(name)s.corr = 0\n") buff.writeIndentedLines(code % self.params) if forceEnd is True: code = ("# a response ends the routine\n" "continueRoutine = False\n") buff.writeIndentedLines(code) buff.setIndentLevel(-(dedentAtEnd), relative=True)
def writeFrameCode(self, buff): """Write the code that will be called every frame """ # some shortcuts store = self.params['store'].val storeCorr = self.params['storeCorrect'].val forceEnd = self.params['forceEndRoutine'].val allowedKeys = self.params['allowedKeys'].val.strip() buff.writeIndented("\n") buff.writeIndented("# *%s* updates\n" % self.params['name']) # writes an if statement to determine whether to draw etc self.writeStartTestCode(buff) buff.writeIndented("%(name)s.status = STARTED\n" % self.params) allowedKeysIsVar = (valid_var_re.match(str(allowedKeys)) and not allowedKeys == 'None') if allowedKeysIsVar: # if it looks like a variable, check that the variable is suitable # to eval at run-time code = ("# AllowedKeys looks like a variable named `{0}`\n" "if not type({0}) in [list, tuple, np.ndarray]:\n" " if not isinstance({0}, basestring):\n" " logging.error('AllowedKeys variable `{0}` is " "not string- or list-like.')\n" " core.quit()\n" .format(allowedKeys)) code += ( " elif not ',' in {0}: {0} = ({0},)\n" " else: {0} = eval({0})\n" .format(allowedKeys)) buff.writeIndentedLines(code) keyListStr = "keyList=list(%s)" % allowedKeys # eval at run time buff.writeIndented("# keyboard checking is just starting\n") if store != 'nothing': if self.params['syncScreenRefresh'].val: code = ("win.callOnFlip(%(name)s.clock.reset) # t=0 on next" " screen flip\n") % self.params else: code = "%(name)s.clock.reset() # now t=0\n" % self.params buff.writeIndented(code) if self.params['discard previous'].val: buff.writeIndented("event.clearEvents(eventType='keyboard')\n") # to get out of the if statement buff.setIndentLevel(-1, relative=True) # test for stop (only if there was some setting for duration or stop) if self.params['stopVal'].val not in ['', None, -1, 'None']: # writes an if statement to determine whether to draw etc self.writeStopTestCode(buff) buff.writeIndented("%(name)s.status = FINISHED\n" % self.params) # to get out of the if statement buff.setIndentLevel(-1, relative=True) buff.writeIndented("if %(name)s.status == STARTED:\n" % self.params) buff.setIndentLevel(1, relative=True) # to get out of if statement dedentAtEnd = 1 # keep track of how far to dedent later # do we need a list of keys? (variable case is already handled) if allowedKeys in [None, "none", "None", "", "[]", "()"]: keyListStr = "" elif not allowedKeysIsVar: try: keyList = eval(allowedKeys) except Exception: raise CodeGenerationException( self.params["name"], "Allowed keys list is invalid.") # this means the user typed "left","right" not ["left","right"] if type(keyList) == tuple: keyList = list(keyList) elif isinstance(keyList, basestring): # a single string/key keyList = [keyList] keyListStr = "keyList=%s" % repr(keyList) # check for keypresses buff.writeIndented("theseKeys = event.getKeys(%s)\n" % keyListStr) if self.exp.settings.params['Enable Escape'].val: code = ('\n# check for quit:\n' 'if "escape" in theseKeys:\n' ' endExpNow = True\n') buff.writeIndentedLines(code) # how do we store it? if store != 'nothing' or forceEnd: # we are going to store something code = "if len(theseKeys) > 0: # at least one key was pressed\n" buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 if store == 'first key': # then see if a key has already been pressed code = ("if %(name)s.keys == []: # then this was the first " "keypress\n") % self.params buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 code = ("%(name)s.keys = theseKeys[0] # just the first key pressed\n" "%(name)s.rt = %(name)s.clock.getTime()\n") buff.writeIndentedLines(code % self.params) elif store == 'last key': code = ("%(name)s.keys = theseKeys[-1] # just the last key pressed\n" "%(name)s.rt = %(name)s.clock.getTime()\n") buff.writeIndentedLines(code % self.params) elif store == 'all keys': code = ("%(name)s.keys.extend(theseKeys) # storing all keys\n" "%(name)s.rt.append(%(name)s.clock.getTime())\n") buff.writeIndentedLines(code % self.params) if storeCorr: code = ("# was this 'correct'?\n" "if (%(name)s.keys == str(%(correctAns)s)) or (%(name)s.keys == %(correctAns)s):\n" " %(name)s.corr = 1\n" "else:\n" " %(name)s.corr = 0\n") buff.writeIndentedLines(code % self.params) if forceEnd == True: code = ("# a response ends the routine\n" "continueRoutine = False\n") buff.writeIndentedLines(code % self.params) buff.setIndentLevel(-(dedentAtEnd), relative=True)
def writeFrameCodeJS(self, buff): # some shortcuts store = self.params['store'].val storeCorr = self.params['storeCorrect'].val forceEnd = self.params['forceEndRoutine'].val allowedKeys = self.params['allowedKeys'].val.strip() buff.writeIndented("\n") buff.writeIndented("// *%s* updates\n" % self.params['name']) # writes an if statement to determine whether to draw etc self.writeStartTestCodeJS(buff) allowedKeysIsVar = (valid_var_re.match(str(allowedKeys)) and not allowedKeys == 'None') if allowedKeysIsVar: # if it looks like a variable, check that the variable is suitable # to eval at run-time raise CodeGenerationException( "Variables for allowKeys aren't supported for JS yet") #code = ("# AllowedKeys looks like a variable named `%s`\n" # "if not '%s' in locals():\n" # " logging.error('AllowedKeys variable `%s` is not defined.')\n" # " core.quit()\n" # "if not type(%s) in [list, tuple, np.ndarray]:\n" # " if not isinstance(%s, basestring):\n" # " logging.error('AllowedKeys variable `%s` is " # "not string- or list-like.')\n" # " core.quit()\n" % # allowedKeys) # #vals = (allowedKeys, allowedKeys, allowedKeys) #code += ( # " elif not ',' in %s: %s = (%s,)\n" % vals + # " else: %s = eval(%s)\n" % (allowedKeys, allowedKeys)) #buff.writeIndentedLines(code) # #keyListStr = "keyList=list(%s)" % allowedKeys # eval at run time buff.writeIndented("// keyboard checking is just starting\n") if self.params['syncScreenRefresh'].val: code = ("psychoJS.window.callOnFlip(function() { %(name)s.clock.reset(); }); " "// t=0 on next screen flip\n" "psychoJS.window.callOnFlip(function() { %(name)s.start(); }); " "// start on screen flip\n") % self.params else: code = ("%(name)s.clock.reset();\n" "%(name)s.start();\n") % self.params buff.writeIndentedLines(code) if self.params['discard previous'].val: if self.params['syncScreenRefresh'].val: buff.writeIndented("psychoJS.window.callOnFlip(function() { %(name)s.clearEvents(); });\n" % self.params) else: buff.writeIndented("%(name)s.clearEvents();\n" % self.params) # to get out of the if statement buff.setIndentLevel(-1, relative=True) buff.writeIndented("}\n\n") # test for stop (only if there was some setting for duration or stop) if self.params['stopVal'].val not in ['', None, -1, 'None']: # writes an if statement to determine whether to draw etc self.writeStopTestCodeJS(buff) buff.writeIndented("%(name)s.status = PsychoJS.Status.FINISHED;\n" " }\n" "\n" % self.params) # to get out of the if statement buff.setIndentLevel(-1, relative=True) buff.writeIndented("if (%(name)s.status === PsychoJS.Status.STARTED) {\n" % self.params) buff.setIndentLevel(1, relative=True) # to get out of if statement dedentAtEnd = 1 # keep track of how far to dedent later # do we need a list of keys? (variable case is already handled) if allowedKeys in [None, "none", "None", "", "[]", "()"]: keyListStr = "[]" elif not allowedKeysIsVar: try: keyList = eval(allowedKeys) except Exception: raise CodeGenerationException( self.params["name"], "Allowed keys list is invalid.") # this means the user typed "left","right" not ["left","right"] if type(keyList) == tuple: keyList = list(keyList) elif isinstance(keyList, basestring): # a single string/key keyList = [keyList] keyListStr = "%s" % repr(keyList) # check for keypresses code = ("let theseKeys = {name}.getKeys({{keyList: {keyStr}, waitRelease: false}});\n" "_{name}_allKeys = _{name}_allKeys.concat(theseKeys);\n" "if (_{name}_allKeys.length > 0) {{\n") buff.writeIndentedLines( code.format( name=self.params['name'], keyStr=keyListStr ) ) buff.setIndentLevel(1, True) dedentAtEnd += 1 # how do we store it? if store == 'first key': # then see if a key has already been pressed code = ("{name}.keys = _{name}_allKeys[0].name; // just the first key pressed\n" "{name}.rt = _{name}_allKeys[0].rt;\n") buff.writeIndentedLines(code.format(name=self.params['name'])) elif store == 'last key' or store =='nothing': code = ("{name}.keys = _{name}_allKeys[_{name}_allKeys.length - 1].name; // just the last key pressed\n" "{name}.rt = _{name}_allKeys[_{name}_allKeys.length - 1].rt;\n") buff.writeIndentedLines(code.format(name=self.params['name'])) elif store == 'all keys': code = ("{name}.keys = _{name}_allKeys.map((key) => key.name); // storing all keys\n" "{name}.rt = _{name}_allKeys.map((key) => key.rt);\n") buff.writeIndentedLines(code.format(name=self.params['name'])) if storeCorr: code = ("// was this correct?\n" "if ({name}.keys == {correctAns}) {{\n" " {name}.corr = 1;\n" "}} else {{\n" " {name}.corr = 0;\n" "}}\n") buff.writeIndentedLines( code.format( name=self.params['name'], correctAns=self.params['correctAns'] ) ) if forceEnd == True: code = ("// a response ends the routine\n" "continueRoutine = false;\n") buff.writeIndentedLines(code) for dedents in range(dedentAtEnd): buff.setIndentLevel(-1, relative=True) buff.writeIndented("}\n") buff.writeIndented("\n")
def writeFrameCode(self, buff): """Write the code that will be called every frame """ # some shortcuts store = self.params['store'].val storeCorr = self.params['storeCorrect'].val forceEnd = self.params['forceEndRoutine'].val allowedKeys = str(self.params['allowedKeys']) visualSync = self.params['syncScreenRefresh'].val buff.writeIndented("\n") buff.writeIndented("# *%s* updates\n" % self.params['name']) if visualSync: buff.writeIndented("waitOnFlip = False\n") # writes an if statement to determine whether to draw etc self.writeStartTestCode(buff) buff.writeIndented("%(name)s.status = STARTED\n" % self.params) allowedKeysIsVar = (valid_var_re.match(str(allowedKeys)) and not allowedKeys == 'None') if allowedKeysIsVar: # if it looks like a variable, check that the variable is suitable # to eval at run-time stringType = '{}'.format(['basestring', 'str'][PY3]) code = ("# AllowedKeys looks like a variable named `{0}`\n" "if not type({0}) in [list, tuple, np.ndarray]:\n" " if not isinstance({0}, {1}):\n" " logging.error('AllowedKeys variable `{0}` is " "not string- or list-like.')\n" " core.quit()\n" .format(allowedKeys, stringType)) code += ( " elif not ',' in {0}:\n" " {0} = ({0},)\n" " else:\n" " {0} = eval({0})\n" .format(allowedKeys)) buff.writeIndentedLines(code) keyListStr = "list(%s)" % allowedKeys # eval at run time buff.writeIndented("# keyboard checking is just starting\n") if visualSync: code = ("waitOnFlip = True\n" "win.callOnFlip(%(name)s.clock.reset) " "# t=0 on next screen flip\n") % self.params else: code = "%(name)s.clock.reset() # now t=0\n" % self.params buff.writeIndentedLines(code) if self.params['discard previous'].val: if visualSync: code = ("win.callOnFlip(%(name)s.clearEvents, eventType='keyboard') " "# clear events on next screen flip\n") % self.params else: code = "%(name)s.clearEvents(eventType='keyboard')\n" % self.params buff.writeIndented(code) # to get out of the if statement buff.setIndentLevel(-1, relative=True) # test for stop (only if there was some setting for duration or stop) if self.params['stopVal'].val not in ['', None, -1, 'None']: # writes an if statement to determine whether to draw etc self.writeStopTestCode(buff) buff.writeIndented("%(name)s.status = FINISHED\n" % self.params) # to get out of the if statement buff.setIndentLevel(-2, relative=True) buff.writeIndented("if %s.status == STARTED%s:\n" % (self.params['name'], ['', ' and not waitOnFlip'][visualSync])) buff.setIndentLevel(1, relative=True) # to get out of if statement dedentAtEnd = 1 # keep track of how far to dedent later # do we need a list of keys? (variable case is already handled) if allowedKeys in [None, "none", "None", "", "[]", "()"]: keyListStr = "" elif not allowedKeysIsVar: try: keyList = eval(allowedKeys) except Exception: raise CodeGenerationException( self.params["name"], "Allowed keys list is invalid.") # this means the user typed "left","right" not ["left","right"] if type(keyList) == tuple: keyList = list(keyList) elif isinstance(keyList, basestring): # a single string/key keyList = [keyList] keyListStr = "%s" % repr(keyList) # check for keypresses code = ("theseKeys = {name}.getKeys(keyList={keyStr}, waitRelease=False)\n" "_{name}_allKeys.extend(theseKeys)\n" "if len(_{name}_allKeys):\n") buff.writeIndentedLines( code.format( name=self.params['name'], keyStr=(keyListStr or None) ) ) buff.setIndentLevel(1, True) dedentAtEnd += 1 if store == 'first key': # then see if a key has already been pressed code = ("{name}.keys = _{name}_allKeys[0].name # just the first key pressed\n" "{name}.rt = _{name}_allKeys[0].rt\n") buff.writeIndentedLines(code.format(name=self.params['name'])) elif store == 'last key' or store == "nothing": # If store nothing, save last key for correct answer test code = ("{name}.keys = _{name}_allKeys[-1].name # just the last key pressed\n" "{name}.rt = _{name}_allKeys[-1].rt\n") buff.writeIndentedLines(code.format(name=self.params['name'])) elif store == 'all keys': code = ("{name}.keys = [key.name for key in _{name}_allKeys] # storing all keys\n" "{name}.rt = [key.rt for key in _{name}_allKeys]\n") buff.writeIndentedLines(code.format(name=self.params['name'])) if storeCorr: code = ("# was this correct?\n" "if ({name}.keys == str({correctAns})) or ({name}.keys == {correctAns}):\n" " {name}.corr = 1\n" "else:\n" " {name}.corr = 0\n") buff.writeIndentedLines( code.format( name=self.params['name'], correctAns=self.params['correctAns'] ) ) if forceEnd == True: code = ("# a response ends the routine\n" "continueRoutine = False\n") buff.writeIndentedLines(code) buff.setIndentLevel(-(dedentAtEnd), relative=True)
def writeFrameCode(self, buff): """Write the code that will be called every frame """ # some shortcuts store = self.params['store'].val storeCorr = self.params['storeCorrect'].val forceEnd = self.params['forceEndRoutine'].val allowedKeys = self.params['allowedKeys'].val.strip() buff.writeIndented("\n") buff.writeIndented("# *%s* updates\n" % self.params['name']) # writes an if statement to determine whether to draw etc self.writeStartTestCode(buff) buff.writeIndented("%(name)s.status = STARTED\n" % self.params) allowedKeysIsVar = (valid_var_re.match(str(allowedKeys)) and not allowedKeys == 'None') if allowedKeysIsVar: # if it looks like a variable, check that the variable is suitable # to eval at run-time code = ("# AllowedKeys looks like a variable named `{0}`\n" "if not type({0}) in [list, tuple, np.ndarray]:\n") buff.writeIndentedLines(code.format(allowedKeys)) buff.setIndentLevel(1, relative=True) code = ("if type({0}) == int:\n") buff.writeIndentedLines(code.format(allowedKeys)) buff.setIndentLevel(1, relative=True) code = ("{0} = [{0}]\n") buff.writeIndentedLines(code.format(allowedKeys)) buff.setIndentLevel(-1, relative=True) code = ("elif not (isinstance({0}, str) " "or isinstance({0}, unicode)):\n") buff.writeIndentedLines(code.format(allowedKeys)) buff.setIndentLevel(1, relative=True) code = ("logging.error('AllowedKeys variable `{0}` is " "not string- or list-like.')\n" "core.quit()\n") buff.writeIndentedLines(code.format(allowedKeys)) buff.setIndentLevel(-1, relative=True) code = ("elif not ',' in {0}: {0} = eval(({0},))\n" "else: {0} = eval({0})\n") buff.writeIndentedLines(code.format(allowedKeys)) buff.setIndentLevel(-1, relative=True) buff.writeIndented("# joyButtons checking is just starting\n") if store != 'nothing': if self.params['syncScreenRefresh'].val: code = ("win.callOnFlip(%(name)s.clock.reset) # t=0 on next" " screen flip\n") % self.params else: code = "%(name)s.clock.reset() # now t=0\n" % self.params buff.writeIndented(code) # to get out of the if statement buff.setIndentLevel(-1, relative=True) # test for stop (only if there was some setting for duration or stop) if self.params['stopVal'].val not in ['', None, -1, 'None']: # writes an if statement to determine whether to draw etc self.writeStopTestCode(buff) buff.writeIndented("%(name)s.status = FINISHED\n" % self.params) # to get out of the if statement buff.setIndentLevel(-2, relative=True) buff.writeIndented("if %(name)s.status == STARTED:\n" % self.params) buff.setIndentLevel(1, relative=True) # to get out of if statement dedentAtEnd = 1 # keep track of how far to dedent later # do we need a list of keys? (variable case is already handled) if allowedKeys in [None, "none", "None", "", "[]", "()"]: keyList = [] elif not allowedKeysIsVar: try: keyList = eval(allowedKeys) except Exception: raise CodeGenerationException(self.params["name"], "Allowed keys list is invalid.") # this means the user typed "left","right" not ["left","right"] if type(keyList) == tuple: keyList = list(keyList) elif isinstance(keyList, int): # a single string/key keyList = [keyList] code1 = ("{name}.newButtonState = {name}.device.getAllButtons()[:]\n" "{name}.pressedButtons = []\n" "{name}.releasedButtons = []\n" "{name}.newPressedButtons = []\n" "if {name}.newButtonState != {name}.oldButtonState:\n") code2 = ( "{name}.pressedButtons = [i for i in range({name}.numButtons) " "if {name}.newButtonState[i] and not {name}.oldButtonState[i]]\n" "{name}.releasedButtons = [i for i in range({name}.numButtons) " "if not {name}.newButtonState[i] and {name}.oldButtonState[i]]\n" "{name}.oldButtonState = {name}.newButtonState\n" "{name}.newPressedButtons = " "[i for i in {0} if i in {name}.pressedButtons]\n" "[logging.data(\"joystick_{{}}_button: {{}}\".format(" "{name}.device_number,i)) for i in {name}.pressedButtons]\n") if allowedKeysIsVar: buff.writeIndentedLines(code1.format(allowedKeys, **self.params)) buff.setIndentLevel(+1, relative=True) buff.writeIndentedLines(code2.format(allowedKeys, **self.params)) buff.setIndentLevel(-1, relative=True) else: if keyList == []: buff.writeIndentedLines( code1.format(allowedKeys, **self.params)) buff.setIndentLevel(+1, relative=True) buff.writeIndentedLines( code2.format( "range({name}.numButtons)".format(**self.params), **self.params)) buff.setIndentLevel(-1, relative=True) else: buff.writeIndentedLines( code1.format(allowedKeys, **self.params)) buff.setIndentLevel(+1, relative=True) buff.writeIndentedLines( code2.format("{}".format(keyList), **self.params)) buff.setIndentLevel(-1, relative=True) code = ("theseKeys = %(name)s.newPressedButtons\n") buff.writeIndented(code % self.params) if self.exp.settings.params['Enable Escape'].val: code = ('\n# check for quit:\n' 'if "escape" in theseKeys:\n' ' endExpNow = True\n') # how do we store it? if store != 'nothing' or forceEnd: # we are going to store something code = "if len(theseKeys) > 0: # at least one key was pressed\n" buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 if store == 'first key': # then see if a key has already been pressed code = ("if %(name)s.keys == []: # then this was the first " "keypress\n") % self.params buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 code = ( "%(name)s.keys = theseKeys[0] # just the first key pressed\n" "%(name)s.rt = %(name)s.clock.getTime()\n") buff.writeIndentedLines(code % self.params) elif store == 'last key': code = ( "%(name)s.keys = theseKeys[-1] # just the last key pressed\n" "%(name)s.rt = %(name)s.clock.getTime()\n") buff.writeIndentedLines(code % self.params) elif store == 'all keys': code = ("%(name)s.keys.extend(theseKeys) # storing all keys\n" "%(name)s.rt.append(%(name)s.clock.getTime())\n") buff.writeIndentedLines(code % self.params) if storeCorr: code = ("# was this 'correct'?\n" "if (str(%(name)s.keys) == str(%(correctAns)s)):\n") buff.writeIndentedLines(code % self.params) buff.setIndentLevel(+1, relative=True) code = ("%(name)s.corr = 1\n") buff.writeIndentedLines(code % self.params) buff.setIndentLevel(-1, relative=True) code = ("else:\n") buff.writeIndentedLines(code % self.params) buff.setIndentLevel(+1, relative=True) code = ("%(name)s.corr = 0\n") buff.writeIndentedLines(code % self.params) buff.setIndentLevel(-1, relative=True) if forceEnd == True: code = ("# a response ends the routine\n" "continueRoutine = False\n") buff.writeIndentedLines(code % self.params) buff.setIndentLevel(-(dedentAtEnd), relative=True)
def writeFrameCodeJS(self, buff): # some shortcuts store = self.params['store'].val storeCorr = self.params['storeCorrect'].val forceEnd = self.params['forceEndRoutine'].val allowedKeys = self.params['allowedKeys'].val.strip() buff.writeIndented("\n") buff.writeIndented("// *%s* updates\n" % self.params['name']) # writes an if statement to determine whether to draw etc self.writeStartTestCodeJS(buff) buff.writeIndented("%(name)s.status = PsychoJS.Status.STARTED;\n" % self.params) allowedKeysIsVar = (valid_var_re.match(str(allowedKeys)) and not allowedKeys == 'None') if allowedKeysIsVar: # if it looks like a variable, check that the variable is suitable # to eval at run-time raise CodeGenerationException( "Variables for allowKeys aren't supported for JS yet") #code = ("# AllowedKeys looks like a variable named `%s`\n" # "if not '%s' in locals():\n" # " logging.error('AllowedKeys variable `%s` is not defined.')\n" # " core.quit()\n" # "if not type(%s) in [list, tuple, np.ndarray]:\n" # " if not isinstance(%s, basestring):\n" # " logging.error('AllowedKeys variable `%s` is " # "not string- or list-like.')\n" # " core.quit()\n" % # allowedKeys) # #vals = (allowedKeys, allowedKeys, allowedKeys) #code += ( # " elif not ',' in %s: %s = (%s,)\n" % vals + # " else: %s = eval(%s)\n" % (allowedKeys, allowedKeys)) #buff.writeIndentedLines(code) # #keyListStr = "keyList=list(%s)" % allowedKeys # eval at run time buff.writeIndented("// keyboard checking is just starting\n") if store != 'nothing': if self.params['syncScreenRefresh'].val: code = ("psychoJS.window.callOnFlip(%(name)s.clock.reset)" " // t = 0 on screen flip\n") % self.params else: code = "%(name)s.clock.reset(); // now t=0\n" % self.params buff.writeIndented(code) if self.params['discard previous'].val: buff.writeIndented( "psychoJS.eventManager.clearEvents({eventType:'keyboard'});\n") # to get out of the if statement buff.setIndentLevel(-1, relative=True) buff.writeIndented("}\n") # test for stop (only if there was some setting for duration or stop) if self.params['stopVal'].val not in ['', None, -1, 'None']: # writes an if statement to determine whether to draw etc self.writeStopTestCodeJS(buff) buff.writeIndented("%(name)s.status = PsychoJS.Status.STOPPED;\n" " }\n" % self.params) # to get out of the if statement buff.setIndentLevel(-1, relative=True) buff.writeIndented( "if (%(name)s.status === PsychoJS.Status.STARTED) {\n" % self.params) buff.setIndentLevel(1, relative=True) # to get out of if statement dedentAtEnd = 1 # keep track of how far to dedent later # do we need a list of keys? (variable case is already handled) if allowedKeys in [None, "none", "None", "", "[]", "()"]: keyListStr = "" elif not allowedKeysIsVar: try: keyList = eval(allowedKeys) except Exception: raise CodeGenerationException(self.params["name"], "Allowed keys list is invalid.") # this means the user typed "left","right" not ["left","right"] if type(keyList) == tuple: keyList = list(keyList) elif isinstance(keyList, basestring): # a single string/key keyList = [keyList] keyListStr = "{keyList:%s}" % repr(keyList) # check for keypresses buff.writeIndented( "let theseKeys = psychoJS.eventManager.getKeys(%s);\n" % keyListStr) if self.exp.settings.params['Enable Escape'].val: code = ('\n// check for quit:\n' 'if ("escape" in theseKeys) {\n' ' psychoJS.experiment.experimentEnded = true;\n' '}\n') buff.writeIndentedLines(code) # how do we store it? if store != 'nothing' or forceEnd: # we are going to store something code = ("if (theseKeys.length > 0) {" " // at least one key was pressed\n") buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # indent by 1 if store == 'first key': # then see if a key has already been pressed code = ("if (%(name)s.keys.length == 0) {" " // then this was the first keypress\n") % self.params buff.writeIndented(code) buff.setIndentLevel(1, True) dedentAtEnd += 1 # to undo this level of "if" code = ("%(name)s.keys = theseKeys[0];" " // just the first key pressed\n" "%(name)s.rt = %(name)s.clock.getTime();\n") buff.writeIndentedLines(code % self.params) elif store == 'last key': code = ("%(name)s.keys = theseKeys[theseKeys.length-1]" " // just the last key pressed\n" "%(name)s.rt = %(name)s.clock.getTime();\n") buff.writeIndentedLines(code % self.params) elif store == 'all keys': code = ( "%(name)s.keys = %(name)s.keys.concat(theseKeys); // storing all keys\n" "%(name)s.rt = %(name)s.rt.concat(%(name)s.clock.getTime());\n" ) buff.writeIndentedLines(code % self.params) if storeCorr: code = ("// was this 'correct'?\n" "if (%(name)s.keys == %(correctAns)s) {\n" " %(name)s.corr = 1;\n" "} else {\n" " %(name)s.corr = 0;\n" "}\n") buff.writeIndentedLines(code % self.params) if forceEnd == True: code = ("// a response ends the routine\n" "continueRoutine = false;\n") buff.writeIndentedLines(code % self.params) for dedents in range(dedentAtEnd): buff.setIndentLevel(-1, relative=True) buff.writeIndented("}\n")
def writeRoutineStartCode(self, buff): """Write the code that will be called at the start of the routine """ code = ("{name}.oldButtonState = {name}.device.getAllButtons()[:]\n") buff.writeIndentedLines(code.format(**self.params)) allowedButtons = self.params['allowedButtons'].val.strip() allowedButtonsIsVar = (valid_var_re.match(str(allowedButtons)) and not allowedButtons == 'None') if allowedButtonsIsVar: # if it looks like a variable, check that the variable is suitable # to eval at run-time code = ( "# AllowedKeys looks like a variable named `{0}`\n" #"print(\"{0}<{{}}> type:{{}}\".format({0}, type({0})))\n" "if not type({0}) in [list, tuple, np.ndarray]:\n") buff.writeIndentedLines(code.format(allowedButtons)) buff.setIndentLevel(1, relative=True) code = ("if type({0}) == int:\n") buff.writeIndentedLines(code.format(allowedButtons)) buff.setIndentLevel(1, relative=True) code = ("{0} = [{0}]\n") buff.writeIndentedLines(code.format(allowedButtons)) buff.setIndentLevel(-1, relative=True) code = ("elif not (isinstance({0}, str) " "or isinstance({0}, unicode)):\n") buff.writeIndentedLines(code.format(allowedButtons)) buff.setIndentLevel(1, relative=True) code = ("logging.error('AllowedKeys variable `{0}` is " "not string- or list-like.')\n" "core.quit()\n") buff.writeIndentedLines(code.format(allowedButtons)) buff.setIndentLevel(-1, relative=True) code = ("elif not ',' in {0}: {0} = eval(({0},))\n" "else: {0} = eval({0})\n") buff.writeIndentedLines(code.format(allowedButtons)) buff.setIndentLevel(-1, relative=True) # do we need a list of buttons? (variable case is already handled) if allowedButtons in [None, "none", "None", "", "[]", "()"]: buttonList = [] elif not allowedButtonsIsVar: try: buttonList = eval(allowedButtons) except Exception: raise CodeGenerationException( self.params["name"], "Allowed buttons list is invalid.") if type(buttonList) == tuple: buttonList = list(buttonList) elif isinstance(buttonList, int): # a single string/key buttonList = [buttonList] #print("buttonList={}".format(buttonList)) if allowedButtonsIsVar: code = ("{name}.activeButtons={0}\n") buff.writeIndentedLines(code.format(allowedButtons, **self.params)) else: if buttonList == []: code = ( "{name}.activeButtons=[i for i in range({name}.numButtons)]" ) buff.writeIndentedLines( code.format(allowedButtons, **self.params)) else: code = ("{name}.activeButtons={0}") buff.writeIndentedLines(code.format(buttonList, **self.params)) # create some lists to store recorded values positions and events if # we need more than one code = ("# setup some python lists for storing info about the " "%(name)s\n") if self.params['saveJoystickState'].val in ['every frame', 'on click']: code += ( "%(name)s.x = []\n" "%(name)s.y = []\n" "%(name)s.buttonLogs = [[] for i in range(%(name)s.numButtons)]\n" "%(name)s.time = []\n") if self.params['clickable'].val: for clickableObjParam in self._clickableParamsList: code += "%(name)s.clicked_{} = []\n".format(clickableObjParam) code += "gotValidClick = False # until a click is received\n" if self.params['timeRelativeTo'].val.lower() == 'routine': code += "%(name)s.joystickClock.reset()\n" buff.writeIndentedLines(code % self.params)