Changeset 1158
- Timestamp:
- Sep 22, 2008, 3:26:05 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gui/scripts/visviewer.tcl
r1152 r1158 1 1 #!/usr/bin/wish 2 2 # ---------------------------------------------------------------------- 3 4 3 5 # VisViewer - 4 6 # … … 21 23 22 24 private common _servers ;# array of visualization server lists 23 set _servers(nanovis) "" 24 set _servers(pymol) "" 25 26 protected variable _dispatcher "" ;# dispatcher for !events27 protected variable _hosts "" 28 protected variable _sid "" 29 protected variable _parser "" 25 set _servers(nanovis) "" 26 set _servers(pymol) "" 27 28 protected variable _dispatcher "" # dispatcher for !events 29 protected variable _hosts "" ;# list of hosts for server 30 protected variable _sid "" ;# socket connection to server 31 protected variable _parser "" ;# interpreter for incoming commands 30 32 protected variable _image 31 private common _done 32 private variable _buffer 33 34 constructor { hostlist args } { 35 # defined below 36 } 37 destructor { 38 # defined below 33 private common _done ;# Used to indicate status of send. 34 private variable _buffer ;# buffer for incoming/outgoing commands 35 36 constructor { hostlist args } { 37 # defined below 38 } 39 destructor { 40 # defined below 39 41 } 40 42 # Used internally only. 41 private method _Shuffle { hostlist } 42 private method _ReceiveHelper {} 43 private method _Shuffle { hostlist } 44 private method _ReceiveHelper {} 43 45 private method _ServerDown {} 44 46 private method _SendHelper {} … … 57 59 58 60 private proc _CheckNameList { namelist } { 59 60 61 62 61 set pattern {^[a-zA-Z0-9\.]+:[0-9]+(,[a-zA-Z0-9\.]+:[0-9]+)*$} 62 if { ![regexp $pattern $namelist match] } { 63 error "bad visualization server address \"$namelist\": should be host:port,host:port,..." 64 } 63 65 } 64 66 public proc GetServerList { tag } { 65 67 return $_servers($tag) 66 68 } 67 69 public proc SetServerList { tag namelist } { 68 69 70 _CheckNameList $namelist 71 set _servers($tag) $namelist 70 72 } 71 73 public proc SetPymolServerList { namelist } { 72 74 SetServerList "pymol" $namelist 73 75 } 74 76 public proc SetNanovisServerList { namelist } { 75 77 SetServerList "nanovis" $namelist 76 78 } 77 79 } … … 133 135 } 134 136 135 # 137 # 136 138 # destructor -- 137 # 139 # 138 140 itcl::body Rappture::VisViewer::destructor {} { 139 141 interp delete $_parser … … 141 143 } 142 144 143 # 144 # _Shuffle -- 145 # 146 # Shuffle the list of server hosts.145 # 146 # _Shuffle -- 147 # 148 # Shuffle the list of server hosts. 147 149 # 148 150 itcl::body Rappture::VisViewer::_Shuffle { hostlist } { 149 151 set hosts [split $hostlist ,] 150 152 set random_hosts {} 151 set ticks [clock ticks]153 set ticks [clock clicks] 152 154 expr {srand($ticks)} 153 155 for { set i [llength $hosts] } { $i > 0 } { incr i -1 } { 154 155 156 157 158 159 156 set index [expr {round(rand()*$i - 0.5)}] 157 if { $index == $i } { 158 set index [expr $i - 1] 159 } 160 lappend random_hosts [lindex $hosts $index] 161 set hosts [lreplace $hosts $index $index] 160 162 } 161 163 return $random_hosts … … 171 173 itcl::body Rappture::VisViewer::_ServerDown {} { 172 174 if { [info exists itk_component(area)] } { 173 174 175 set x [expr {[winfo rootx $itk_component(area)]+10}] 176 set y [expr {[winfo rooty $itk_component(area)]+10}] 175 177 } else { 176 178 set x 0; set y 0 177 179 } 178 180 Rappture::Tooltip::cue @$x,$y "Lost connection to visualization server. This happens sometimes when there are too many users and the system runs out of memory.\n\nTo reconnect, reset the view or press any other control. Your picture should come right back up." … … 181 183 # 182 184 # Connect -- 183 # 185 # 184 186 # Connect to the visualization server (e.g. nanovis, pymolproxy). Send 185 187 # the server some estimate of the size of our job. If it's too busy, that 186 # server may forward us to another. 188 # server may forward us to another. 187 189 # 188 190 itcl::body Rappture::VisViewer::Connect { hostlist } { … … 202 204 if { [catch {socket $hostname $port} _sid] != 0 } { 203 205 if {[llength $servers] == 0} { 204 206 blt::busy release $itk_component(hull) 205 207 return 0 206 208 } 207 209 # Get the next server 208 210 foreach {hostname port} [split [lindex $servers 0] :] break 209 211 set servers [lrange $servers 1 end] … … 215 217 puts -nonewline $_sid [binary format I $memorySize] 216 218 flush $_sid 217 219 218 220 # read back a reconnection order 219 221 set data [read $_sid 4] 220 222 if {[binary scan $data cccc b1 b2 b3 b4] != 4} { 221 223 blt::busy release $itk_component(hull) 222 224 error "couldn't read redirection request" 223 225 } … … 229 231 230 232 if { [string equal $addr "0.0.0.0"] } { 231 232 233 234 235 236 233 # We're connected. Cancel any pending serverDown events and 234 # release the busy window over the hull. 235 $_dispatcher cancel !serverDown 236 blt::busy release $itk_component(hull) 237 fconfigure $_sid -buffering line 238 fileevent $_sid readable [itcl::code $this _ReceiveHelper] 237 239 return 1 238 240 } … … 255 257 catch {close $_sid} err 256 258 set _sid "" 257 258 } 259 set _buffer(in) "" 259 $_dispatcher event -after 750 !serverDown 260 } 261 set _buffer(in) "" 260 262 } 261 263 … … 272 274 # _SendHelper -- 273 275 # 274 # 275 # connection is writable (i.e. not blocked). Sets a magic276 # 276 # Helper routine called from a file event to send data when the 277 # connection is writable (i.e. not blocked). Sets a magic 278 # variable _done($this) when we're done. 277 279 # 278 280 itcl::body Rappture::VisViewer::_SendHelper {} { 279 281 puts $_sid $_buffer(out) 280 282 flush $_sid 281 set _done($this) 1; 283 set _done($this) 1; # Success 282 284 } 283 285 … … 285 287 # _SendHelper.old -- 286 288 # 287 # 288 # 289 # 290 # 291 # 289 # Helper routine called from a file event to send data when the 290 # connection is writable (i.e. not blocked). Sends data in chunks 291 # of 8k (or less). Sets magic variable _done($this) to indicate 292 # that we're either finished (success) or could not send bytes to 293 # the server (failure). 292 294 # 293 295 itcl::body Rappture::VisViewer::_SendHelper.old {} { 294 296 set bytesLeft [string length $_buffer(out)] 295 297 if { $bytesLeft > 0} { 296 297 298 299 300 301 302 303 304 } 305 306 307 308 309 set _done($this) 0;# Failure310 } 298 set chunk [string range $_buffer(out) 0 8095] 299 set _buffer(out) [string range $_buffer(out) 8096 end] 300 incr bytesLeft -8096 301 set code [catch { 302 if { $bytesLeft > 0 } { 303 puts -nonewline $_sid $chunk 304 } else { 305 puts $_sid $chunk 306 } 307 } err] 308 if { $code != 0 } { 309 puts stderr "error sending data to $_sid: $err" 310 Disconnect 311 set _done($this) 0; # Failure 312 } 311 313 } else { 312 set _done($this) 1;# Success314 set _done($this) 1; # Success 313 315 } 314 316 } … … 317 319 # SendBytes -- 318 320 # 319 # Send a a string to the visualization server.321 # Send a a string to the visualization server. 320 322 # 321 323 itcl::body Rappture::VisViewer::SendBytes { bytes } { … … 323 325 324 326 if { ![IsConnected]} { 325 326 327 327 # If we aren't connected, assume it's because the connection to the 328 # visualization server broke. Try to open a connection and trigger a 329 # rebuild. 328 330 $_dispatcher cancel !serverDown 329 331 set x [expr {[winfo rootx $itk_component(area)]+10}] 330 332 set y [expr {[winfo rooty $itk_component(area)]+10}] 331 333 Rappture::Tooltip::cue @$x,$y "Connecting..." 332 334 set code [catch { Connect } ok] 333 335 if { $code == 0 && $ok} { 334 335 336 336 $_dispatcher event -idle !rebuild 337 Rappture::Tooltip::cue hide 338 return 1 337 339 } else { 338 339 340 340 Rappture::Tooltip::cue @$x,$y "Can't connect to visualization server. This may be a network problem. Wait a few moments and try resetting the view." 341 return 0 342 } 341 343 } 342 344 # Even though the data is sent in only 1 "puts", we need to verify that … … 360 362 itcl::body Rappture::VisViewer::ReceiveBytes { size } { 361 363 if { [eof $_sid] } { 362 364 error "unexpected eof on socket" 363 365 } 364 366 set bytes [read $_sid $size] … … 367 369 } 368 370 369 # 371 # 370 372 # _ReceiveHelper -- 371 373 # 372 # 373 # 374 # 375 # 374 # Helper routine called from a file event when the connection is 375 # readable (i.e. a command response has been sent by the rendering 376 # server. Reads the incoming command and executes it in a safe 377 # interpreter to handle the action. 376 378 # 377 379 # Note: This routine currently only handles command responses from 378 # 379 # 380 # 381 # nv>image -bytes 100000yes382 # ...following 100000 bytes... no383 # 384 # Note: All commands from the render server are on one line.385 # 386 # 387 # 380 # the visualization server. It doesn't handle non-blocking 381 # reads from the visualization server. 382 # 383 # nv>image -bytes 100000 yes 384 # ...following 100000 bytes... no 385 # 386 # Note: All commands from the render server are on one line. 387 # This is because the render server can send anything 388 # as an error message (restricted again to one line). 389 # 388 390 itcl::body Rappture::VisViewer::_ReceiveHelper {} { 389 391 if { [IsConnected] } { 390 391 392 392 if { [eof $_sid] } { 393 error "_receive: unexpected eof on socket" 394 } 393 395 if { [gets $_sid line] < 0 } { 394 396 Disconnect 395 } 396 397 398 399 400 397 } 398 set line [string trim $line] 399 if { $line == "" } { 400 return 401 } 402 if { [string equal [string range $line 0 2] "nv>"] } { 401 403 ReceiveEcho <<line $line 402 404 append _buffer(in) [string range $line 3 end] 403 405 append _buffer(in) "\n" 404 406 if {[info complete $_buffer(in)]} { 405 407 set request $_buffer(in) … … 423 425 itcl::body Rappture::VisViewer::Flush {} { 424 426 if { [IsConnected] } { 425 427 flush $_sid 426 428 } 427 429 } … … 431 433 # Color2RGB -- 432 434 # 433 # 434 # engine. Each r/g/b component is scaled in the # range 0-1.435 # Converts a color name to a list of r,g,b values needed for the 436 # engine. Each r/g/b component is scaled in the # range 0-1. 435 437 # 436 438 itcl::body Rappture::VisViewer::Color2RGB {color} { … … 445 447 # Euler2XYZ -- 446 448 # 447 # 448 # 449 # {xangle, yangle, zangle}.449 # Converts euler angles for the camera placement the to angles of 450 # rotation about the x/y/z axes, used by the engine. Returns a list: 451 # {xangle, yangle, zangle}. 450 452 # 451 453 itcl::body Rappture::VisViewer::Euler2XYZ {theta phi psi} {
Note: See TracChangeset
for help on using the changeset viewer.