Exemple #1
0
class python(object):

    """A snippet of custom Python code.
    Activated by trigger. Can have any number of pull inputs and any number of outputs, which can be push, pull or
    trigger.
    When the Python processor is activated, all inputs are pulled in, and made available to the code as variables of the
    same name.
    If persistent, previous pull output values are likewise added.
    After the code has run, its locals() are inspected for output variables.
    All pull output variables must be set (unless persistent).
    If a push output variable has been set, it is fired towards its targets when the processor has finished.
    If a trigger output variable has been set to True, it is fired towards its targets when the processor has finished
    """

    metaguiparams = {
        "inputs": "NodeIOArray",
        "outputs": "AdvancedNodeIOArray",
        "autocreate": {"inputs": Spyder.NodeIOArray(), "outputs": Spyder.AdvancedNodeIOArray()},
    }

    @classmethod
    def form(cls, f):
        f.inputs.name = "Inputs"
        f.inputs.length = 10
        f.inputs.count_from_one = True
        f.inputs.form = "soft"
        f.inputs.arraymanager = "dynamic"

        f.outputs.name = "Outputs"
        f.outputs.length = 10
        f.outputs.count_from_one = True
        f.outputs.form = "soft"
        f.outputs.arraymanager = "dynamic"

    def __new__(cls, inputs, outputs):
        io_names = set()
        reserved = ("trig", "code", "code_parameter_", "persistent", "persistent_parameter_", "form")
        for inp in inputs:
            if inp.io_name in reserved: raise ValueError("Reserved input name: %s" % inp.io_name)
            if inp.io_name in io_names: raise ValueError("Duplicate input name: %s" % inp.io_name)
            io_names.add(inp.io_name)
        for outp in outputs:
            if outp.io_name in reserved: raise ValueError("Reserved output name: %s" % outp.io_name)
            if outp.io_name in io_names: raise ValueError("Duplicate input/output name: %s" % outp.io_name)
            io_names.add(outp.io_name)
        dic = {
            "trig": antenna("push", "trigger"),
            "code": variable("str"),
            "persistent": variable("bool"),
        }
        dic["code_parameter_"] = parameter(dic["code"], "")
        dic["persistent_parameter_"] = parameter(dic["persistent"], False)
        guiparams = {}
        guiparams["trig"] = {"name": "Trigger"}
        guiparams["_memberorder"] = ["trig"]
        counter = 0
        for inp in inputs:
            name = inp.io_name
            name2 = name + "_"
            typ = inp.type_
            if typ == "custom": typ = inp.customtype
            if typ: typ = stringtupleparser(typ)
            dic[name2] = antenna("pull", typ)
            dic[name] = buffer("pull", typ)
            guiparams[name2] = {"name": name}
            while 1:
                counter += 1
                conname = "con" + str(counter)
                if conname not in io_names: break
            dic[conname] = connect(name2, name)

        for outp in outputs:
            name = outp.io_name
            name2 = name + "_"
            typ = outp.type_
            guiparams[name2] = {"name": name}
            if typ == "custom": typ = outp.customtype
            if typ: typ = stringtupleparser(typ)
            if outp.mode == "trigger":
                dic[name2] = output("push", "trigger")
                dic[name2 + "trig_"] = triggerfunc(dic[name2])
                dic[name] = variable("bool")
            else:
                dic[name2] = output(outp.mode, typ)
                dic[name] = buffer(outp.mode, typ)
                while 1:
                    counter += 1
                    conname = "con" + str(counter)
                    if conname not in io_names: break
                dic[conname] = connect(name, name2)

        dic["guiparams"] = guiparams
        return type("python", (_python_base,), dic)
Exemple #2
0
class advanced_python(object):
    """A snippet of advanced custom Python code.
Activated by trigger. Can have any number of inputs and outputs, which can be push, pull or trigger.
When the Python processor is activated, all push inputs are evaluated, and made available to the code as variables of the same name.
Push inputs that have not been set since the previous invocation are set to None, unless the processor is persistent.
Within the code, a pull input's value must be explicitly requested using v(), where v is the name of the pull input
Within the code, a push output must be explicitly firedusing v(), where v is the name of the push output
After the code has run, its locals() are inspected for pull output variables. All pull output variables must be set (unless persistent).

Parameters:
Persistent: if True, all push inputs and pull outputs have persistent values from one invocation to the next.
Activate by push: if True, every change on a push input triggers the execution of the controller.
Activate by pull: if True, every value request on a pull output (pre-)triggers the execution of the controller
"""
    metaguiparams = {
        "inputs": "AdvancedNodeIOArray",
        "outputs": "AdvancedNodeIOArray",
        "autocreate": {
            "inputs": Spyder.AdvancedNodeIOArray(),
            "outputs": Spyder.AdvancedNodeIOArray()
        },
    }

    @classmethod
    def form(cls, f):
        f.inputs.name = "Inputs"
        f.inputs.length = 10
        f.inputs.count_from_one = True
        f.inputs.form = "soft"
        f.inputs.arraymanager = "dynamic"

        f.outputs.name = "Outputs"
        f.outputs.length = 10
        f.outputs.count_from_one = True
        f.outputs.form = "soft"
        f.outputs.arraymanager = "dynamic"

    def __new__(cls, inputs, outputs):
        io_names = set()
        reserved = ("trig", "code", "code_parameter_", "persistent",
                    "persistent_parameter_", "push_activates",
                    "push_activates_parameter_", "pull_activates",
                    "pull_activates_parameter_", "form")
        for inp in inputs:
            if inp.io_name in reserved:
                raise ValueError("Reserved input name: %s" % inp.io_name)
            if inp.io_name in io_names:
                raise ValueError("Duplicate input name: %s" % inp.io_name)
            io_names.add(inp.io_name)
        for outp in outputs:
            if outp.io_name in reserved:
                raise ValueError("Reserved output name: %s" % outp.io_name)
            if outp.io_name in io_names:
                raise ValueError("Duplicate input/output name: %s" %
                                 outp.io_name)
            io_names.add(outp.io_name)
        dic = {
            "trig": antenna("push", "trigger"),
            "code": variable("str"),
            "persistent": variable("bool"),
            "push_activates": variable("bool"),
            "pull_activates": variable("bool"),
        }
        dic["code_parameter_"] = parameter(dic["code"], "")
        dic["persistent_parameter_"] = parameter(dic["persistent"], False)
        dic["push_activates_parameter_"] = parameter(dic["push_activates"],
                                                     False)
        dic["pull_activates_parameter_"] = parameter(dic["pull_activates"],
                                                     False)
        guiparams = {}
        guiparams["trig"] = {"name": "Trigger"}
        guiparams["_memberorder"] = ["trig"]
        counter = 0
        for inp in inputs:
            name = inp.io_name
            name2 = name + "_"
            typ = inp.type_
            if typ == "custom": typ = inp.customtype
            if typ: typ = stringtupleparser(typ)
            dic[name2] = antenna("pull", typ)
            dic[name] = buffer("pull", typ)
            guiparams[name2] = {"name": name}
            while 1:
                counter += 1
                conname = "con" + str(counter)
                if conname not in io_names: break
            dic[conname] = connect(name2, name)

        for outp in outputs:
            name = outp.io_name
            name2 = name + "_"
            typ = outp.type_
            guiparams[name2] = {"name": name}
            if typ == "custom": typ = outp.customtype
            if typ: typ = stringtupleparser(typ)
            if outp.mode == "trigger":
                dic[name2] = output("push", "trigger")
                dic[name2 + "trig_"] = triggerfunc(dic[name2])
                dic[name] = variable("bool")
            else:
                dic[name2] = output(outp.mode, typ)
                dic[name] = buffer(outp.mode, typ)
                while 1:
                    counter += 1
                    conname = "con" + str(counter)
                    if conname not in io_names: break
                dic[conname] = connect(name, name2)

        dic["guiparams"] = guiparams
        return type("advanced_python", (_advanced_python_base, ), dic)