aboutsummaryrefslogtreecommitdiff
path: root/operationscore/Behavior.py
blob: d48c1d520e06395611c3b7412ab60353bfb6ef65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#Abstract class for a behavior.  On every time step, the behavior is passed the
#inputs from all sensors it is bound to as well as any recursive inputs that it
#spawned during the last time step.  Inheriting classes MUST define
#processResponse.  processResponse should return a list of dictionaries which
#define the properties of the light response, (outputs, recursions).  They must give a location and
#color.  They may define a PixelEvent to more closely control the outgoing
#data, however, this is normally handled by routing the event to a behavior
#specifically designed to do this (like DecayBehavior). 

import pdb
from operationscore.SmootCoreObject import *
#timeStep is called on every iteration of the LightInstallation
#addInput is called on each individual input received, and the inputs queue
class Behavior(SmootCoreObject):
    def init(self):
        self.validateArgs('Behavior.params')
        if type(self['Inputs']) != type([]):
            self['Inputs'] = [self['Inputs']]
        self.recursiveResponseQueue = []
        self.sensorResponseQueue = []
        self.outGoingQueue = []
        self.behaviorInit()
    def behaviorInit(self):
        pass
    def processResponse(self, sensorInputs, recursiveInputs):
        pass
    def addInput(self, sensorInput):
        self.sensorResponseQueue.append(sensorInput)
    #used for behavior chaining
    def immediateProcessInput(self, sensorInputs, recursiveInputs=[]): 
        try:
            (output,recursions) = self.processResponse(sensorInputs, \
                    recursiveInputs)
            if type(output) != type([]):
                output = [output]
            return self.addMapperToResponse((output, recursions)) #TODO: use a decorator for this?
        except:  #deal with behaviors that don't return a tuple.
            responses = self.processResponse(sensorInputs, recursiveInputs)
            return (self.processResponse(sensorInputs, recursiveInputs),[])
    def addInputs(self, sensorInputs):
        if type(sensorInputs) == type([]):
            [self.addInput(sensorInput) for sensorInput in sensorInputs]
        else:
            self.addInput(sensorInputs)
    #private
    def addMapperToResponse(self, responses):
        if self['Mapper'] != None:
            if type(responses) == type(tuple):
                (out, recurs) = responses
                return (self.addMapperToResponse(out), self.addMapperToResponse(recurs))
            if type(responses) == type([]):
                    for r in responses:
                        r['Mapper'] = self['Mapper']
                    return responses
        return responses
    def timeStep(self): #TODO: type checking.  clean this up
        responses = self.processResponse(self.sensorResponseQueue, \
                self.recursiveResponseQueue)
        if type(responses) == type(tuple()) and len(responses) == 2:
            (outputs, recursions) = responses
        else:
            outputs = responses
            recursions = []
        self.sensorResponseQueue = []
        self.recursiveResponseQueue = recursions 
        if type(outputs) != type([]):
            outputs = [outputs]
        try:
            return self.addMapperToResponse(outputs) #TODO: WTF is up with this?
        except:
            pass
        return self.addMapperToResponse(outputs)