--- deliantra/server/lib/cf.pm 2007/01/09 21:32:42 1.155 +++ deliantra/server/lib/cf.pm 2007/01/10 01:16:54 1.157 @@ -1441,10 +1441,34 @@ $self->in_memory (cf::MAP_IN_MEMORY); } +# find and load all maps in the 3x3 area around a map +sub load_diag { + my ($map) = @_; + + my @diag; # diagonal neighbours + + for (0 .. 3) { + my $neigh = $map->tile_path ($_) + or next; + $neigh = find $neigh, $map + or next; + $neigh->load; + + push @diag, [$neigh->tile_path (($_ + 3) % 4), $neigh], + [$neigh->tile_path (($_ + 1) % 4), $neigh]; + } + + for (@diag) { + my $neigh = find @$_ + or next; + $neigh->load; + } +} + sub find_sync { my ($path, $origin) = @_; - cf::sync_job { cf::map::find $path, $origin } + cf::sync_job { find $path, $origin } } sub do_load_sync { @@ -1453,6 +1477,38 @@ cf::sync_job { $map->load }; } +our %MAP_PREFETCH; +our $MAP_PREFETCHER = Coro::async { + while () { + while (%MAP_PREFETCH) { + my $key = each %MAP_PREFETCH + or next; + my $path = delete $MAP_PREFETCH{$key}; + + my $map = find $path + or next; + $map->load; + } + Coro::schedule; + } +}; + +sub find_async { + my ($path, $origin) = @_; + + $path = new cf::path $path, $origin && $origin->path; + my $key = $path->as_string; + + if (my $map = $cf::MAP{$key}) { + return $map if $map->in_memory == cf::MAP_IN_MEMORY; + } + + $MAP_PREFETCH{$key} = $path; + $MAP_PREFETCHER->ready; + + () +} + sub save { my ($self) = @_; @@ -1709,6 +1765,7 @@ if $x <=0 && $y <= 0; $map->load; + $map->load_diag; return unless $self->contr->active; $self->activate_recursive; @@ -2220,7 +2277,7 @@ } } -sub emergency_save { +sub emergency_save() { my $freeze_guard = cf::freeze_mainloop; warn "enter emergency perl save\n";