A Greeting Idler
[zanchey/dispense2.git] / sql-edition / servers / Idler.py
1 #!/usr/bin/env python
2
3 import string, time, popen2, os
4 from random import random
5 from MessageKeeper import MessageKeeper
6
7 orderings = None
8
9 IDLER_TEXT_SPEED=1.8
10
11 class Idler:
12         def __init__(self, v):
13                 self.v = v
14
15         def next(self):
16                 """Displays next stage of the idler. Returns time to the next step"""
17                 return 1
18
19         def reset(self):
20                 """Resets the idler to a known intial state"""
21                 pass
22         
23         def finished(self):
24                 """Returns True if the idler is considered finished"""
25                 return False
26
27         def affinity(self):
28                 """How much we want this idler to be the next one chosen"""
29                 return 1
30
31 class GreetingIdler(Idler):
32         def __init__(self, v, secs_to_greeting = None):
33                 self.v = v
34                 self.secs_to_greeting = secs_to_greeting
35
36         def next(self):
37                 if not self.secs_to_greeting is None:
38                         x = self.secs_to_greeting
39                         self.secs_to_greeting = None
40                         return x
41
42                 self.v.display('UCC SNACKS')
43                 return 2
44
45         def reset(self):
46                 pass
47
48         def finished(self):
49                 return self.secs_to_greeting == None
50
51         def affinity(self):
52                 return 0
53
54 class TrainIdler(Idler):
55         def __init__(self, v):
56                 self.idle_state = 0
57                 self.v = v
58
59         def put_shark(self, s, l):
60                 if self.s[l] == ' ':
61                         self.s[l] = s
62                 elif self.s[l] == 'X':
63                         self.s[l] = '*'
64                 else:
65                         self.s[l] = 'X'
66
67         def next(self):
68                 # does the next stage of a dance
69                 self.s = [' ']*10
70                 shark1 = self.idle_state % 18
71                 if shark1 < 9:
72                         self.put_shark('^', shark1)
73                 else:
74                         self.put_shark('^', 18-shark1)
75
76                 shark2 = ((self.idle_state+4) % 36)/2
77                 if shark2 < 9:
78                         self.put_shark('<', shark2)
79                 else:
80                         self.put_shark('<', 18-shark2)
81
82                 shark3 = ((self.idle_state+7) % 54)/3
83                 if shark3 < 9:
84                         self.put_shark('>', 9-shark3)
85                 else:
86                         self.put_shark('>', 9-(18-shark3))
87
88                 train1 = ((self.idle_state%(18*36)))
89                 train1_start = 122
90                 if train1 > train1_start and train1 < train1_start+(10*2):
91                         for i in range(5):
92                                 ptr = i+train1-train1_start-5
93                                 if ptr >= 0 and ptr < 10: self.s[ptr] = '#'
94
95                 train2 = ((self.idle_state%(18*36)))
96                 train2_start = 400
97                 if train2 > train2_start and train2 < train2_start+(10*2):
98                         for i in range(5):
99                                 ptr = i+train2-train2_start-5
100                                 if ptr >= 0 and ptr < 10: self.s[9-ptr] = '#'
101
102                 train3 = ((self.idle_state%(18*36)))
103                 train3_start = 230
104                 if train3 > train3_start and train3 < train3_start+(10*2):
105                         for i in range(10):
106                                 ptr = i+train3-train3_start-10
107                                 if ptr >= 0 and ptr < 10: self.s[ptr] = '-'
108
109                 self.v.display(string.join(self.s, ''))
110                 self.idle_state += 1
111                 self.idle_state %= 18*36*54
112
113         def reset(self):
114                 self.idle_state = 0
115
116 class OrderMaker:
117         def __init__(self, n=8):
118                 self.n = n
119                 self.make_factorials(n)
120         
121         def make_factorials(self, n):
122                 self.factorial = []
123                 a = 1
124                 for i in range(1,n+1):
125                         self.factorial.append(a)
126                         a *= i
127
128         def order(self, index):
129                 used = []
130                 for i in range(0,self.n):
131                         used.append(i)
132                 i = self.n-1
133                 j = 0
134                 res = []
135                 while i >= 0:
136                         a = index/self.factorial[i]
137                         index %= self.factorial[i]
138                         res.append(a+1)
139                         i -= 1
140                         j += 1
141                 for i in range(0,self.n):
142                         tmp = used[res[i]-1]
143                         for j in range(res[i],self.n):
144                                 used[j-1] = used[j]
145                         res[i] = tmp
146                 return res
147
148         def __getitem__(self, i):
149                 return self.order(i)
150
151 class GrayIdler(Idler):
152         def __init__(self, v, one=None, zero=None, reorder=0):
153                 self.bits = 8
154                 self.size = 1 << self.bits
155                 self.i = 0
156                 self.grayCode = 0
157                 self.v = v
158                 self.one = one
159                 self.zero = zero
160                 self.reorder = reorder
161                 global orderings
162                 if not orderings:
163                         orderings = OrderMaker()
164
165         def next(self):
166                 output = self.do_next_state()
167                 # does the next stage of a dance
168                 if self.zero:
169                         output = string.replace(output, "0", self.zero)
170                 if self.one:
171                         output = string.replace(output, "1", self.one)
172                 if self.reorder:
173                         global orderings
174                         newoutput = ""
175                         for i in range(0,8):
176                                 newoutput += output[orderings[self.reorder][i]]
177                         output = newoutput
178                 self.v.display(" %8.8s " % (output))
179                 self.i = (self.i + 1) % self.size
180
181         def do_next_state(self):
182                 self.grayCode = self.i ^ (self.i >> 1)
183                 output = self.dec2bin(self.grayCode)
184
185                 return "0"*(self.bits-len(output))+output
186
187
188         def dec2bin(self,num):
189             """Convert long/integer number to binary string.
190
191             E.g. dec2bin(12) ==> '1100'.
192             
193             from http://starship.python.net/~gherman/playground/decbingray/decbingray.py"""
194
195             assert num >= 0, "Decimal number must be >= 0!"
196
197             # Gracefully handle degenerate case.
198             # (Not really needed, but anyway.)    
199             if num == 0:
200                 return '0'
201
202             # Find highest value bit.
203             val, j = 1L, 1L
204             while val < num:
205                 val, j = val*2L, j+1L
206
207             # Convert.
208             bin = '' 
209             i = j - 1
210             while i + 1L:
211                 k = pow(2L, i)
212                 if num >= k:
213                     bin = bin + '1'
214                     num = num - k
215                 else:
216                     if len(bin) > 0:
217                         bin = bin + '0'
218                 i = i - 1L
219
220             return bin
221
222         def reset(self):
223                 self.i = 0
224                 self.grayCode = 0
225                 if self.reorder:
226                         self.reorder = int(random()*40319)+1
227
228
229 class StringIdler(Idler):
230         def __init__(self, v, text="Hello Cruel World!  ",repeat=True):
231                 self.v = v
232                 self.mk = MessageKeeper(v)
233                 self.text = self.clean_text(text) + "          "
234                 
235                 msg = [("",False, None),(self.text, repeat, IDLER_TEXT_SPEED)]
236                 self.mk.set_messages(msg)
237
238         def clean_text(self, text):
239                 # nothing like a bit of good clean text :)
240                 valid = string.digits \
241                         + string.letters \
242                         + string.punctuation \
243                         + " "
244                 # uppercase it
245                 text = string.upper(text)
246                 clean = ""
247                 for char in text:
248                         if char in valid:
249                                 clean = clean + char
250                         else:
251                                 clean = clean + " "
252                 return clean
253
254         def next(self):
255                 self.mk.update_display()
256
257         def finished(self):     
258                 return self.mk.done()
259
260 class ClockIdler(Idler):
261         def __init__(self, v):
262                 self.v = v
263                 self.last = None
264
265         def next(self):
266                 colonchar = ':'
267                 if int(time.time()*2) & 1: colonchar = ' '
268                 output = time.strftime("%%H%c%%M%c%%S"%(colonchar,colonchar))
269                 if output != self.last:
270                         self.v.display(" %8.8s " % (output))
271                         self.last = output
272
273         def affinity(self):
274                 return 3 
275
276 class FortuneIdler(StringIdler):
277         def __init__(self, v):
278                 fortune = "/usr/games/fortune"
279                 text = "I broke my wookie...."
280                 if os.access(fortune,os.F_OK|os.X_OK):
281                         (stdout, stdin) = popen2.popen2(fortune)
282                         text = string.join(stdout.readlines())
283                         stdout.close()
284                         stdin.close()
285                 StringIdler.__init__(self, v, text,repeat=False)
286
287         def affinity(self):
288                 return 20
289
290 class PipeIdler(StringIdler):
291         def __init__(self, v, command, args):
292                 text = "I ate my cookie...."
293                 if os.access(command,os.F_OK|os.X_OK):
294                         (stdout, stdin) = popen2.popen2(command+' '+args)
295                         text = string.join(stdout.readlines())
296                         stdout.close()
297                         stdin.close()
298                 StringIdler.__init__(self, v, text,repeat=False)
299
300         def affinity(self):
301                 return 20
302
303 class FileIdler(StringIdler):
304         def __init__(self, v, thefile=None, repeat=False):
305                 text = "I broke my wookie...."
306
307                 if file and os.access(thefile,os.F_OK|os.R_OK):
308                         f = file(thefile,'r')
309                         text = string.join(f.readlines())
310                         f.close()
311                 StringIdler.__init__(self, v, text,repeat=repeat)
312
313         def affinity(self):
314                 return 8 

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