add support for one shot Idlers
[zanchey/dispense2.git] / sql-edition / servers / Idler.py
1 #!/usr/bin/env python
2
3 import string, time
4 from random import random
5 from MessageKeeper import MessageKeeper
6
7 orderings = None
8
9 class Idler:
10         def __init__(self, v):
11                 self.v = v
12
13         def next(self):
14                 pass
15
16         def reset(self):
17                 pass
18         
19         def finished(self):
20                 return False
21
22 class TrainIdler(Idler):
23         def __init__(self, v):
24                 self.idle_state = 0
25                 self.v = v
26
27         def put_shark(self, s, l):
28                 if self.s[l] == ' ':
29                         self.s[l] = s
30                 elif self.s[l] == 'X':
31                         self.s[l] = '*'
32                 else:
33                         self.s[l] = 'X'
34
35         def next(self):
36                 # does the next stage of a dance
37                 self.s = [' ']*10
38                 shark1 = self.idle_state % 18
39                 if shark1 < 9:
40                         self.put_shark('^', shark1)
41                 else:
42                         self.put_shark('^', 18-shark1)
43
44                 shark2 = ((self.idle_state+4) % 36)/2
45                 if shark2 < 9:
46                         self.put_shark('<', shark2)
47                 else:
48                         self.put_shark('<', 18-shark2)
49
50                 shark3 = ((self.idle_state+7) % 54)/3
51                 if shark3 < 9:
52                         self.put_shark('>', 9-shark3)
53                 else:
54                         self.put_shark('>', 9-(18-shark3))
55
56                 train1 = ((self.idle_state%(18*36)))
57                 train1_start = 122
58                 if train1 > train1_start and train1 < train1_start+(10*2):
59                         for i in range(5):
60                                 ptr = i+train1-train1_start-5
61                                 if ptr >= 0 and ptr < 10: self.s[ptr] = '#'
62
63                 train2 = ((self.idle_state%(18*36)))
64                 train2_start = 400
65                 if train2 > train2_start and train2 < train2_start+(10*2):
66                         for i in range(5):
67                                 ptr = i+train2-train2_start-5
68                                 if ptr >= 0 and ptr < 10: self.s[9-ptr] = '#'
69
70                 train3 = ((self.idle_state%(18*36)))
71                 train3_start = 230
72                 if train3 > train3_start and train3 < train3_start+(10*2):
73                         for i in range(10):
74                                 ptr = i+train3-train3_start-10
75                                 if ptr >= 0 and ptr < 10: self.s[ptr] = '-'
76
77                 self.v.display(string.join(self.s, ''))
78                 self.idle_state += 1
79                 self.idle_state %= 18*36*54
80
81         def reset(self):
82                 self.idle_state = 0
83
84 class OrderMaker:
85         def __init__(self, n=8):
86                 self.n = n
87                 self.a = []
88                 self.u = []
89                 self.s = []
90                 for x in range(0,n):
91                         self.u.append(False)
92                 self.go()
93
94         def go(self):
95                 from copy import deepcopy
96                 if len(self.s) == self.n:
97                         self.a.append(deepcopy(self.s))
98                 else:
99                         for x in range(0,self.n):
100                                 if self.u[x]: continue
101                                 self.s.append(x)
102                                 self.u[x] = True
103                                 self.go()
104                                 self.u[x] = False
105                                 self.s.pop()
106
107         def order(self):
108                 return self.a
109
110 class GrayIdler(Idler):
111         def __init__(self, v, one=None, zero=None, reorder=0):
112                 self.bits = 8
113                 self.size = 1 << self.bits
114                 self.i = 0
115                 self.grayCode = 0
116                 self.v = v
117                 self.one = one
118                 self.zero = zero
119                 self.reorder = reorder
120                 global orderings
121                 if not orderings:
122                         orderings = OrderMaker().order()
123
124         def next(self):
125                 output = self.do_next_state()
126                 # does the next stage of a dance
127                 if self.zero:
128                         output = string.replace(output, "0", self.zero)
129                 if self.one:
130                         output = string.replace(output, "1", self.one)
131                 if self.reorder:
132                         global orderings
133                         newoutput = ""
134                         for i in range(0,8):
135                                 newoutput += output[orderings[self.reorder][i]]
136                         output = newoutput
137                 self.v.display(" %8.8s " % (output))
138                 self.i = (self.i + 1) % self.size
139
140         def do_next_state(self):
141                 self.grayCode = self.i ^ (self.i >> 1)
142                 output = self.dec2bin(self.grayCode)
143
144                 return "0"*(self.bits-len(output))+output
145
146
147         def dec2bin(self,num):
148             """Convert long/integer number to binary string.
149
150             E.g. dec2bin(12) ==> '1100'.
151             
152             from http://starship.python.net/~gherman/playground/decbingray/decbingray.py"""
153
154             assert num >= 0, "Decimal number must be >= 0!"
155
156             # Gracefully handle degenerate case.
157             # (Not really needed, but anyway.)    
158             if num == 0:
159                 return '0'
160
161             # Find highest value bit.
162             val, j = 1L, 1L
163             while val < num:
164                 val, j = val*2L, j+1L
165
166             # Convert.
167             bin = '' 
168             i = j - 1
169             while i + 1L:
170                 k = pow(2L, i)
171                 if num >= k:
172                     bin = bin + '1'
173                     num = num - k
174                 else:
175                     if len(bin) > 0:
176                         bin = bin + '0'
177                 i = i - 1L
178
179             return bin
180
181         def reset(self):
182                 self.i = 0
183                 self.grayCode = 0
184                 if self.reorder:
185                         self.reorder = int(random()*40319)+1
186
187
188 class StringIdler(Idler):
189         def __init__(self, v, text="Hello Cruel World!  "):
190                 self.v = v
191                 self.mk = MessageKeeper(v)
192                 self.text = self.clean_text(text)
193                 
194                 msg = [("",False, None),(self.text, True, 0.8)]
195                 self.mk.set_messages(msg)
196
197         def clean_text(self, text):
198                 # nothing like a bit of good clean text :)
199                 valid = string.digits \
200                         + string.letters \
201                         + string.punctuation \
202                         + " "
203                 # uppercase it
204                 text = string.upper(text)
205                 clean = ""
206                 for char in text:
207                         if char in valid:
208                                 clean = clean + char
209                         else:
210                                 clean = clean + " "
211                 return clean
212
213         def next(self):
214                 self.mk.update_display()
215
216 class ClockIdler(Idler):
217         def __init__(self, v):
218                 self.v = v
219                 self.last = None
220
221         def next(self):
222                 output = time.strftime("%H:%M:%S")
223                 if output != self.last:
224                         self.v.display(" %8.8s " % (output))
225                         self.last = output

UCC git Repository :: git.ucc.asn.au