… | |
… | |
44 | our @EVENT; |
44 | our @EVENT; |
45 | our $LIBDIR = datadir . "/ext"; |
45 | our $LIBDIR = datadir . "/ext"; |
46 | |
46 | |
47 | our $TICK = MAX_TIME * 1e-6; |
47 | our $TICK = MAX_TIME * 1e-6; |
48 | our $TICK_WATCHER; |
48 | our $TICK_WATCHER; |
|
|
49 | our $AIO_POLL_WATCHER; |
|
|
50 | our $WRITE_RUNTIME_WATCHER; |
49 | our $NEXT_TICK; |
51 | our $NEXT_TICK; |
50 | our $NOW; |
52 | our $NOW; |
51 | |
53 | |
52 | our %CFG; |
54 | our %CFG; |
53 | |
55 | |
… | |
… | |
257 | } |
259 | } |
258 | |
260 | |
259 | sub freeze_mainloop { |
261 | sub freeze_mainloop { |
260 | return unless $TICK_WATCHER->is_active; |
262 | return unless $TICK_WATCHER->is_active; |
261 | |
263 | |
262 | my $guard = Coro::guard { $TICK_WATCHER->start }; |
264 | my $guard = Coro::guard { |
|
|
265 | $TICK_WATCHER->start; |
|
|
266 | $WRITE_RUNTIME_WATCHER->start; |
|
|
267 | }; |
|
|
268 | $WRITE_RUNTIME_WATCHER->stop; |
263 | $TICK_WATCHER->stop; |
269 | $TICK_WATCHER->stop; |
264 | $guard |
270 | $guard |
265 | } |
271 | } |
266 | |
272 | |
267 | =item cf::async { BLOCK } |
273 | =item cf::async { BLOCK } |
… | |
… | |
338 | |
344 | |
339 | $coro |
345 | $coro |
340 | } |
346 | } |
341 | |
347 | |
342 | sub write_runtime { |
348 | sub write_runtime { |
343 | return unless $TICK_WATCHER->is_active; |
|
|
344 | |
|
|
345 | my $runtime = cf::localdir . "/runtime"; |
349 | my $runtime = cf::localdir . "/runtime"; |
346 | |
350 | |
347 | my $fh = aio_open "$runtime~", O_WRONLY | O_CREAT, 0644 |
351 | my $fh = aio_open "$runtime~", O_WRONLY | O_CREAT, 0644 |
348 | or return; |
352 | or return; |
349 | |
353 | |
… | |
… | |
679 | # object support |
683 | # object support |
680 | |
684 | |
681 | sub reattach { |
685 | sub reattach { |
682 | # basically do the same as instantiate, without calling instantiate |
686 | # basically do the same as instantiate, without calling instantiate |
683 | my ($obj) = @_; |
687 | my ($obj) = @_; |
|
|
688 | |
|
|
689 | bless $obj, ref $obj; # re-bless in case extensions have been reloaded |
684 | |
690 | |
685 | my $registry = $obj->registry; |
691 | my $registry = $obj->registry; |
686 | |
692 | |
687 | @$registry = (); |
693 | @$registry = (); |
688 | |
694 | |
… | |
… | |
1494 | |
1500 | |
1495 | sub reset_at { |
1501 | sub reset_at { |
1496 | my ($self) = @_; |
1502 | my ($self) = @_; |
1497 | |
1503 | |
1498 | # TODO: safety, remove and allow resettable per-player maps |
1504 | # TODO: safety, remove and allow resettable per-player maps |
1499 | return 1e99 if $self->isa ("ext::map_per_player"); |
1505 | return 1e99 if $self->isa ("ext::map_per_player");#d# |
1500 | return 1e99 if $self->{deny_reset}; |
1506 | return 1e99 if $self->{deny_reset}; |
1501 | |
1507 | |
1502 | my $time = $self->fixed_resettime ? $self->{instantiate_time} : $self->last_access; |
1508 | my $time = $self->fixed_resettime ? $self->{instantiate_time} : $self->last_access; |
1503 | my $to = List::Util::min $MAX_RESET, $self->reset_timeout || $DEFAULT_RESET; |
1509 | my $to = List::Util::min $MAX_RESET, $self->reset_timeout || $DEFAULT_RESET; |
1504 | |
1510 | |
… | |
… | |
2402 | }, |
2408 | }, |
2403 | ); |
2409 | ); |
2404 | |
2410 | |
2405 | IO::AIO::max_poll_time $TICK * 0.2; |
2411 | IO::AIO::max_poll_time $TICK * 0.2; |
2406 | |
2412 | |
2407 | Event->io ( |
2413 | $AIO_POLL_WATCHER = Event->io ( |
2408 | fd => IO::AIO::poll_fileno, |
2414 | fd => IO::AIO::poll_fileno, |
2409 | poll => 'r', |
2415 | poll => 'r', |
2410 | prio => 5, |
2416 | prio => 5, |
2411 | data => WF_AUTOCANCEL, |
2417 | data => WF_AUTOCANCEL, |
2412 | cb => \&IO::AIO::poll_cb, |
2418 | cb => \&IO::AIO::poll_cb, |
2413 | ); |
2419 | ); |
2414 | |
2420 | |
2415 | Event->timer ( |
2421 | $WRITE_RUNTIME_WATCHER = Event->timer ( |
2416 | data => WF_AUTOCANCEL, |
2422 | data => WF_AUTOCANCEL, |
2417 | after => 0, |
2423 | after => 0, |
2418 | interval => 10, |
2424 | interval => 10, |
2419 | cb => sub { |
2425 | cb => sub { |
2420 | (Coro::unblock_sub { |
2426 | (Coro::unblock_sub { |