aboutsummaryrefslogtreecommitdiff
path: root/LightInstallation.py
diff options
context:
space:
mode:
authorGravatar Russell Cohen <rcoh@mit.edu>2010-11-25 21:44:00 -0500
committerGravatar Russell Cohen <rcoh@mit.edu>2010-11-25 21:44:00 -0500
commit5783d6336f014c05e0e46d7bc35533e70b280582 (patch)
treeb4e0b0b2787b8fe464baadbd375ad6dc6c1dbf76 /LightInstallation.py
parentb042647b68abdc82490ca6e059993b8eba28904c (diff)
Added BehaviorChain to support chains of behaviors. Added FollowMouse
parameter to PygameInput to support following of mice. Added component registry to Util which allows any component to access any other component. Some changes to the structure of LightInstallation.
Diffstat (limited to 'LightInstallation.py')
-rw-r--r--LightInstallation.py77
1 files changed, 55 insertions, 22 deletions
diff --git a/LightInstallation.py b/LightInstallation.py
index 3fcdcd5..2891e08 100644
--- a/LightInstallation.py
+++ b/LightInstallation.py
@@ -9,19 +9,33 @@ class LightInstallation:
def __init__(self, configFileName):
self.inputs = {} #dict of inputs and their bound behaviors, keyed by InputId
self.behaviors = {}
+ self.behaviorOutputs = {} #key: [list of output destinations]
+ self.behaviorInputs = {}
+ self.componentDict = {}
+ self.inputBehaviorRegistry = {} #inputid -> behaviors listening to that
+ #input
+ #give Util a pointer to our componentRegistry so that everyone can use
+ #it
+ Util.setComponentDict(self.componentDict)
self.screen = Screen()
config = Util.loadConfigFile(configFileName)
+ #read configs from xml
rendererConfig = config.find('RendererConfiguration')
layoutConfig = config.find('LayoutConfiguration')
inputConfig = config.find('InputConfiguration')
behaviorConfig = config.find('BehaviorConfiguration')
- self.initializeLights(layoutConfig)
+ #inits
+ self.initializeScreen(layoutConfig)
self.initializeRenderers(rendererConfig)
self.initializeInputs(inputConfig)
self.initializeBehaviors(behaviorConfig)
-
+ #registration in dict
+ self.registerComponents(self.renderers)
+ self.registerComponents(self.inputs)
+ self.registerComponents(self.behaviors)
+ #Done initializing. Lets start this thing!
self.mainLoop()
- def initializeLights(self, layoutConfig):
+ def initializeScreen(self, layoutConfig):
layoutEngines = self.initializeComponent(layoutConfig)
[self.addPixelStrip(l) for l in layoutEngines]
def addPixelStrip(self, layoutEngine):
@@ -29,12 +43,20 @@ class LightInstallation:
self.screen.addStrip(pixelStrip)
def initializeInputs(self, inputConfig):
inputs = self.initializeComponent(inputConfig)
+ self.inputs = inputs
for inputClass in inputs:
inputClass.start()
- self.inputs[inputClass.argDict['InputId']] = (inputClass, [])
+ self.inputBehaviorRegistry[inputClass['Id']] = []
+ #empty list is list of bound behaviors
def initializeRenderers(self, rendererConfig):
self.renderers = self.initializeComponent(rendererConfig)
- print self.renderers
+ def registerComponents(self, components):
+ for component in components:
+ try:
+ cid = component['Id']
+ except:
+ raise Exception('Components must have Ids!')
+ self.componentDict[cid] = component
def initializeComponent(self, config):
components = []
if config != None:
@@ -42,7 +64,8 @@ class LightInstallation:
[module,className] = configItem.find('Class').text.split('.')
exec('from ' + module+'.'+className + ' import *')
args = Util.generateArgDict(configItem.find('Args'))
- args['parentScope'] = self
+ args['parentScope'] = self #TODO: we shouldn't give away scope
+ #like this, find another way.
components.append(eval(className+'(args)')) #TODO: doesn't error
#right
return components
@@ -52,32 +75,42 @@ class LightInstallation:
#self.screen.allOn()
while 1:
time.sleep(.1)
- responses = []
- for behaviorId in self.behaviors:
- [responses.append(b) for b in \
- self.behaviors[behaviorId].timeStep()] #processes all queued inputs
+ responses = self.evaluateBehaviors() #inputs are all queued when they
+ #happen, so we only need to run the behaviors
[self.screen.respond(response) for response in responses if
response != []]
self.screen.timeStep()
- if responses != []:
- print responses
[r.render(self.screen) for r in self.renderers]
+ #evaluates all the behaviors (including inter-dependencies) and returns a
+ #list of responses to go to the screen.
+ def evaluateBehaviors(self):
+ responses = {}
+ responses['Screen'] = [] #responses to the screen
+ for behavior in self.behaviors:
+ responses[behavior['Id']] = behavior.timeStep()
+ if behavior['RenderToScreen'] == True: #TODO: this uses extra space,
+ #we can use less in the future if needbe.
+ responses['Screen'] += responses[behavior['Id']]
+ return responses['Screen']
+
def initializeBehaviors(self, behaviorConfig):
- behaviors = self.initializeComponent(behaviorConfig)
- for behavior in behaviors:
- print behavior.argDict
+ self.behaviors = self.initializeComponent(behaviorConfig)
+ for behavior in self.behaviors:
self.addBehavior(behavior)
- print self.inputs
- print self.behaviors
+ #TODO: we probably don't need this anymore :(
+ def topologicalBehaviorSort(self):
+ return Util.topologicalSort(self.behaviorDependencies)
+ #Does work needed to add a behavior: currently -- maps behavior inputs into
+ #the input behavior registry.
def addBehavior(self, behavior):
- self.behaviors[behavior.argDict['behaviorId']] = behavior
for inputId in behavior.argDict['Inputs']:
- self.inputs[inputId][1].append(behavior.argDict['behaviorId'])
+ if inputId in self.inputBehaviorRegistry: #it could be a behavior
+ self.inputBehaviorRegistry[inputId].append(behavior['Id'])
def processResponse(self,inputDict, responseDict):
#pdb.set_trace()
- inputId = inputDict['InputId']
- boundBehaviors = self.inputs[inputId][1]
- [self.behaviors[b].addInput(responseDict) for b in boundBehaviors]
+ inputId = inputDict['Id']
+ boundBehaviorIds = self.inputBehaviorRegistry[inputId]
+ [self.componentDict[b].addInput(responseDict) for b in boundBehaviorIds]
def main(argv):
print argv