# Copyright (c) 1997-2007 # Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany) # http://www.math.tu-berlin.de/polymake, mailto:polymake@math.tu-berlin.de # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2, or (at your option) any # later version: http://www.gnu.org/licenses/gpl.txt. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. #----------------------------------------------------------------------------- # $Project: polymake $$Id: JRealityViewer.pm 7550 2007-01-10 12:25:54Z gawrilow $ use JReality; use Poly::Sockets; package JReality::WindowParams; use Struct ( [ new => '$' ], [ '$embedding' => '#1' ], '$client', '@client_args', '%client_params', '$launcher_class', '@jars', '%jre_properties', ); # will overload it later unimport_function(*new); sub compose_command { my ($self, $socket_no)=@_; ( $self->client, map { $_ eq "==FD==" ? $socket_no : $_ } @{$self->client_args}, map { ("-$_", (defined($self->client_params->{$_}) ? ($self->client_params->{$_}) : ())) } keys %{$self->client_params}, ) } package JReality::Window; use Struct ( [ '@ISA' => 'JReality::File' ], [ new => '$' ], [ '$title' => '#1' ], [ '$workfile' => 'undef' ], [ '$params' => 'undef' ], ); sub append { my $self = shift; foreach my $elem (@_) { if (defined (my $p=$elem->{points})) { if (defined (my $dyn=detect_dynamic($p))) { if (defined $self->params) { die "multiple interactive components in the same window are not supported\n" if $self->params->embedding != $dyn; } else { $self->params=new WindowParams($dyn); } my @indices=flatten_indices($p); $elem->{points}=[ map { "$_ 0 0" } @indices ? @indices : 0..$p->get_n_vertices-1 ]; $elem->{name} =~ s/^/dynamic:/; $elem->{number_of_points} = @indices ? scalar @indices : $p->get_n_vertices; } else { $elem->{number_of_points} = @{$p}; } } } $self->SUPER::append(@_); } package JReality::Viewer; use Struct ( '@windows', [ '$jvpid' => 'undef' ], [ '$jv_server_socket' => 'undef' ], [ '$jvx_socket' => 'undef' ] ); sub new_drawing { my ($self, $title)=@_; push @{$self->windows}, new Window($title); $self; } sub append { my $self = shift; $self->windows->[-1]->append(@_); } sub proceed { my ($self)=@_; my $static_launcher = qw( de.tuberlin.polymake.common.JRealityStaticControl ); # my $static_launcher = qw( de.tuberlin.polymake.polytope.JRealitySchlegelControl ); # starter class with main() method my @classes=qw( de.tuberlin.polymake.common.Launcher ); my (@cl_sockets, @cl_ports, @clients, %jars, %jre_properties); foreach my $w (@{$self->windows}) { if (defined $w->params) { push @cl_sockets, new Poly::ServerSocket; push @clients, [ $w->params->compose_command($cl_sockets[-1]->fileno) ]; push @classes, $w->params->launcher_class, "-client_port", $cl_sockets[-1]->port; @jars{@{$w->params->jars}}=(); while (my ($prop, $value)=each %{$w->params->jre_properties}) { $jre_properties{$prop}=$value; } } else { push @classes, $static_launcher; } } ### FIXME: die "interactive viewer: unimplemented feature: cannot run several embedding clients simultaneously\n" if @clients>1; $self->jv_server_socket=new Poly::ServerSocket; my $jv_port=$self->jv_server_socket->port; if (!defined ($self->jvpid=fork)) { die "fork failed: $!\n"; } if (!$self->jvpid) { # child process undef @cl_sockets; undef $self->jv_server_socket; if ($Switches::d) { $jre_properties{"polymake.debug"} = $Switches::d >= 2 ? "max" : "yes"; } my @jre_args = map { "-D$_=$jre_properties{$_}" } keys %jre_properties; my $polymake_jar_path = $main::InstallTop; if (-f "$polymake_jar_path/jars/common.jar") { $polymake_jar_path .= "/jars"; } elsif (-f "$polymake_jar_path/java_build/common.jar") { $polymake_jar_path .= "/java_build"; } my $classpath = join(":", (map { "$polymake_jar_path/$_.jar" } keys %jars), "$polymake_jar_path/common.jar", (map { "$JReality::Viewer::jar_path/$_" } @JReality::Viewer::jars) ); if($JReality::Viewer::jogl) { $classpath .= ":$JReality::Viewer::jogl_path/jogl.jar"; } my $bsh_jar = $JReality::Viewer::bean_shell_jar; push @jre_args, ( # jreality needs this, don't know why "-Djreality.bsh.jar=file://$JReality::Viewer::jar_path/$bsh_jar", # ... # "-Djreality.data=$JReality::Viewer::jar_path" #"-Dpolymake.window.title= " ); push @jre_args, "-Djava.library.path=$JReality::Viewer::jogl_native_path" if($JReality::Viewer::jogl); my @java_command = ($Modules::common::java, @jre_args, "-cp", $classpath, @classes, "-ps_port", $jv_port); dbg_print( "launching @java_command" ) if $Switches::d; exec @java_command; die "exec($java_command[0]) failed: $!\n"; } # end child process my $JVX = $self->jvx_socket = $self->jv_server_socket->accept; { my $old_handle = select $JVX; $| = 1; select $old_handle; } my $n_geom = 0; foreach my $w (@{$self->windows}) { my $initial_jvx = $w->toString($n_geom); $n_geom++; warn $initial_jvx if $Switches::d>=2; print $JVX $initial_jvx; } foreach (@clients) { ### FIXME: background_client when implemented client(@$_); } $self; } sub DESTROY { my ($self)=@_; waitpid $self->jvpid, 0 if $self->jvpid; undef $self->jvx_socket; undef $self->jv_server_socket; } 1 # Local Variables: # mode:perl # c-basic-offset:3 # End: