forked from ak15199/rop
/
art.py
128 lines (96 loc) · 3.54 KB
/
art.py
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import logging
logging.basicConfig(filename='art.log', level=logging.DEBUG)
import opc.utils.prof as prof
import argparse
from exceptions import KeyboardInterrupt
from random import seed
import sys
from time import sleep, time
from traceback import format_exception
import dpyinfo
from importer import ImportPlugins
from opc.matrix import OPCMatrix
DFLT_FLIPTIME_SECS = 30
DFLT_CYCLE_COUNT = None
matrix = None
def exceptionHandler(etype, evalue, etraceback):
global matrix
if matrix is not None:
matrix.terminate()
for line in format_exception(etype, evalue, etraceback):
logging.error('Exception: '+line.rstrip('\n'))
if etype is not KeyboardInterrupt:
print "%s (see log for details)" % evalue
@prof.timereference
def run(arts, args):
global matrix
cycleCount = 0
while args.count is None or cycleCount < args.count:
cycleCount += 1
seed(time())
for name, art in arts.iteritems():
matrix.setFirmwareConfig()
art.start(matrix)
time_sound = 0 # sound as in 'sound as a pound'
time_alarm = 0
start_time = time()
while time()-start_time < args.fliptime:
cycle_time = time()
art.refresh(matrix)
matrix.show()
# interval is between refreshes, but we take time to actually
# render. Account for that here.
debt_time = time()-cycle_time
sleep_time = (art.interval()/1000.0) - debt_time
if sleep_time > 0:
sleep(sleep_time)
time_sound += 1
else:
time_alarm += 1
# timer overrun alarms are an indication that the art has higher
# expectations of the hardware than is reasonable. If you see a
# lot of these, then consider performance tuning, turning up the
# art's interval, or buying better hardware
pc_overrun = 100*time_alarm/(time_sound+time_alarm)
if pc_overrun > 0:
logging.info("%s: %d%% timer overrun alarms" %
(name, pc_overrun))
def _v(attr, default):
try:
return getattr(dpyinfo, attr)
except:
return default
def main():
global matrix
parser = argparse.ArgumentParser()
parser.add_argument("-c", "--count", type=int,
help="run for count cycles through all of the art",
default=DFLT_CYCLE_COUNT)
parser.add_argument("-f", "--fliptime", type=int,
help="run art for FLIPTIME secs before transitioning",
default=DFLT_FLIPTIME_SECS)
parser.add_argument("-p", "--profile",
help="switch on and report profiling detail",
action="store_true")
parser.add_argument("art", help="Optional list of arts",
nargs="*")
args = parser.parse_args()
if args.profile:
prof.on()
matrix = OPCMatrix(
_v("WIDTH", 16), _v("HEIGHT", 16),
_v("ADDRESS", "ansi"), _v("ZIGZAG", False),
_v("FLIPUP", False), _v("FLIPLR", False)
)
arts = ImportPlugins("art", ["template.py"], args.art, matrix)
if len(arts) == 0:
matrix.terminate()
print "Couldn't find any art to execute"
exit(1)
run(arts, args)
matrix.terminate()
if args.profile:
prof.dumptimings()
if __name__ == "__main__":
sys.excepthook = exceptionHandler
main()