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.64 by root, Sun Sep 10 00:51:24 2006 UTC vs.
Revision 1.67 by root, Tue Sep 12 23:22:32 2006 UTC

642 load_extension $ext; 642 load_extension $ext;
643 1 643 1
644 } or warn "$ext not loaded: $@"; 644 } or warn "$ext not loaded: $@";
645 } 645 }
646} 646}
647
648sub _perl_reload(&) {
649 my ($msg) = @_;
650
651 $msg->("reloading...");
652
653 eval {
654 # 1. cancel all watchers
655 $_->cancel for Event::all_watchers;
656
657 # 2. unload all extensions
658 for (@exts) {
659 $msg->("unloading <$_>");
660 unload_extension $_;
661 }
662
663 # 3. unload all modules loaded from $LIBDIR
664 while (my ($k, $v) = each %INC) {
665 next unless $v =~ /^\Q$LIBDIR\E\/.*\.pm$/;
666
667 $msg->("removing <$k>");
668 delete $INC{$k};
669
670 $k =~ s/\.pm$//;
671 $k =~ s/\//::/g;
672
673 if (my $cb = $k->can ("unload_module")) {
674 $cb->();
675 }
676
677 Symbol::delete_package $k;
678 }
679
680 # 4. get rid of safe::, as good as possible
681 Symbol::delete_package "safe::$_"
682 for qw(cf::object cf::object::player cf::player cf::map cf::party cf::region);
683
684 # 5. remove register_script_function callbacks
685 # TODO
686
687 # 6. unload cf.pm "a bit"
688 delete $INC{"cf.pm"};
689
690 # don't, removes xs symbols, too,
691 # and global variables created in xs
692 #Symbol::delete_package __PACKAGE__;
693
694 # 7. reload cf.pm
695 $msg->("reloading cf.pm");
696 require cf;
697
698 $msg->("load extensions");
699 cf::load_extensions;
700
701 $msg->("reattach");
702 _global_reattach;
703 };
704 $msg->($@) if $@;
705
706 $msg->("reloaded");
707};
708
709sub perl_reload() {
710 _perl_reload {
711 warn $_[0];
712 print "$_[0]\n";
713 };
714}
715
716register_command "perl-reload", 0, sub {
717 my ($who, $arg) = @_;
718
719 if ($who->flag (FLAG_WIZ)) {
720 _perl_reload {
721 warn $_[0];
722 $who->message ($_[0]);
723 };
724 }
725};
726 647
727############################################################################# 648#############################################################################
728# extcmd framework, basically convert ext <msg> 649# extcmd framework, basically convert ext <msg>
729# into pkg::->on_extcmd_arg1 (...) while shortcutting a few 650# into pkg::->on_extcmd_arg1 (...) while shortcutting a few
730 651
895 no strict 'refs'; 816 no strict 'refs';
896 *{"safe::$fun"} = $safe_hole->wrap ($cb); 817 *{"safe::$fun"} = $safe_hole->wrap ($cb);
897} 818}
898 819
899############################################################################# 820#############################################################################
821
822=head2 EXTENSION DATABASE SUPPORT
823
824Crossfire maintains a very simple database for extension use. It can
825currently store anything that can be serialised using Storable, which
826excludes objects.
827
828The parameter C<$family> should best start with the name of the extension
829using it, it should be unique.
830
831=over 4
832
833=item $hashref = cf::db_get $family
834
835Return a hashref for use by the extension C<$family>, which can be
836modified. After modifications, you have to call C<cf::db_dirty> or
837C<cf::db_sync>.
838
839=item $value = cf::db_get $family => $key
840
841Returns a single value from the database
842
843=item cf::db_put $family => $hashref
844
845Stores the given family hashref into the database. Updates are delayed, if
846you want the data to be synced to disk immediately, use C<cf::db_sync>.
847
848=item cf::db_put $family => $key => $value
849
850Stores the given C<$value> in the family hash. Updates are delayed, if you
851want the data to be synced to disk immediately, use C<cf::db_sync>.
852
853=item cf::db_dirty
854
855Marks the database as dirty, to be updated at a later time.
856
857=item cf::db_sync
858
859Immediately write the database to disk I<if it is dirty>.
860
861=cut
862
863{
864 my $db;
865 my $path = cf::localdir . "/database.pst";
866
867 sub db_load() {
868 warn "loading database $path\n";#d# remove later
869 $db = stat $path ? Storable::retrieve $path : { };
870 }
871
872 my $pid;
873
874 sub db_save() {
875 warn "saving database $path\n";#d# remove later
876 waitpid $pid, 0 if $pid;
877 if (0 == ($pid = fork)) {
878 $db->{_meta}{version} = 1;
879 Storable::nstore $db, "$path~";
880 rename "$path~", $path;
881 kill 9, $$ if defined $pid; #d# remove when binary updated
882 cf::_exit 0 if defined $pid;
883 }
884 }
885
886 my $dirty;
887
888 sub db_sync() {
889 db_save if $dirty;
890 undef $dirty;
891 }
892
893 my $idle = Event->idle (min => $TICK * 2.8, max => 10, repeat => 0, cb => sub {
894 db_sync;
895 });
896
897 sub db_dirty() {
898 $dirty = 1;
899 $idle->start;
900 }
901
902 sub db_get($;$) {
903 @_ >= 2
904 ? $db->{$_[0]}{$_[1]}
905 : ($db->{$_[0]} ||= { })
906 }
907
908 sub db_put($$;$) {
909 if (@_ >= 3) {
910 $db->{$_[0]}{$_[1]} = $_[2];
911 } else {
912 $db->{$_[0]} = $_[1];
913 }
914 db_dirty;
915 }
916
917 attach_global
918 prio => 10000,
919 on_cleanup => sub {
920 db_sync;
921 },
922 ;
923}
924
925#############################################################################
900# the server's main() 926# the server's main()
901 927
902sub main { 928sub main {
929 db_load;
903 load_extensions; 930 load_extensions;
904 Event::loop; 931 Event::loop;
905} 932}
906 933
907############################################################################# 934#############################################################################
908# initialisation 935# initialisation
936
937sub _perl_reload(&) {
938 my ($msg) = @_;
939
940 $msg->("reloading...");
941
942 eval {
943 # cancel all watchers
944 $_->cancel for Event::all_watchers;
945
946 # unload all extensions
947 for (@exts) {
948 $msg->("unloading <$_>");
949 unload_extension $_;
950 }
951
952 # unload all modules loaded from $LIBDIR
953 while (my ($k, $v) = each %INC) {
954 next unless $v =~ /^\Q$LIBDIR\E\/.*\.pm$/;
955
956 $msg->("removing <$k>");
957 delete $INC{$k};
958
959 $k =~ s/\.pm$//;
960 $k =~ s/\//::/g;
961
962 if (my $cb = $k->can ("unload_module")) {
963 $cb->();
964 }
965
966 Symbol::delete_package $k;
967 }
968
969 # sync database to disk
970 cf::db_sync;
971
972 # get rid of safe::, as good as possible
973 Symbol::delete_package "safe::$_"
974 for qw(cf::object cf::object::player cf::player cf::map cf::party cf::region);
975
976 # remove register_script_function callbacks
977 # TODO
978
979 # unload cf.pm "a bit"
980 delete $INC{"cf.pm"};
981
982 # don't, removes xs symbols, too,
983 # and global variables created in xs
984 #Symbol::delete_package __PACKAGE__;
985
986 # reload cf.pm
987 $msg->("reloading cf.pm");
988 require cf;
989
990 # load database again
991 cf::db_load;
992
993 # load extensions
994 $msg->("load extensions");
995 cf::load_extensions;
996
997 # reattach attachments to objects
998 $msg->("reattach");
999 _global_reattach;
1000 };
1001 $msg->($@) if $@;
1002
1003 $msg->("reloaded");
1004};
1005
1006sub perl_reload() {
1007 _perl_reload {
1008 warn $_[0];
1009 print "$_[0]\n";
1010 };
1011}
1012
1013register_command "perl-reload", 0, sub {
1014 my ($who, $arg) = @_;
1015
1016 if ($who->flag (FLAG_WIZ)) {
1017 _perl_reload {
1018 warn $_[0];
1019 $who->message ($_[0]);
1020 };
1021 }
1022};
909 1023
910register "<global>", __PACKAGE__; 1024register "<global>", __PACKAGE__;
911 1025
912unshift @INC, $LIBDIR; 1026unshift @INC, $LIBDIR;
913 1027

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines