ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/00_map_handling.ext
(Generate patch)

Comparing deliantra/server/ext/00_map_handling.ext (file contents):
Revision 1.1 by root, Sat Dec 30 10:16:10 2006 UTC vs.
Revision 1.4 by root, Sat Dec 30 16:56:16 2006 UTC

130 and return; 130 and return;
131 131
132 1 132 1
133} 133}
134 134
135(Coro::unblock_sub { 135(Coro::async {
136 unless (write_runtime) { 136 unless (write_runtime) {
137 warn "unable to write runtime file: $!"; 137 warn "unable to write runtime file: $!";
138 exit 1; 138 exit 1;
139 } 139 }
140})->(); 140})->prio (Coro::PRIO_MAX);
141 141
142our $SCHEDULER = cf::coro { 142our $SCHEDULER = cf::coro {
143 while () { 143 while () {
144 Coro::Timer::sleep $SCHEDULE_INTERVAL; 144 Coro::Timer::sleep $SCHEDULE_INTERVAL;
145 145
181 181
182 Carp::confess "nested sync_job" if $cf::FREEZE; 182 Carp::confess "nested sync_job" if $cf::FREEZE;
183 183
184 local $cf::FREEZE = 1; 184 local $cf::FREEZE = 1;
185 185
186 (async { 186 (Coro::async {
187 @res = eval { $job->() }; 187 @res = eval { $job->() };
188 warn $@ if $@; 188 warn $@ if $@;
189 $done = 1; 189 $done = 1;
190 })->prio (Coro::PRIO_MAX); 190 })->prio (Coro::PRIO_MAX);
191 191
192 while (!$done) { 192 while (!$done) {
193 Coro::cede_notself; 193 Coro::cede_notself;
194 Event::one_event unless Coro::nready; 194 Event::one_event unless Coro::nready;
195 } 195 }
196 196
197 warn "job done<@res>\n";#d#
198
199 wantarray ? @res : $res[0] 197 wantarray ? @res : $res[0]
200} 198}
201 199
202# and all this just because we cannot iterate over 200# and all this just because we cannot iterate over
203# all maps in C++... 201# all maps in C++...
222 220
223 $map->reset_time (0) if $map->reset_time > $cf::RUNTIME; 221 $map->reset_time (0) if $map->reset_time > $cf::RUNTIME;
224 $map->reset_timeout (10);#d# 222 $map->reset_timeout (10);#d#
225 223
226 $map->{load_path} = $path; 224 $map->{load_path} = $path;
227 warn "load header from $path\n";#d#
228 225
229 $map 226 $map
230} 227}
231 228
232sub cf::map::find_map_nb { 229sub cf::map::find_map_nb {
233 my ($path, $origin) = @_; 230 my ($path, $origin) = @_;
234 231
232 warn "find_map_nb<$path,$origin>\n";#d#
233
235 $path = ref $path ? $path : new cf::path $path, $origin && $origin->path; 234 $path = ref $path ? $path : new cf::path $path, $origin && $origin->path;
236 my $key = $path->as_string; 235 my $key = $path->as_string;
237
238 warn "find_map_nb<$path,$origin>\n";#d#
239 236
240 $cf::MAP{$key} || do { 237 $cf::MAP{$key} || do {
241 # do it the slow way 238 # do it the slow way
242 my $map = try_load_header $path->save_path; 239 my $map = try_load_header $path->save_path;
243 240
249 $map or return; 246 $map or return;
250 247
251 $map->instantiate; 248 $map->instantiate;
252 $map->path ($key); 249 $map->path ($key);
253 $map->{path} = $path; 250 $map->{path} = $path;
251
252 $map->per_player (0) if $path->{user_rel};
254 253
255 $map->reset if $map->should_reset; 254 $map->reset if $map->should_reset;
256 255
257 $cf::MAP{$key} = $map 256 $cf::MAP{$key} = $map
258 } 257 }
331 330
332 $self->{load_path} = $save; 331 $self->{load_path} = $save;
333 $self->{last_save} = $cf::RUNTIME; 332 $self->{last_save} = $cf::RUNTIME;
334} 333}
335 334
335sub cf::map::swap_out {
336 my ($self) = @_;
337
338 $self->save if $self->in_memory == cf::MAP_IN_MEMORY;
339 $self->clear;
340 $self->in_memory (cf::MAP_SWAPPED);
341}
342
336sub cf::map::should_reset { 343sub cf::map::should_reset {
337 my ($map) = @_; 344 my ($map) = @_;
338 345
339 # TODO: safety, remove and allow resettable per-player maps 346 # TODO: safety, remove and allow resettable per-player maps
340 return if $map->{path}{user_rel};#d# 347 return if $map->{path}{user_rel};#d#
348 355
349sub cf::map::reset { 356sub cf::map::reset {
350 my ($self) = @_; 357 my ($self) = @_;
351 358
352 return if $self->players; 359 return if $self->players;
360 return if $self->{path}{user_rel};#d#
353 361
354 warn "resetting map ", $self->path;#d# 362 warn "resetting map ", $self->path;#d#
355 return;#d# 363
364 utf8::encode (my $save = $self->{path}->save_path);
365 aioreq_pri 3; IO::AIO::aio_unlink $save;
366 aioreq_pri 3; IO::AIO::aio_unlink "$save.pst";
356 367
357 $self->clear; 368 $self->clear;
358 $self->in_memory (cf::MAP_SWAPPED); 369 $self->in_memory (cf::MAP_SWAPPED);
359 $self->{load_path} = $self->{path}->load_path; 370 utf8::encode ($self->{load_path} = $self->{path}->load_path);
360 utf8::encode $self->{load_path};
361}
362
363sub cf::map::swap_out {
364 my ($self) = @_;
365
366 $self->save;
367 $self->clear;
368 $self->in_memory (cf::MAP_SWAPPED);
369} 371}
370 372
371sub cf::object::player::enter_exit { 373sub cf::object::player::enter_exit {
372 my ($ob, $exit) = @_; 374 my ($ob, $exit) = @_;
373 375
374 warn "enter_exit\n";#d# 376 # if at login, move to interim map immediately
377 unless ($exit) {
378 # used on login only
379 $ob->enter_map ($LINK_MAP, 0, 0);
380 }
381
382 #TODO: do this in the background, freeze the player if required
375 sync_job { 383 sync_job {
376 warn "enter_exit<$ob,$exit>\n";#d# 384 my ($map, $x, $y);
377 385
378 if ($exit) { 386 unless ($exit) {
387 # used on login only(?)
388 $map = cf::map::find_map_nb $ob->contr->maplevel;
389 ($x, $y) = ($ob->x, $ob->y);
390 } else {
379 my $path = new cf::path $exit->slaying, $exit->map && $exit->map->path; 391 my $path = new cf::path $exit->slaying, $exit->map && $exit->map->path;
380 392
381 my $map = cf::map::find_map_nb $path->as_string; 393 $map = cf::map::find_map_nb $path->as_string;
382 $map = $map->customise_for ($ob) if $map; 394 $map = $map->customise_for ($ob) if $map;
383
384 if ($map) {
385 $map->do_load_nb;
386 $ob->enter_map ($map, $exit->stats->hp, $exit->stats->sp); 395 ($x, $y) = ($exit->stats->hp, $exit->stats->sp);
387 } else {
388 $ob->message ("The exit is closed", cf::NDI_UNIQUE | cf::NDI_RED);
389 } 396 }
390 } else {
391 # used on login only(?)
392 my $map = cf::map::find_map_nb $ob->contr->maplevel;
393 my ($x, $y) = ($ob->x, $ob->y);
394 397
395 unless ($map) { 398 unless ($map) {
396 $map = cf::map::find_map_nb $emergency_position->[0] 399 $map = cf::map::find_map_nb $emergency_position->[0]
397 or die "FATAL: cannot load emergency map\n"; 400 or die "FATAL: cannot load emergency map\n";
398 $x = $emergency_position->[1]; 401 $x = $emergency_position->[1];
399 $y = $emergency_position->[2]; 402 $y = $emergency_position->[2];
400 } 403 }
401 404
405 if ($map) {
406 warn "entering ", $map->path, " at ($x, $y)\n";#d#
402 $map->do_load_nb; 407 $map->do_load_nb;
403 $ob->enter_map ($map, $x, $y); 408 $ob->enter_map ($map, $x, $y);
409 } else {
410 $ob->message ("The exit is closed", cf::NDI_UNIQUE | cf::NDI_RED);
404 } 411 }
405 } 412 }
406} 413}
407 414
408sub cf::map::customise_for { 415sub cf::map::customise_for {
409 my ($map, $ob) = @_; 416 my ($map, $ob) = @_;
410 417
411 warn "customise_for<$map,$ob>\n";#d#
412
413 if ($map->per_player) { 418 if ($map->per_player) {
414 return cf::map::find_map_nb "~" . $ob->name . "/" . $map->{path}{path}; 419 return cf::map::find_map_nb "~" . $ob->name . "/" . $map->{path}{path};
415 } 420 }
416 421
417 $map 422 $map
418} 423}
419 424
420sub cf::map::emergency_save { 425sub cf::map::emergency_save {
421 local $cf::FREEZE = 1; 426 local $cf::FREEZE = 1;
422 427
428 warn "enter emergency map save\n";
429
430 my $saver = async {
423 warn "begin emergency map save\n"; 431 warn "begin emergency map save\n";
424 $_->save for values %cf::MAP; 432 $_->save for values %cf::MAP;
433 };
434 $saver->prio (Coro::PRIO_MAX);
435 $saver->join;
436
425 warn "emergency map save drain\n"; 437 warn "emergency map save drain\n";
426
427 Event::one_event while IO::AIO::nreqs; 438 Event::one_event while IO::AIO::nreqs;
428 warn "end emergency map save\n"; 439 warn "end emergency map save\n";
429} 440}
430 441

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines