Exemplo n.º 1
0
    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")
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    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)
Exemplo n.º 8
0
    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")
Exemplo n.º 9
0
    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)
Exemplo n.º 10
0
    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)
Exemplo n.º 11
0
    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")
Exemplo n.º 12
0
    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)