1 | #! perl # mandatory |
1 | #! perl # mandatory |
2 | |
2 | |
3 | # player scheduler, evoking players from ram |
3 | # player scheduler, evoking players from ram |
4 | |
4 | |
5 | our $SCHEDULE_INTERVAL = $cf::CFG{player_schedule_interval} || 10; # time the player scheduler sleeps between runs |
5 | CONF SCHEDULE_INTERVAL : player_schedule_interval = 10; # time the player scheduler sleeps between runs |
6 | our $SAVE_TIMEOUT = $cf::CFG{player_save_interval} || 20; # save players every n seconds |
6 | CONF SAVE_TIMEOUT : player_save_interval = 20; # save players every n seconds |
7 | |
7 | |
8 | our $SCHEDULER = cf::async_ext { |
8 | our $SCHEDULER = cf::async_ext { |
9 | $Coro::current->{desc} = "player scheduler"; |
9 | $Coro::current->{desc} = "player scheduler"; |
10 | |
10 | |
11 | while () { |
11 | while () { |
12 | Coro::EV::timer_once $SCHEDULE_INTERVAL; |
12 | Coro::AnyEvent::sleep $SCHEDULE_INTERVAL; |
13 | |
13 | |
14 | # this weird form of iteration over values is used because |
14 | # this weird form of iteration over values is used because |
15 | # the hash changes underneath us frequently, and for |
15 | # the hash changes underneath us frequently, and for |
16 | # keeps a direct reference to the value without (in 5.8 perls) |
16 | # keeps a direct reference to the value without (in 5.8 perls) |
17 | # keeping a reference, so this is prone to crashes or worse. |
17 | # keeping a reference, so this is prone to crashes or worse. |
… | |
… | |
31 | |
31 | |
32 | my $pl_ref = $pl->refcnt_cnt; |
32 | my $pl_ref = $pl->refcnt_cnt; |
33 | my $ob_ref = $ob->refcnt_cnt; |
33 | my $ob_ref = $ob->refcnt_cnt; |
34 | |
34 | |
35 | ## pl_ref == (P)$pl + (P)%cf::PLAYER + (C)ob->contr |
35 | ## pl_ref == (P)$pl + (P)%cf::PLAYER + (C)ob->contr |
36 | ## ob_ref == (P)$ob + (C)pl->observe + (C)simply being an object |
36 | ## ob_ref == (P)$ob + (C)pl->observe + (C)pl->viewpoint + (C)simply being an object |
|
|
37 | ## !$pl->ns ensures that ob == viewpoint == observe |
37 | if ($pl_ref == 3 && $ob_ref == 3) { |
38 | if ($pl_ref == 3 && $ob_ref == 4) { |
38 | warn "player-scheduler destroy ", $ob->name;#d# |
39 | cf::trace "player-scheduler destroy ", $ob->name;#d# |
39 | |
40 | |
40 | # remove from sight and get fresh "copies" |
41 | # remove from sight and get fresh "copies" |
41 | $pl = delete $cf::PLAYER{$ob->name}; |
42 | $pl = delete $cf::PLAYER{$ob->name}; |
42 | $ob = $pl->ob; |
43 | $ob = $pl->ob; |
43 | |
44 | |
44 | $pl->destroy; # destroys $ob |
45 | $pl->destroy; # destroys $ob |
45 | } else { |
46 | } else { |
46 | my $a_ = $pl->refcnt;#d# |
47 | my $a_ = $pl->refcnt;#d# |
47 | my $b_ = $ob->refcnt;#d# |
48 | my $b_ = $ob->refcnt;#d# |
48 | |
49 | |
49 | warn "player-scheduler refcnt ", $ob->name, " pl $pl_ref/3 ob $ob_ref/3 (C pl $a_/1 ob $b_/2)\n";#d# |
50 | cf::debug "player-scheduler refcnt ", $ob->name, " pl $pl_ref/3 ob $ob_ref/3 (C pl $a_/1 ob $b_/2)\n";#d# |
50 | } |
51 | } |
51 | } |
52 | } |
52 | } |
53 | } |
53 | }; |
54 | }; |
54 | warn $@ if $@; |
55 | cf::error $@ if $@; |
|
|
56 | |
55 | cf::cede_to_tick; |
57 | cf::cede_to_tick; |
56 | }; |
58 | }; |
57 | } |
59 | } |
58 | }; |
60 | }; |
59 | |
61 | |