ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/cf.pm
(Generate patch)

Comparing deliantra/server/lib/cf.pm (file contents):
Revision 1.600 by root, Sun Nov 11 04:31:57 2012 UTC vs.
Revision 1.601 by root, Sun Nov 11 05:53:12 2012 UTC

2654 2654
2655Creates and returns a persistent reference to an object that can be stored as a string. 2655Creates and returns a persistent reference to an object that can be stored as a string.
2656 2656
2657=item $ob = cf::object::deref ($refstring) 2657=item $ob = cf::object::deref ($refstring)
2658 2658
2659returns the objetc referenced by refstring. may return undef when it cnanot find the object, 2659returns the objetc referenced by refstring. may return undef when it cannot find the object,
2660even if the object actually exists. May block. 2660even if the object actually exists. May block.
2661 2661
2662=cut 2662=cut
2663 2663
2664sub deref { 2664sub deref {
3519=cut 3519=cut
3520 3520
3521############################################################################# 3521#############################################################################
3522# the server's init and main functions 3522# the server's init and main functions
3523 3523
3524our %FACEHASH; # hash => idx, #d# HACK for http server 3524{
3525our @FACEDATA; # dynamically-created facedata 3525 package cf::face;
3526 3526
3527 our %HASH; # hash => idx
3528 our @DATA; # dynamically-created facedata, only faceste 0 used
3529 our @FOFS; # file offset, if > 0
3530 our @SIZE; # size of face, in octets
3531 our @META; # meta hash of face, if any
3532 our $DATAFH; # facedata filehandle
3533
3527# internal api, not fianlised 3534 # internal api, not finalised
3528sub set_face { 3535 sub set {
3529 my ($name, $type, $data) = @_; 3536 my ($name, $type, $data) = @_;
3530 3537
3531 my $idx = cf::face::find $name; 3538 my $idx = cf::face::find $name;
3532 3539
3533 if ($idx) { 3540 if ($idx) {
3534 delete $FACEHASH{cf::face::get_chksum $idx}; 3541 delete $HASH{cf::face::get_chksum $idx};
3535 } else { 3542 } else {
3536 $idx = cf::face::alloc $name; 3543 $idx = cf::face::alloc $name;
3537 } 3544 }
3538 3545
3539 my $hash = cf::face::mangle_chksum Digest::MD5::md5 $data; 3546 my $hash = cf::face::mangle_csum Digest::MD5::md5 $data;
3540 3547
3541 cf::face::set_type $idx, $type; 3548 cf::face::set_type $idx, $type;
3542 cf::face::set_data $idx, 0, (length $data), 0, $hash; 3549 cf::face::set_csum $idx, 0, $hash;
3543 cf::face::set_meta $idx, $type & 1 ? undef : undef;
3544 3550
3545 # we need to destroy the SV itself, not just overwrite, 3551 # we need to destroy the SV itself, not just modify it, as a running ix
3546 # as a running ix might hold a reference to it. 3552 # might hold a reference to it: "delete" achieves that.
3547 # delete achieves that. 3553 delete $FOFS[0][$idx];
3554 delete $DATA[0][$idx];
3555 $DATA[0][$idx] = $data;
3556 $SIZE[0][$idx] = length $data;
3548 delete $FACEDATA[$idx]; 3557 delete $META[$idx];
3549 $FACEDATA[$idx] = $data;
3550 $FACEHASH{$hash} = $idx;#d# 3558 $HASH{$hash} = $idx;#d#
3551 3559
3552 $idx 3560 $idx
3553} 3561 }
3554 3562
3555our $FACEDATA; # facedata filehandle
3556
3557sub _face_get_data($$$$) { 3563 sub _get_data($$$) {
3558 my ($idx, $size, $fofs, $cb) = @_; 3564 my ($idx, $set, $cb) = @_;
3559 3565
3560 if (defined $FACEDATA[$idx]) { 3566 if (defined $DATA[$set][$idx]) {
3561 $cb->($FACEDATA[$idx]); 3567 $cb->($DATA[$set][$idx]);
3562 } elsif ($fofs) { 3568 } elsif (my $fofs = $FOFS[$set][$idx]) {
3569 my $size = $SIZE[$set][$idx];
3563 my $buf; 3570 my $buf;
3564 IO::AIO::aio_read $FACEDATA, $fofs, $size, $buf, 0, sub { 3571 IO::AIO::aio_read $DATAFH, $fofs, $size, $buf, 0, sub {
3565 if ($_[0] == $size) { 3572 if ($_[0] == $size) {
3566 #cf::debug "read face $idx, $size from $fofs as ", length $buf;#d# 3573 #cf::debug "read face $idx, $size from $fofs as ", length $buf;#d#
3567 $cb->($buf); 3574 $cb->($buf);
3568 } else { 3575 } else {
3569 cf::error "INTERNAL ERROR: unable to read facedata for face $idx ($size, $fofs), ignoring request."; 3576 cf::error "INTERNAL ERROR: unable to read facedata for face $idx#$set ($size, $fofs), ignoring request.";
3577 }
3570 } 3578 };
3579 } else {
3580 cf::error "requested facedata for unknown face $idx#$set, ignoring.";
3581 }
3582 }
3583
3584 # rather ineffient
3585 sub cf::face::get_data($;$) {
3586 my ($idx, $set) = @_;
3587
3588 _get_data $idx, $set, Coro::rouse_cb;
3589 Coro::rouse_wait
3590 }
3591
3592 sub cf::face::ix {
3593 my ($ns, $set, $idx, $pri) = @_;
3594
3595 _get_data $idx, $set, sub {
3596 $ns->ix_send ($idx, $pri, $_[0]);
3571 }; 3597 };
3572 } else {
3573 cf::error "requested facedata for unknown face $idx ($size, $fofs), ignoring.";
3574 }
3575}
3576
3577# rather ineffient
3578sub cf::face::get_data($;$) {
3579 my ($idx, $faceset) = @_;
3580
3581 my $size = cf::face::get_size $idx, $faceset;
3582 my $fofs = cf::face::get_fofs $idx, $faceset;
3583
3584 _face_get_data $idx, $size, $fofs, Coro::rouse_cb;
3585 Coro::rouse_wait
3586}
3587
3588sub cf::face::ix {
3589 my ($ns, $idx, $pri, $size, $fofs) = @_;
3590
3591 _face_get_data $idx, $size, $fofs, sub {
3592 $ns->ix_send ($idx, $pri, $_[0]);
3593 }; 3598 }
3594} 3599}
3595 3600
3596sub load_facedata($) { 3601sub load_facedata($) {
3597 my ($path) = @_; 3602 my ($path) = @_;
3598 3603
3604 3609
3605 $facedata->{version} == 2 3610 $facedata->{version} == 2
3606 or cf::cleanup "$path/faceinfo: version mismatch, cannot proceed."; 3611 or cf::cleanup "$path/faceinfo: version mismatch, cannot proceed.";
3607 3612
3608 my $fh = aio_open "$DATADIR/facedata", IO::AIO::O_RDONLY, 0 3613 my $fh = aio_open "$DATADIR/facedata", IO::AIO::O_RDONLY, 0
3609 or cf::cleanup "$path/facedata: $!, cnanot proceed."; 3614 or cf::cleanup "$path/facedata: $!, cannot proceed.";
3610 3615
3611 get_slot 1, -100, "load_facedata"; # make sure we get a very big slot 3616 get_slot 1, -100, "load_facedata"; # make sure we get a very big slot
3612 3617
3613 # BEGIN ATOMIC 3618 # BEGIN ATOMIC
3614 # from here on, everything must be atomic - no thread switch allowed 3619 # from here on, everything must be atomic - no thread switch allowed
3621 my $info = $faces->{$face}; 3626 my $info = $faces->{$face};
3622 my $idx = (cf::face::find $face) || cf::face::alloc $face; 3627 my $idx = (cf::face::find $face) || cf::face::alloc $face;
3623 3628
3624 cf::face::set_visibility $idx, $info->{visibility}; 3629 cf::face::set_visibility $idx, $info->{visibility};
3625 cf::face::set_magicmap $idx, $info->{magicmap}; 3630 cf::face::set_magicmap $idx, $info->{magicmap};
3626 cf::face::set_data $idx, 0, $info->{size32}, $info->{fofs32}, $info->{hash32}; 3631 cf::face::set_csum $idx, 0, $info->{hash64}; $cf::face::SIZE[0][$idx] = $info->{size64}; $cf::face::FOFS[0][$idx] = $info->{fofs64};
3627 cf::face::set_data $idx, 1, $info->{size64}, $info->{fofs64}, $info->{hash64}; 3632 cf::face::set_csum $idx, 1, $info->{hash32}; $cf::face::SIZE[1][$idx] = $info->{size32}; $cf::face::FOFS[1][$idx] = $info->{fofs32};
3628 #cf::face::set_data $idx, 2, $info->{glyph} , $info->{glyph}; # glyphs no longer downloadable via ix 3633 #cf::face::set_data $idx, 2, $info->{glyph} , $info->{glyph}; # glyphs no longer downloadable via ix
3629 $FACEHASH{$info->{hash64}} = $idx;#d# 3634 $cf::face::HASH{$info->{hash64}} = $idx;
3635 delete $cf::face::META[$idx];
3630 } 3636 }
3631 3637
3632 while (my ($face, $info) = each %$faces) { 3638 while (my ($face, $info) = each %$faces) {
3633 next unless $info->{smooth}; 3639 next unless $info->{smooth};
3634 3640
3661 if (defined (my $type = $info->{type})) { 3667 if (defined (my $type = $info->{type})) {
3662 # TODO: different hash - must free and use new index, or cache ixface data queue 3668 # TODO: different hash - must free and use new index, or cache ixface data queue
3663 my $idx = (cf::face::find $name) || cf::face::alloc $name; 3669 my $idx = (cf::face::find $name) || cf::face::alloc $name;
3664 3670
3665 cf::face::set_type $idx, $type; 3671 cf::face::set_type $idx, $type;
3666 cf::face::set_data $idx, 0, $info->{size}, $info->{fofs}, $info->{hash}; 3672 cf::face::set_csum $idx, 0, $info->{hash};
3673 $cf::face::SIZE[0][$idx] = $info->{size};
3674 $cf::face::FOFS[0][$idx] = $info->{fofs};
3667 cf::face::set_meta $idx, $type & 1 ? undef : $info->{meta}; # preserve meta unless prepended already 3675 $cf::face::META[$idx] = $type & 1 ? undef : $info->{meta}; # preserve meta unless prepended already
3668 $FACEHASH{$info->{hash}} = $idx;#d# 3676 $cf::face::HASH{$info->{hash}} = $idx;
3669 } else { 3677 } else {
3670# $RESOURCE{$name} = $info; # unused 3678# $RESOURCE{$name} = $info; # unused
3671 } 3679 }
3672 } 3680 }
3673 } 3681 }
3674 3682
3675 ($fh, $FACEDATA) = ($FACEDATA, $fh); 3683 ($fh, $cf::face::DATAFH) = ($cf::face::DATAFH, $fh);
3676 3684
3677 # HACK to clear player env face cache, we need some signal framework 3685 # HACK to clear player env face cache, we need some signal framework
3678 # for this (global event?) 3686 # for this (global event?)
3679 %ext::player_env::MUSIC_FACE_CACHE = (); 3687 %ext::player_env::MUSIC_FACE_CACHE = ();
3680 3688
3708} 3716}
3709 3717
3710sub reload_exp_table { 3718sub reload_exp_table {
3711 _reload_exp_table; 3719 _reload_exp_table;
3712 3720
3721 cf::face::set
3713 set_face "res/exp_table" => FT_RSRC, 3722 "res/exp_table" => FT_RSRC,
3714 JSON::XS->new->utf8->canonical->encode ( 3723 JSON::XS->new->utf8->canonical->encode (
3715 [map cf::level_to_min_exp $_, 1 .. cf::settings->max_level] 3724 [map cf::level_to_min_exp $_, 1 .. cf::settings->max_level]
3716 ); 3725 );
3717} 3726}
3718 3727
3719sub reload_materials { 3728sub reload_materials {
3720 _reload_materials; 3729 _reload_materials;
3721} 3730}
3741 3750
3742sub reload_archetypes { 3751sub reload_archetypes {
3743 load_resource_file "$DATADIR/archetypes" 3752 load_resource_file "$DATADIR/archetypes"
3744 or die "unable to load archetypes\n"; 3753 or die "unable to load archetypes\n";
3745 3754
3755 cf::face::set
3746 set_face "res/skill_info" => FT_RSRC, 3756 "res/skill_info" => FT_RSRC,
3747 JSON::XS->new->utf8->canonical->encode ( 3757 JSON::XS->new->utf8->canonical->encode (
3748 [map [cf::arch::skillvec ($_)->name], 0 .. cf::arch::skillvec_size - 1] 3758 [map [cf::arch::skillvec ($_)->name], 0 .. cf::arch::skillvec_size - 1]
3749 ); 3759 );
3760
3761 cf::face::set
3750 set_face "res/spell_paths" => FT_RSRC, 3762 "res/spell_paths" => FT_RSRC,
3751 JSON::XS->new->utf8->canonical->encode ( 3763 JSON::XS->new->utf8->canonical->encode (
3752 [map [cf::spellpathnames ($_)], 0 .. NRSPELLPATHS - 1] 3764 [map [cf::spellpathnames ($_)], 0 .. NRSPELLPATHS - 1]
3753 ); 3765 );
3754} 3766}
3755 3767
3756sub reload_treasures { 3768sub reload_treasures {
3757 load_resource_file "$DATADIR/treasures" 3769 load_resource_file "$DATADIR/treasures"
3758 or die "unable to load treasurelists\n"; 3770 or die "unable to load treasurelists\n";

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines