--- deliantra/server/utils/cfutil.in 2007/08/18 22:25:35 1.52 +++ deliantra/server/utils/cfutil.in 2007/08/19 09:27:08 1.53 @@ -25,6 +25,7 @@ use POSIX (); use Digest::MD5; use Carp; +use Coro::Channel; use Coro::Storable; $Storable::canonical = 1; $SIG{QUIT} = sub { Carp::cluck "QUIT" }; @@ -116,7 +117,11 @@ our $QUANTIZE = "+dither -colorspace RGB -colors 256"; - our (@png, @trs, @arc, @res); # files we are interested in + our $c_arc = new Coro::Channel; + our $c_trs = new Coro::Channel; + our $c_res = new Coro::Channel; + + our @c_png; sub commit_png($$$) { my ($name, $data, $T) = @_; @@ -125,8 +130,8 @@ } sub process_png { - while (@png) { - my ($path, $delete) = @{pop @png}; + while (@c_png) { + my ($path, $delete) = @{pop @c_png}; my $png; aio_lstat $path; @@ -227,7 +232,7 @@ }; } - push @png, [$other, !$CACHE]; + push @c_png, [$other, !$CACHE]; } # possibly scale down @@ -262,7 +267,7 @@ } #warn "scaled down $path to $other\n";#d# - push @png, [$other, !$CACHE]; + push @c_png, [$other, !$CACHE]; } } @@ -333,8 +338,8 @@ } sub process_arc { - while (@arc) { - my ($dir, $file) = @{pop @arc}; + while (my $job = $c_arc->get) { + my ($dir, $file) = @$job; my $arc; aio_load "$dir/$file", $arc; # simply pre-cache, as read_arch wants a file :/ @@ -401,6 +406,7 @@ my $info = $FACEINFO{$face} ||= {}; + $info->{arc} = $o; $info->{visibility} = $visibility if defined $visibility; $info->{magicmap} = $magicmap if defined $magicmap; } @@ -419,8 +425,8 @@ } sub process_trs { - while (@trs) { - my ($dir, $file) = @{pop @trs}; + while (my $job = $c_trs->get) { + my ($dir, $file) = @$job; my $path = "$dir/$file"; my $trs; @@ -452,8 +458,8 @@ } sub process_res { - while (@res) { - my ($dir, $file, $type) = @{pop @res}; + while (my $job = $c_res->get) { + my ($dir, $file, $type) = @$job; my $data; aio_load "$dir/$file", $data; @@ -472,7 +478,7 @@ "pd" => "Public Domain", "gpl" => "GNU General Public License, version 3.0 or any later", "cc/by/2.0" => "Licensed under Creative Commons Attribution 2.0 http://creativecommons.org/licenses/by/2.0/", - "cc/by/2.5" => "Licensed under Creative Commons Attribution 2.0 http://creativecommons.org/licenses/by/2.5/", + "cc/by/2.5" => "Licensed under Creative Commons Attribution 2.5 http://creativecommons.org/licenses/by/2.5/", "cc/by/3.0" => "Licensed under Creative Commons Attribution 3.0 http://creativecommons.org/licenses/by/3.0/", })->{$meta->{license}} || warn "$dir/$file: license tag '$meta->{license}' not found."; @@ -508,27 +514,27 @@ for my $file (@$nondirs) { if ($dir =~ /^music(?:\/|$)/) { - push @res, [$path, $file, 3] # FT_MUSIC + $c_res->put ([$path, $file, 3]) # FT_MUSIC if $file =~ /\.(ogg)$/; } elsif ($dir =~ /^sound(?:\/|$)/) { - push @res, [$path, $file, 5] # FT_SOUND + $c_res->put ([$path, $file, 5]) # FT_SOUND if $file =~ /\.(wav|ogg)$/; } elsif ($dir =~ /^res(?:\/|$)/) { - push @res, [$path, $file, 0] # FT_FACE + $c_res->put ([$path, $file, 0]) # FT_FACE if $file =~ /\.(jpg|png)$/; - push @res, [$path, $file, 7] # FT_RSRC + $c_res->put ([$path, $file, 7]) # FT_RSRC if $file =~ /\.(res)$/; } elsif ($file =~ /\.png$/) { - push @png, ["$path/$file", 0]; + push @c_png, ["$path/$file", 0]; } elsif ($file =~ /\.trs$/) { - push @trs, [$path, $file]; + $c_trs->put ([$path, $file]); } elsif ($file =~ /\.arc$/) { - push @arc, [$path, $file]; + $c_arc->put ([$path, $file]); } else { warn "ignoring $path/$file\n" if $VERBOSE >= 3; @@ -557,22 +563,38 @@ exit 1 unless $FORCE; } + print "scanning files...\n" if $VERBOSE; + find_files $path; + + my @a_arc = map +(async \&process_arc), 1..2; + my @a_res = map +(async \&process_res), 1..2; + my @a_trs = map +(async \&process_trs), 1..2; + IO::AIO::flush; - $_->join for ( - # four png crunchers work fine for my 2x smp machine - (async \&process_png), (async \&process_png), (async \&process_png), (async \&process_png), - (async \&process_trs), (async \&process_trs), - (async \&process_arc), (async \&process_arc), - (async \&process_res), (async \&process_res), - ); + $c_res->put (undef) for @a_res; + $c_arc->put (undef) for @a_arc; + $c_trs->put (undef) for @a_trs; + + print "start file scan, arc, res processing...\n" if $VERBOSE; + + $_->join for @a_arc; # need to parse all archetypes before png processing + print "end arc, start png processing...\n" if $VERBOSE; + + # four png crunchers work fine for my 2x smp machine + my @a_png = map +(async \&process_png), 1..4; + + $_->join for (@a_trs, @a_res, @a_png); + + print "scanning done, processing results...\n" if $VERBOSE; { # remove path prefix from editor_folder substr $_->{editor_folder}, 0, 1 + length $path, "" for values %ARC; + print "resolving inheritance tree...\n" if $VERBOSE; # resolve inherit while () { my $progress; @@ -608,18 +630,21 @@ # remove base classes (by naming scheme, should use something like "baseclass xxx" to inherit @ARC = grep $_->{_name} !~ /^(?:type|class)_/, @ARC; + print "writing archetypes...\n" if $VERBOSE; open my $fh, ">:utf8", "$DATADIR/archetypes~" or die "$DATADIR/archetypes~: $!"; print $fh Crossfire::archlist_to_string [sort { $a->{_name} cmp $b->{_name} } @ARC]; } { + print "writing treasures...\n" if $VERBOSE; open my $fh, ">:utf8", "$DATADIR/treasures~" or die "$DATADIR/treasures~: $!"; print $fh $TRS; } { + print "processing facedata...\n" if $VERBOSE; while (my ($k, $v) = each %FACEINFO) { length $v->{data32} or warn "$k: face has no png32. this will not work (shoddy gcfclient will crash of course).\n"; length $v->{data64} or warn "$k: face has no png64. this will not work very well.\n"; @@ -634,8 +659,11 @@ $magicmap =~ y/A-Z_\-/a-z/d; $v->{magicmap} = $COLOR{$magicmap}; } + + delete $v->{arc}; } + print "writing facedata...\n" if $VERBOSE; open my $fh, ">:perlio", "$DATADIR/facedata~" or die "$DATADIR/facedata~: $!"; @@ -647,6 +675,8 @@ }; } + print "committing files...\n" if $VERBOSE; + for (qw(archetypes facedata treasures)) { chmod 0644, "$DATADIR/$_~"; rename "$DATADIR/$_~", "$DATADIR/$_"