1
2
3
4
5
6
7
8
9
10
11
12 """
13 Allows control of parameter values over the network.
14
15 Don't use for realtime control unless you think your network is that
16 fast and reliable. Also, this code has not been optimized for speed,
17 and I think it is unwise to attempt to change the value of controllers
18 in realtime. In other words, do not design an experiment where, on a
19 remote computer, you have determined that a certain amount of time has
20 passed, and you require a certain new controller value NOW. In this
21 case, it would be better to use parameter=eval_str() with an if
22 statement involving time.
23
24 To control parameters over a network, start a server with an instance
25 of TCPServer. The server spawns an instance of SocketListenController
26 for each connected socket. (Most commonly you will only want
27 connection over a single socket.) The instance of
28 SocketListenController handles all communication for that connection
29 and serves as a container and (meta) controller for instances of
30 TCPController.
31
32 This module contains ABSOLUTELY NO SECURITY FEATURES, and could easily
33 allow arbitrary execution of code on your computer. For this reason,
34 if you use this module, I recommend operating behind a firewall. This
35 could be an inexpensive "routing switch" used for cable modems, which
36 would provide the added benefit that your local network would be
37 isolated. This would elimate all traffic not to or from computers on
38 the switch and therefore reduce/eliminate packet collisions, decrease
39 latency, and providing a network performance and reliability. To
40 address security concerns, you could also write code that implements
41 IP address checking or other security features.
42
43 """
44
45 import VisionEgg
46 import VisionEgg.Core
47 import VisionEgg.FlowControl
48 import VisionEgg.ParameterTypes as ve_types
49 import socket, select, re, string, types
50 import numpy.oldnumeric as Numeric, math
51
52 try:
53 import Tkinter
54 except:
55 pass
56
57 import logging
58
59 __version__ = VisionEgg.release_name
60 __cvs__ = '$Revision$'.split()[1]
61 __date__ = ' '.join('$Date$'.split()[1:3])
62 __author__ = 'Andrew Straw <astraw@users.sourceforge.net>'
63
65 """TCP server creates SocketListenController upon connection.
66
67 This class is analagous to VisionEgg.PyroHelpers.PyroServer.
68
69 """
70 - def __init__(self,
71 hostname="",
72 port=7834,
73 single_socket_but_reconnect_ok=0,
74 dialog_ok=1,
75 confirm_address_with_gui=1):
76 """Bind to hostname and port, but don't listen yet.
77
78 """
79 server_address = (socket.getfqdn(hostname),port)
80 self.dialog_ok = dialog_ok
81 self.single_socket_but_reconnect_ok = single_socket_but_reconnect_ok
82 self.buffer = ""
83 self.server_socket=None
84 if not globals().has_key("Tkinter") or (VisionEgg.config.VISIONEGG_TKINTER_OK==0):
85 self.dialog_ok = 0
86
87 class GetServerAddressWindow(Tkinter.Frame):
88 def __init__(self,server_address,**kw):
89 try:
90 Tkinter.Frame.__init__(self,**kw)
91 except AttributeError,x:
92 tk=Tkinter.Tk()
93 Tkinter.Frame.__init__(self,tk,**kw)
94 self.winfo_toplevel().title("Vision Egg: TCP Server get address")
95 self.server_address = server_address
96 hostname,port = self.server_address
97 self.clicked_ok = 0
98 self.hostname = Tkinter.StringVar()
99 self.hostname.set(hostname)
100 self.port = Tkinter.StringVar()
101 self.port.set(port)
102 row = 0
103 Tkinter.Label(self,
104 text="Please enter the hostname and port you would like to listen for connections on.",
105 ).grid(row=row,columnspan=2)
106 row += 1
107 Tkinter.Label(self,
108 text="Hostname (blank means localhost):",
109 ).grid(row=row,column=0,sticky=Tkinter.E)
110 Tkinter.Entry(self,textvariable=self.hostname).grid(row=row,column=1,sticky=Tkinter.W+Tkinter.E,padx=10)
111 row += 1
112 Tkinter.Label(self,
113 text="Port:",
114 ).grid(row=row,column=0,sticky=Tkinter.E)
115 Tkinter.Entry(self,textvariable=self.port).grid(row=row,column=1,sticky=Tkinter.W+Tkinter.E,padx=10)
116 row += 1
117 b = Tkinter.Button(self,
118 text="Bind port and listen for connections",
119 command=self.click_ok)
120 b.grid(row=row,columnspan=2)
121 b.focus_force()
122 b.bind('<Return>',self.click_ok)
123 def click_ok(self,dummy_arg=None):
124 hostname = self.hostname.get()
125 try:
126 port = int(self.port.get())
127 except:
128 port = self.port.get()
129 self.server_address = (hostname,port)
130 self.clicked_ok = 1
131 self.winfo_toplevel().destroy()
132
133 bound = 0
134 if not bound:
135
136 if confirm_address_with_gui and self.dialog_ok:
137 window = GetServerAddressWindow(server_address)
138 window.pack()
139 window.mainloop()
140 if not window.clicked_ok:
141 return
142 server_address = window.server_address
143 self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
144 self.server_socket.bind(server_address)
145 bound = 1
146
148 """Wait for connection and spawn instance of SocketListenController."""
149 if eval_frequency is None:
150
151 eval_frequency = VisionEgg.FlowControl.Controller.EVERY_FRAME | VisionEgg.FlowControl.Controller.NOT_DURING_GO
152 host,port = self.server_socket.getsockname()
153 fqdn = socket.getfqdn(host)
154 logger = logging.getLogger('VisionEgg.TCPController')
155 logger.info("Awaiting connection to TCP Server at '%s', port %d"%(fqdn,port))
156 self.server_socket.listen(1)
157 if self.dialog_ok:
158
159 class WaitingDialog(Tkinter.Frame):
160 def __init__(self,server_socket=None,**kw):
161 Tkinter.Frame.__init__(self,**kw)
162 self.winfo_toplevel().title('Vision Egg TCP Server')
163 self.server_socket = server_socket
164 host,port = self.server_socket.getsockname()
165 fqdn = socket.getfqdn(host)
166 spacer = Tkinter.Frame(self,borderwidth=30)
167 spacer.pack()
168 Tkinter.Label(spacer,text=
169 """Awaiting connection to TCP Server at "%s", port %d"""%(fqdn,port)
170 ).pack()
171 b = Tkinter.Button(self,text="Cancel",command=self.stop_listening)
172 b.pack(side=Tkinter.BOTTOM)
173 b.focus_force()
174 b.bind('<Return>',self.stop_listening)
175 self.winfo_toplevel().protocol("WM_DELETE_WINDOW", self.stop_listening)
176 self.server_socket.setblocking(0)
177 self.after(1,self.idle_func)
178 def stop_listening(self,dummy=None):
179 raise SystemExit
180 def idle_func(self):
181 try:
182
183 self.accepted = self.server_socket.accept()
184 self.quit()
185 except socket.error, x:
186 self.after(1,self.idle_func)
187 dialog = WaitingDialog(server_socket = self.server_socket)
188 dialog.pack()
189 dialog.mainloop()
190 client, client_address = dialog.accepted
191 dialog.winfo_toplevel().destroy()
192 else:
193 client, client_address = self.server_socket.accept()
194 if self.single_socket_but_reconnect_ok:
195 return SocketListenController(client,
196 disconnect_ok = 1,
197 server_socket = self.server_socket)
198 else:
199 return SocketListenController(client)
200
202 r"""Handle connection from remote machine, control TCPControllers.
203
204 This meta controller handles a TCP socket to control zero to many
205 instances of TCPController. As a subclass of Controller, it gets
206 called at specified moments in time via the Presentation
207 class. When called in this way, it checks for any strings from the
208 TCP socket. It parses this information into a command or fails
209 and sends an error.
210
211 This class is analagous to VisionEgg.PyroHelpers.PyroListenController.
212
213 TCP commands (sent over network socket)
214 =======================================
215
216 close -- close the connection
217 exit -- close the connection
218 quit -- quit the server program
219 help -- print help message
220 <name> -- show the value of the controller of <name>
221 <name>=const(<args>) -- assign a new ConstantController to <name>
222 <name>=eval_str(<args>) -- assign a new EvalStringController to <name>
223 <name>=exec_str(<args>) -- assign a new ExecStringController to <name>
224 <name>=exec_str(*<args>) -- assign a new unrestricted namespace ExecStringController to <name>
225
226 TCP commands are always on a single line. (Newlines in string
227 literals can be specified by using "\n" without the quotes.)
228
229 The assignment commands share common behavior:
230
231 <name> -- value passed as argument "tcp_name" to method create_tcp_controller
232 <args> -- during_go [, between_go [, eval_frequency [, temporal_variables [, return_type ]]]]
233
234 The <args> string is parsed by the Python's eval() function. If
235 you don't want to explicitly set an argument early in the argument
236 list, but you need to set one late in the list, use "None". If
237 not set, the optional arguments default to:
238
239 eval_frequency = EVERY_FRAME
240 temporal_variables = TIME_SEC_SINCE_GO
241 return_type = (evaluates during_go function to find)
242 between_go = (see below, depends on assignment type)
243
244 The only difference between the assignment commands are in the
245 first two arguments. For "const(...)", the first two arguments
246 are constant values, for "eval_str(...)" they are strings that
247 evaluate to a single variable, and for "exec_str(...)", they are
248 strings that set the variable "x" in their local namespace, which
249 is then returned. (An unrestricted namespace is available with
250 "exec_str(*...)".) If the argument between_go is set to None or
251 is not defined, the behavior depends on the assignment command.
252 If this is a <name>=const(...) assignment, between_go_value is set
253 to during_go_value. If this is a <name>=eval_str(...) or
254 <name>=exec_str(...) assignment, the correct value cannot be
255 guessed, and therefore the between_go_eval function will never be
256 called (the eval_frequency flag NOT_BETWEEN_GO is set).
257
258 Because the default value for temporal_variables is
259 TIME_SEC_SINCE_GO, the variable "t" may be safely used in the
260 during_go string for the eval_str or exec_str assignment commands.
261 See the documentation for VisionEgg.FlowControl.EvalStringController for
262 more information.
263
264 Example commands from TCP port (try with telnet):
265
266 <name>=const(1.0)
267 <name>=eval_str("t*360.0")
268 <name>=exec_str("x=t*360.0")
269
270 <name>=const(0.,1.,EVERY_FRAME)
271 <name>=const(1,None,ONCE)
272
273 <name>=const(1.0,0.0,EVERY_FRAME,TIME_INDEPENDENT,types.FloatType)
274 <name>=eval_str("t*360.0","t_abs*360.0",None,TIME_SEC_ABSOLUTE|TIME_SEC_SINCE_GO)
275 <name>=eval_str("t_abs*360.0","t_abs*360.0",EVERY_FRAME,TIME_SEC_ABSOLUTE,types.FloatType)
276 <name>=exec_str("x=t*360.0","x=0.0",EVERY_FRAME,TIME_SEC_SINCE_GO)
277 <name>=exec_str("print 'Time since go=%f'%(t,)\nx=t*360.0","x=0.0",EVERY_FRAME,TIME_SEC_SINCE_GO)
278
279 """
280
281 help_string = r""" TCP commands (sent over network socket):
282
283 close -- close the connection
284 exit -- close the connection
285 quit -- quit the server program
286 help -- print this message
287 <name> -- show the value of the controller of <name>
288 <name>=const(<args>) -- assign a new ConstantController to <name>
289 <name>=eval_str(<args>) -- assign a new EvalStringController to <name>
290 <name>=exec_str(<args>) -- assign a new ExecStringController to <name>
291 <name>=exec_str(*<args>) -- assign a new unrestricted namespace ExecStringController to <name>
292
293 TCP commands are always on a single line. (Newlines in string
294 literals can be specified by using "\n" without the quotes.)
295
296 The assignment commands share common behavior:
297
298 <name> -- value passed as argument "tcp_name" to method create_tcp_controller
299 <args> -- during_go [, between_go [, eval_frequency [, temporal_variables [, return_type ]]]]
300 """
301
302 _re_line = re.compile(r"^(.*)\n",re.MULTILINE)
303 _re_x_finder = re.compile(r'\A|\Wx\s?=[^=]')
304
305 _re_const = re.compile(r'^const\(\s?(.*)\s?\)$',re.DOTALL)
306 _re_eval_str = re.compile(r'^eval_str\(\s?(.*)\s?\)$',re.DOTALL)
307 _re_exec_str = re.compile(r'^exec_str\(\s?(\*)?\s?(.*)\s?\)$',re.DOTALL)
308 _parse_args_globals = {'types':types}
309 _parse_args_locals = VisionEgg.FlowControl.Controller.flag_dictionary
316 """Instantiated by TCPServer."""
317 VisionEgg.FlowControl.Controller.__init__(self,
318 return_type = types.NoneType,
319 temporal_variables = temporal_variables,
320 eval_frequency = eval_frequency)
321 self.socket = socket
322 self.disconnect_ok = disconnect_ok
323 if self.disconnect_ok and server_socket is None:
324
325 pass
326 self.server_socket = server_socket
327
328 logger = logging.getLogger('VisionEgg.TCPController')
329 logger.info("Handling connection from %s"%(self.socket.getsockname(),))
330 self.socket.setblocking(0)
331
332 self.socket.send("Hello. This is %s version %s.\n"%(self.__class__,__version__))
333 self.socket.send(SocketListenController.help_string+"\n")
334 self.socket.send("Begin sending commands now.\n")
335
336 self.buffer = ""
337
338 self.last_command = {}
339
340 self.names = {}
341
342 - def send_raw_text(self,text):
343 """Send text over the TCP socket."""
344 self.socket.send(text)
345
347 if self.socket is not None:
348
349 ready_to_read, temp, temp2 = select.select([self.socket],[],[],0)
350 new_info = 0
351 while len(ready_to_read):
352 try:
353 new = self.socket.recv(1024)
354 except socket.error, x:
355 if not self.disconnect_ok:
356 raise
357 else:
358 self.socket.close()
359 self.socket = None
360 if self.server_socket is not None:
361 self.server_socket.setblocking(0)
362 return
363 if len(new) == 0:
364
365 self.socket.close()
366 self.socket = None
367 if not self.disconnect_ok:
368 raise RuntimeError("Socket disconnected!")
369 else:
370 if self.server_socket is not None:
371 self.server_socket.setblocking(0)
372 return
373
374 self.buffer += new
375 new_info = 1
376 ready_to_read, temp, temp2 = select.select([self.socket],[],[],0)
377
378
379 if new_info:
380
381 self.buffer = string.replace(self.buffer,chr(0x0D),"")
382 self.buffer = string.replace(self.buffer,chr(0x0A),"\n")
383
384 for tcp_name in self.names.keys():
385 (controller, name_re_str, parser, require_type) = self.names[tcp_name]
386
387
388
389 self.buffer = name_re_str.sub(parser,self.buffer)
390
391 command = self.last_command[tcp_name]
392 if command is not None:
393 self.__do_assignment_command(tcp_name,command,require_type)
394 self.last_command[tcp_name] = None
395
396 self.buffer = SocketListenController._re_line.sub(self.__unprocessed_line,self.buffer)
397 elif self.server_socket is not None:
398
399 try:
400
401 (client, client_address) = self.server_socket.accept()
402 self.socket = client
403 self.socket.send("Hello. This is %s version %s.\n"%(self.__class__,__version__))
404 self.socket.send(SocketListenController.help_string+"\n")
405 self.socket.send("Begin sending commands now.\n")
406 for tcp_name in self.names.keys():
407 (controller, name_re_str, parser, require_type) = self.names[tcp_name]
408 self.socket.send('"%s" controllable with this connection.\n'%tcp_name)
409 except socket.error, x:
410 pass
411
413 text = match.group(1)
414 text = string.strip(text).lower()
415 if text=="quit":
416 raise SystemExit
417 elif text=="close" or text=="exit":
418 self.socket = None
419 if not self.disconnect_ok:
420 raise RuntimeError("Socket disconnected!")
421 else:
422 if self.server_socket is not None:
423 self.server_socket.setblocking(0)
424 return ""
425 elif text=="help":
426 self.socket.send(SocketListenController.help_string+"\n")
427 return ""
428 elif text in self.names.keys():
429 (controller, name_re_str, parser, require_type) = self.names[text]
430 self.socket.send(text+"="+str(controller)+"\n")
431 return ""
432 self.socket.send("Error: Invalid command line \""+text+"\"\n")
433 logger = logging.getLogger('VisionEgg.TCPController')
434 logger.warning('Invalid command line: "%s"'%(text,))
435 return ''
436
441 """Create new instance of TCPController.
442
443 Arguments:
444
445 tcp_name -- String to reference new TCPController over TCP
446
447 Optional arguments:
448
449 initial_controller -- Initial value of TCPController instance
450 require_type -- force this as TCPController instance's return_type
451 """
452 class Parser:
453 def __init__(self,tcp_name,most_recent_command):
454 self.tcp_name = tcp_name
455 self.most_recent_command = most_recent_command
456
457 def parse_func(self,match):
458
459 self.most_recent_command[self.tcp_name] = match.groups()[-1]
460 return ""
461 if tcp_name is None:
462 raise ValueError("Must specify tcp_name")
463 if tcp_name in self.names.keys():
464 raise ValueError('tcp_name "%s" already in use.'%tcp_name)
465 if string.count(tcp_name,' '):
466 raise ValueError('tcp_name "%s" cannot have spaces.'%tcp_name)
467 if tcp_name == "quit":
468 raise ValueError('tcp_name "%s" conflicts with reserved word.'%tcp_name)
469 if initial_controller is None:
470
471 initial_controller = VisionEgg.FlowControl.ConstantController(
472 during_go_value=1.0,
473 between_go_value=0.0)
474 else:
475 if not isinstance(initial_controller,VisionEgg.FlowControl.Controller):
476 print initial_controller
477 raise ValueError('initial_controller not an instance of VisionEgg.FlowControl.Controller')
478 if require_type is None:
479 require_type = initial_controller.returns_type()
480
481 self.last_command[tcp_name] = None
482
483 controller = TCPController(
484 tcp_name=tcp_name,
485 initial_controller=initial_controller
486 )
487 name_re_str = re.compile("^"+tcp_name+r"\s*=\s*(.*)\s*\n$",re.MULTILINE)
488 parser = Parser(tcp_name,self.last_command).parse_func
489 self.names[tcp_name] = (controller, name_re_str, parser, require_type)
490 self.socket.send('"%s" controllable with this connection.\n'%tcp_name)
491 return controller
492
494 args = eval("("+arg_string+",)",SocketListenController._parse_args_globals,SocketListenController._parse_args_locals)
495 num_args = len(args)
496 if num_args == 0:
497 args = (None,None,None,None,None)
498 elif num_args == 1:
499 args = (args[0],None,None,None,None)
500 elif num_args == 2:
501 args = (args[0],args[1],None,None,None)
502 elif num_args == 3:
503 args = (args[0],args[1],args[2],None,None)
504 elif num_args == 4:
505 args = (args[0],args[1],args[2],args[3],None)
506 elif num_args > 5:
507 raise ValueError("Too many arguments!")
508 if args[0] is None:
509 raise ValueError("First argument must be set.")
510 return args
511
513 if match_groups[2] is not None:
514 kw_args['eval_frequency'] = match_groups[2]
515 if match_groups[3] is not None:
516 kw_args['temporal_variables'] = match_groups[3]
517 if match_groups[4] is not None:
518 kw_args['return_type'] = match_groups[4]
519
521 new_contained_controller = None
522 match = SocketListenController._re_const.match(command)
523 if match is not None:
524 try:
525 match_groups = self.__get_five_args(match.group(1))
526 kw_args = {}
527 kw_args['during_go_value'] = match_groups[0]
528 if match_groups[1] is not None:
529 kw_args['between_go_value'] = match_groups[1]
530 self.__process_common_args(kw_args,match_groups)
531 kw_args.setdefault('return_type',require_type)
532 new_contained_controller = VisionEgg.FlowControl.ConstantController(**kw_args)
533 new_type = new_contained_controller.returns_type()
534 ve_types.assert_type( new_type, require_type)
535 except Exception, x:
536 import traceback
537 traceback.print_exc()
538 self.socket.send("Error %s parsing const for %s: %s\n"%(x.__class__,tcp_name,x))
539 logger = logging.getLogger('VisionEgg.TCPController')
540 logger.info("%s parsing const for %s: %s"%(x.__class__,tcp_name,x))
541 else:
542 match = SocketListenController._re_eval_str.match(command)
543 if match is not None:
544 try:
545 match_groups = self.__get_five_args(match.group(1))
546 kw_args = {}
547 kw_args['during_go_eval_string'] = string.replace(match_groups[0],r"\n","\n")
548 if match_groups[1] is not None:
549 kw_args['between_go_eval_string'] = string.replace(match_groups[1],r"\n","\n")
550 self.__process_common_args(kw_args,match_groups)
551 kw_args.setdefault('return_type',require_type)
552 new_contained_controller = VisionEgg.FlowControl.EvalStringController(**kw_args)
553 if not (new_contained_controller.eval_frequency & VisionEgg.FlowControl.Controller.NOT_DURING_GO):
554 logger = logging.getLogger('VisionEgg.TCPController')
555 logger.debug('Executing "%s" as safety check.'%(kw_args['during_go_eval_string'],))
556 new_contained_controller._test_self(1)
557 if not (new_contained_controller.eval_frequency & VisionEgg.FlowControl.Controller.NOT_BETWEEN_GO):
558 logger = logging.getLogger('VisionEgg.TCPController')
559 logger.debug('Executing "%s" as safety check.'%(kw_args['between_go_eval_string'],))
560 new_contained_controller._test_self(0)
561 new_type = new_contained_controller.returns_type()
562 ve_types.assert_type( new_type, require_type)
563 except Exception, x:
564 new_contained_controller = None
565 self.socket.send("Error %s parsing eval_str for %s: %s\n"%(x.__class__,tcp_name,x))
566 logger = logging.getLogger('VisionEgg.TCPController')
567 logger.info("%s parsing eval_str for %s: %s"%(x.__class__,tcp_name,x))
568 else:
569 match = SocketListenController._re_exec_str.match(command)
570 if match is not None:
571 try:
572 kw_args = {}
573 match_groups = match.groups()
574 if match_groups[0] == '*':
575 kw_args['restricted_namespace'] = 0
576 else:
577 kw_args['restricted_namespace'] = 1
578 match_groups = self.__get_five_args(match_groups[1])
579 tmp = string.replace(match_groups[0],r"\n","\n")
580 if not SocketListenController._re_x_finder.match(tmp):
581 raise ValueError("x is not defined for during_go_exec_string")
582 kw_args['during_go_exec_string'] = tmp
583 if match_groups[1] is not None:
584 tmp = string.replace(match_groups[1],r"\n","\n")
585 if not SocketListenController._re_x_finder.match(tmp):
586 raise ValueError("x is not defined for between_go_exec_string")
587 kw_args['between_go_exec_string'] = tmp
588 self.__process_common_args(kw_args,match_groups)
589 kw_args.setdefault('return_type',require_type)
590 new_contained_controller = VisionEgg.FlowControl.ExecStringController(**kw_args)
591 if not (new_contained_controller.eval_frequency & VisionEgg.FlowControl.Controller.NOT_DURING_GO):
592 logger = logging.getLogger('VisionEgg.TCPController')
593 logger.debug('Executing "%s" as safety check.'%(kw_args['during_go_exec_string'],))
594 new_contained_controller._test_self(1)
595 if not (new_contained_controller.eval_frequency & VisionEgg.FlowControl.Controller.NOT_BETWEEN_GO):
596 logger = logging.getLogger('VisionEgg.TCPController')
597 logger.debug('Executing "%s" as safety check.'%(kw_args['between_go_exec_string'],))
598 new_contained_controller._test_self(0)
599 new_type = new_contained_controller.returns_type()
600 ve_types.assert_type( new_type, require_type)
601 except Exception, x:
602 new_contained_controller = None
603 self.socket.send("Error %s parsing exec_str for %s: %s\n"%(x.__class__,tcp_name,x))
604 logger = logging.getLogger('VisionEgg.TCPController')
605 logger.debug("%s parsing exec_str for %s: %s"%(x.__class__,tcp_name,x))
606 else:
607 self.socket.send("Error: Invalid assignment command for %s: %s\n"%(tcp_name,command))
608 logger = logging.getLogger('VisionEgg.TCPController')
609 logger.info("Invalid assignment command for %s: %s"%(tcp_name,command))
610
611 if new_contained_controller is not None:
612 (controller, name_re_str, parser, require_type) = self.names[tcp_name]
613 controller.set_new_controller(new_contained_controller)
614
616 """Check socket and act accordingly. Called by instance of Presentation.
617
618 Overrides base class Controller method."""
619 self.__check_socket()
620 return None
621
623 """Check socket and act accordingly. Called by instance of Presentation.
624
625 Overrides base class Controller method."""
626 self.__check_socket()
627 return None
628
629 -class TCPController(VisionEgg.FlowControl.EncapsulatedController):
630 """Control a parameter from a network (TCP) connection.
631
632 Subclass of Controller to allow control of Parameters via the
633 network.
634
635 This class is analagous to VisionEgg.PyroHelpers.PyroEncapsulatedController.
636 """
637
638 - def __init__(self, tcp_name, initial_controller):
639 """Instantiated by SocketListenController.
640
641 Users should create instance by using method
642 create_tcp_controller of class SocketListenController."""
643 VisionEgg.FlowControl.EncapsulatedController.__init__(self,initial_controller)
644 self.tcp_name = tcp_name
645
647 value = ""
648 my_class = self.contained_controller.__class__
649 if my_class == VisionEgg.FlowControl.ConstantController:
650 value += "const( "
651 value += str(self.contained_controller.get_during_go_value()) + ", "
652 value += str(self.contained_controller.get_between_go_value()) + ", "
653 elif my_class == VisionEgg.FlowControl.EvalStringController:
654 value += "eval_str( "
655 str_val = self.contained_controller.get_during_go_eval_string()
656 if str_val is None:
657 value += "None, "
658 else:
659 value += '"' + string.replace(str_val,"\n",r"\n") + '", '
660 str_val = self.contained_controller.get_between_go_eval_string()
661 if str_val is None:
662 value += "None, "
663 else:
664 value += '"' + string.replace(str_val,"\n",r"\n") + '", '
665 elif my_class == VisionEgg.FlowControl.ExecStringController:
666 value += "exec_str("
667 if self.contained_controller.restricted_namespace:
668 value += " "
669 else:
670 value += "* "
671 str_val = self.contained_controller.get_during_go_exec_string()
672 if str_val is None:
673 value += "None, "
674 else:
675 value += '"' + string.replace(str_val,"\n",r"\n") + '", '
676 str_val = self.contained_controller.get_between_go_exec_string()
677 if str_val is None:
678 value += "None, "
679 else:
680 value += '"' + string.replace(str_val,"\n",r"\n") + '", '
681 never = 1
682 ef = self.contained_controller.eval_frequency
683 if ef & VisionEgg.FlowControl.Controller.EVERY_FRAME:
684 value += "EVERY_FRAME | "
685 never = 0
686 if ef & VisionEgg.FlowControl.Controller.TRANSITIONS:
687 value += "TRANSITIONS | "
688 never = 0
689 if ef & VisionEgg.FlowControl.Controller.ONCE:
690 value += "ONCE | "
691 never = 0
692 if ef & VisionEgg.FlowControl.Controller.NOT_DURING_GO:
693 value += "NOT_DURING_GO | "
694 never = 0
695 if ef & VisionEgg.FlowControl.Controller.NOT_BETWEEN_GO:
696 value += "NOT_BETWEEN_GO | "
697 never = 0
698 if never:
699 value += "NEVER"
700 else:
701 value = value[:-3]
702 value += ", "
703 time_indep = 1
704 tv = self.contained_controller.temporal_variables
705 if tv & VisionEgg.FlowControl.Controller.TIME_SEC_ABSOLUTE:
706 value += "TIME_SEC_ABSOLUTE | "
707 time_indep = 0
708 if tv & VisionEgg.FlowControl.Controller.TIME_SEC_SINCE_GO:
709 value += "TIME_SEC_SINCE_GO | "
710 time_indep = 0
711 if tv & VisionEgg.FlowControl.Controller.FRAMES_ABSOLUTE:
712 value += "FRAMES_ABSOLUTE | "
713 time_indep = 0
714 if tv & VisionEgg.FlowControl.Controller.FRAMES_SINCE_GO:
715 value += "FRAMES_SINCE_GO | "
716 time_indep = 0
717 if time_indep:
718 value += "TIME_INDEPENDENT"
719 else:
720 value = value[:-3]
721 value += ", "
722 my_type = self.contained_controller.returns_type()
723 if my_type == types.ClassType:
724 value += str(my_type)
725 else:
726 for t in dir(types):
727 if my_type == getattr(types,t):
728 value += "types."+t
729 break
730 value += " )"
731 return value
732