~sjdv1982/hivesystem/trunk

« back to all changes in this revision

Viewing changes to sparta/processors/python.py

  • Committer: Sjoerd de Vries
  • Date: 2014-06-09 10:19:38 UTC
  • mfrom: (182.1.43 hive-view)
  • Revision ID: sjdv1982@gmail.com-20140609101938-7ji5g0buo09r0se6
merged with hive-view branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import libcontext, bee
 
2
from bee.segments import *
 
3
import spyder, Spyder
 
4
from ..models import nodeio
 
5
from bee.types import stringtupleparser
 
6
 
 
7
class _python_base(bee.worker):
 
8
    @classmethod
 
9
    def form(cls, f):
 
10
        f.code.name = "Python code"
 
11
        f.code.type = "pythoncode"
 
12
        f.persistent.name = "Persistent"
 
13
        f.persistent.tooltip = "Output values persist between invocations"
 
14
        f.memberorder = "persistent", "code"
 
15
    def place(self):
 
16
        raise NotImplementedError("sparta.processors.python has not been implemented yet")
 
17
    
 
18
class python(object):
 
19
    """A snippet of custom Python code.
 
20
Activated by trigger. Can have any number of pull inputs and any number of outputs, which can be push, pull or trigger.
 
21
When the Python processor is activated, all inputs are pulled in, and made available to the code as variables of the same name.
 
22
If persistent, previous pull output values are likewise added.
 
23
After the code has run, its locals() are inspected for output variables.
 
24
All pull output variables must be set (unless persistent).
 
25
If a push output variable has been set, it is fired towards its targets when the processor has finished.
 
26
If a trigger output variable has been set to True, it is fired towards its targets when the processor has finished"""
 
27
    metaguiparams = {
 
28
      "inputs" : "NodeIOArray",
 
29
      "outputs" : "AdvancedNodeIOArray",
 
30
      "autocreate" : {"inputs": Spyder.NodeIOArray(), "outputs" : Spyder.AdvancedNodeIOArray()},
 
31
    }
 
32
    @classmethod
 
33
    def form(cls, f):
 
34
        f.inputs.name = "Inputs"
 
35
        f.inputs.length = 10
 
36
        f.inputs.count_from_one = True
 
37
        f.inputs.form = "soft"
 
38
        f.inputs.arraymanager = "dynamic"
 
39
      
 
40
        f.outputs.name = "Outputs"
 
41
        f.outputs.length = 10
 
42
        f.outputs.count_from_one = True
 
43
        f.outputs.form = "soft"
 
44
        f.outputs.arraymanager = "dynamic"                
 
45
    
 
46
    def __new__(cls, inputs, outputs):
 
47
        ionames = set()
 
48
        reserved = ("trig", "code", "code_parameter_", "persistent", "persistent_parameter_", "form")
 
49
        for inp in inputs:
 
50
            if inp.ioname in reserved: raise ValueError("Reserved input name: %s" % inp.ioname)
 
51
            if inp.ioname in ionames: raise ValueError("Duplicate input name: %s" % inp.ioname)
 
52
            ionames.add(inp.ioname)
 
53
        for outp in outputs:
 
54
            if outp.ioname in reserved: raise ValueError("Reserved output name: %s" % outp.ioname)
 
55
            if outp.ioname in ionames: raise ValueError("Duplicate input/output name: %s" % outp.ioname)
 
56
            ionames.add(outp.ioname)
 
57
        dic = {
 
58
            "trig": antenna("push", "trigger"),
 
59
            "code": variable("str"),
 
60
            "persistent": variable("bool"),
 
61
          }
 
62
        dic["code_parameter_"] = parameter(dic["code"], "")
 
63
        dic["persistent_parameter_"] = parameter(dic["persistent"], False)  
 
64
        guiparams = {}
 
65
        guiparams["trig"] = {"name" : "Trigger"}
 
66
        guiparams["_memberorder"] = ["trig"]
 
67
        counter = 0
 
68
        for inp in inputs:
 
69
            name = inp.ioname 
 
70
            name2 = name + "_"
 
71
            typ = inp.type_            
 
72
            if typ == "custom": typ = inp.customtype
 
73
            if typ: typ = stringtupleparser(typ)
 
74
            dic[name2] = antenna("pull", typ)
 
75
            dic[name] = buffer("pull", typ)            
 
76
            guiparams[name2] = {"name": name}
 
77
            while 1:
 
78
                counter += 1            
 
79
                conname = "con" + str(counter)
 
80
                if conname not in ionames: break
 
81
            dic[conname] = connect(name2, name)
 
82
 
 
83
        for outp in outputs:
 
84
            name = outp.ioname 
 
85
            name2 = name + "_"
 
86
            typ = outp.type_
 
87
            guiparams[name2] = {"name": name}
 
88
            if typ == "custom": typ = outp.customtype   
 
89
            if typ: typ = stringtupleparser(typ)
 
90
            if outp.mode == "trigger": 
 
91
                dic[name2] = output("push", "trigger")
 
92
                dic[name2+"trig_"] = triggerfunc(dic[name2])
 
93
                dic[name] = variable("bool")
 
94
            else:
 
95
                dic[name2] = output(outp.mode, typ)
 
96
                dic[name] = buffer(outp.mode, typ)              
 
97
                while 1:
 
98
                    counter += 1            
 
99
                    conname = "con" + str(counter)
 
100
                    if conname not in ionames: break
 
101
                dic[conname] = connect(name, name2)
 
102
        
 
103
        dic["guiparams"] = guiparams        
 
104
        return type("python", (_python_base,), dic)