… | |
… | |
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 | our $SCHEDULE_INTERVAL = $cf::CFG{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 | our $SAVE_TIMEOUT = $cf::CFG{player_save_interval} || 20; # save players every n seconds |
7 | |
7 | |
8 | cf::player->attach ( |
|
|
9 | on_load => sub { |
|
|
10 | my ($pl, $path) = @_; |
|
|
11 | |
|
|
12 | my $slots = delete $pl->{_slots}; |
|
|
13 | |
|
|
14 | $pl->ob->current_weapon ($slots->[0]); |
|
|
15 | $pl->combat_ob ($slots->[1]); |
|
|
16 | $pl->ranged_ob ($slots->[2]); |
|
|
17 | }, |
|
|
18 | on_save => sub { |
|
|
19 | my ($pl, $path) = @_; |
|
|
20 | $pl->{_slots} = [$pl->ob->current_weapon, $pl->combat_ob, $pl->ranged_ob]; |
|
|
21 | }, |
|
|
22 | ); |
|
|
23 | |
|
|
24 | our $SCHEDULER = cf::async_ext { |
8 | our $SCHEDULER = cf::async_ext { |
25 | $Coro::current->{desc} = "player scheduler"; |
9 | $Coro::current->{desc} = "player scheduler"; |
26 | |
10 | |
27 | while () { |
11 | while () { |
28 | Coro::EV::timer_once $SCHEDULE_INTERVAL; |
12 | Coro::AnyEvent::sleep $SCHEDULE_INTERVAL; |
29 | |
13 | |
30 | # this weird form of iteration over values is used because |
14 | # this weird form of iteration over values is used because |
31 | # the hash changes underneath us frequently, and for |
15 | # the hash changes underneath us frequently, and for |
32 | # 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) |
33 | # keeping a reference, so this is prone to crashes or worse. |
17 | # keeping a reference, so this is prone to crashes or worse. |
… | |
… | |
50 | |
34 | |
51 | ## pl_ref == (P)$pl + (P)%cf::PLAYER + (C)ob->contr |
35 | ## pl_ref == (P)$pl + (P)%cf::PLAYER + (C)ob->contr |
52 | ## ob_ref == (P)$ob + (C)pl->observe + (C)pl->viewpoint + (C)simply being an object |
36 | ## ob_ref == (P)$ob + (C)pl->observe + (C)pl->viewpoint + (C)simply being an object |
53 | ## !$pl->ns ensures that ob == viewpoint == observe |
37 | ## !$pl->ns ensures that ob == viewpoint == observe |
54 | if ($pl_ref == 3 && $ob_ref == 4) { |
38 | if ($pl_ref == 3 && $ob_ref == 4) { |
55 | warn "player-scheduler destroy ", $ob->name;#d# |
39 | cf::trace "player-scheduler destroy ", $ob->name;#d# |
56 | |
40 | |
57 | # remove from sight and get fresh "copies" |
41 | # remove from sight and get fresh "copies" |
58 | $pl = delete $cf::PLAYER{$ob->name}; |
42 | $pl = delete $cf::PLAYER{$ob->name}; |
59 | $ob = $pl->ob; |
43 | $ob = $pl->ob; |
60 | |
44 | |
61 | $pl->destroy; # destroys $ob |
45 | $pl->destroy; # destroys $ob |
62 | } else { |
46 | } else { |
63 | my $a_ = $pl->refcnt;#d# |
47 | my $a_ = $pl->refcnt;#d# |
64 | my $b_ = $ob->refcnt;#d# |
48 | my $b_ = $ob->refcnt;#d# |
65 | |
49 | |
66 | 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# |
67 | } |
51 | } |
68 | } |
52 | } |
69 | } |
53 | } |
70 | }; |
54 | }; |
71 | warn $@ if $@; |
55 | cf::error $@ if $@; |
|
|
56 | |
72 | cf::cede_to_tick; |
57 | cf::cede_to_tick; |
73 | }; |
58 | }; |
74 | } |
59 | } |
75 | }; |
60 | }; |
76 | |
61 | |