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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
from pixelcore.Pixel import *
from pixelcore.PixelStrip import *
from operationscore.PixelEvent import *
from operationscore.PixelMapper import *
import util.Search as Search
import util.ComponentRegistry as compReg
import util.Strings as Strings
import util.TimeOps as timeops
import itertools
import sys
import pdb
from logger import main_log
#Class representing a collection of Pixels grouped into PixelStrips. Needs a
#PixelMapper, currently set via setMapper by may be migrated into the argDict.
class Screen:
def __init__(self):
self.responseQueue = []
self.pixelStrips = []
self.xSortedPixels = []
self.xPixelLocs = []
sizeValid = False
def addStrip(self, lS):
self.pixelStrips.append(lS)
self.sizeValid = False #keep track of whether or not our screen size has
#been invalidated by adding more pixels
self.computeXSortedPixels()
#Returns (pixelIndex, pixel). Does a binary search.
def pixelsInRange(self, minX, maxX):
minIndex = Search.find_ge(self.xPixelLocs, minX)
maxIndex = Search.find_le(self.xPixelLocs, maxX)+1
return self.xSortedPixels[minIndex:maxIndex]
def computeXSortedPixels(self):
for pixel in self:
self.xSortedPixels.append((pixel.location[0], pixel))
self.xSortedPixels.sort()
self.xPixelLocs = [p[0] for p in self.xSortedPixels]
#For debug only
def allOn(self):
[lS.allOn(-1) for lS in self.pixelStrips]
def __iter__(self): #the iterator of all our pixel strips chained togther
return itertools.chain(*[strip.__iter__() for strip in \
self.pixelStrips]) #the * operator breaks the list into args
#increment time -- This processes all queued responses. Responses generated
#during this period are added to the queue that will be processed on the next
#time step.
#SUBVERTING DESIGN FOR EFFICIENCY 1/24/11, RCOH -- It would be cleaner to store the time on the responses
#themselves, however, it is faster to just pass it in.
def timeStep(self, currentTime=None):
if currentTime == None:
currentTime = timeops.time()
tempQueue = list(self.responseQueue)
self.responseQueue = []
for response in tempQueue:
self.processResponse(response, currentTime)
#public
def respond(self, responseInfo):
self.responseQueue.append(responseInfo)
def getSize(self):
if self.sizeValid:
return self.size
(minX, minY, maxX, maxY) = (sys.maxint,sys.maxint,-sys.maxint,-sys.maxint)
for light in self:
(x,y) = light.location
minX = min(x, minX)
maxX = max(x, maxX)
minY = min(y, minY)
maxY = max(y, maxY)
self.size = (0,0, maxX, maxY)
self.sizeValid = True
return (0, 0, maxX+100, maxY+100) #TODO: cleaner
#private
def processResponse(self, responseInfo, currentTime=None): #we need to make a new dict for
#each to prevent interference
#[strip.respond(dict(responseInfo)) for strip in self.pixelStrips]
if currentTime == None:
currentTime = timeops.time()
print 'cachetime fail'
if type(responseInfo) != type(dict()):
pass
if 'Mapper' in responseInfo:
mapper = compReg.getComponent(responseInfo['Mapper'])
else:
mapper = compReg.getComponent(Strings.DEFAULT_MAPPER)
#if type(mapper) != type(PixelMapper):
# raise Exception('No default mapper specified.')
pixelWeightList = mapper.mapEvent(responseInfo['Location'], self)
main_log.debug('Screen processing response. ' + str(len(pixelWeightList)) + ' events\
generated')
PixelEvent.addPixelEventIfMissing(responseInfo)
for (pixel, weight) in pixelWeightList:
pixel.processInput(responseInfo['PixelEvent'], 0,weight, currentTime) #TODO: z-index
|