ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/cf.pm
(Generate patch)

Comparing deliantra/server/lib/cf.pm (file contents):
Revision 1.307 by root, Sun Jul 15 22:39:48 2007 UTC vs.
Revision 1.315 by root, Mon Jul 23 17:53:55 2007 UTC

166=item cf::wait_for_tick, cf::wait_for_tick_begin 166=item cf::wait_for_tick, cf::wait_for_tick_begin
167 167
168These are functions that inhibit the current coroutine one tick. cf::wait_for_tick_begin only 168These are functions that inhibit the current coroutine one tick. cf::wait_for_tick_begin only
169returns directly I<after> the tick processing (and consequently, can only wake one process 169returns directly I<after> the tick processing (and consequently, can only wake one process
170per tick), while cf::wait_for_tick wakes up all waiters after tick processing. 170per tick), while cf::wait_for_tick wakes up all waiters after tick processing.
171
172=item @cf::INVOKE_RESULTS
173
174This array contains the results of the last C<invoke ()> call. When
175C<cf::override> is called C<@cf::INVOKE_RESULTS> is set to the parameters of
176that call.
171 177
172=back 178=back
173 179
174=cut 180=cut
175 181
316 }; 322 };
317 $TICK_WATCHER->stop; 323 $TICK_WATCHER->stop;
318 $guard 324 $guard
319} 325}
320 326
327=item cf::get_slot $time[, $priority[, $name]]
328
329Allocate $time seconds of blocking CPU time at priority C<$priority>:
330This call blocks and returns only when you have at least C<$time> seconds
331of cpu time till the next tick. The slot is only valid till the next cede.
332
333The optional C<$name> can be used to identify the job to run. It might be
334used for statistical purposes and should identify the same time-class.
335
336Useful for short background jobs.
337
338=cut
339
340our @SLOT_QUEUE;
341our $SLOT_QUEUE;
342
343$SLOT_QUEUE->cancel if $SLOT_QUEUE;
344$SLOT_QUEUE = Coro::async {
345 my $signal = new Coro::Signal;
346
347 while () {
348 next_job:
349 my $avail = cf::till_tick;
350 if ($avail > 0.01) {
351 for (0 .. $#SLOT_QUEUE) {
352 if ($SLOT_QUEUE[$_][0] < $avail) {
353 my $job = splice @SLOT_QUEUE, $_, 1, ();
354 $job->[2]->send;
355 Coro::cede;
356 goto next_job;
357 }
358 }
359 }
360
361 if (@SLOT_QUEUE) {
362 # we do not use wait_For_tick() as it returns immediately when tick is inactive
363 push @cf::WAIT_FOR_TICK, $signal;
364 $signal->wait;
365 } else {
366 Coro::schedule;
367 }
368 }
369};
370
371sub get_slot($;$$) {
372 my ($time, $pri, $name) = @_;
373
374 $time = $TICK * .6 if $time > $TICK * .6;
375 my $sig = new Coro::Signal;
376
377 push @SLOT_QUEUE, [$time, $pri, $sig, $name];
378 @SLOT_QUEUE = sort { $b->[1] <=> $a->[1] } @SLOT_QUEUE;
379 $SLOT_QUEUE->ready;
380 $sig->wait;
381}
382
321=item cf::async { BLOCK } 383=item cf::async { BLOCK }
322 384
323Currently the same as Coro::async_pool, meaning you cannot use 385Currently the same as Coro::async_pool, meaning you cannot use
324C<on_destroy>, C<join> or other gimmicks on these coroutines. The only 386C<on_destroy>, C<join> or other gimmicks on these coroutines. The only
325thing you are allowed to do is call C<prio> on it. 387thing you are allowed to do is call C<prio> on it.
866 "; 928 ";
867 die if $@; 929 die if $@;
868} 930}
869 931
870our $override; 932our $override;
871our @invoke_results = (); # referenced from .xs code. TODO: play tricks with reify and mortals? 933our @INVOKE_RESULTS = (); # referenced from .xs code. TODO: play tricks with reify and mortals?
872 934
873sub override { 935sub override {
874 $override = 1; 936 $override = 1;
875 @invoke_results = (); 937 @INVOKE_RESULTS = (@_);
876} 938}
877 939
878sub do_invoke { 940sub do_invoke {
879 my $event = shift; 941 my $event = shift;
880 my $callbacks = shift; 942 my $callbacks = shift;
881 943
882 @invoke_results = (); 944 @INVOKE_RESULTS = ();
883 945
884 local $override; 946 local $override;
885 947
886 for (@$callbacks) { 948 for (@$callbacks) {
887 eval { &{$_->[1]} }; 949 eval { &{$_->[1]} };
904 966
905Generate an object-specific event with the given arguments. 967Generate an object-specific event with the given arguments.
906 968
907This API is preliminary (most likely, the EVENT_CLASS_xxx prefix will be 969This API is preliminary (most likely, the EVENT_CLASS_xxx prefix will be
908removed in future versions), and there is no public API to access override 970removed in future versions), and there is no public API to access override
909results (if you must, access C<@cf::invoke_results> directly). 971results (if you must, access C<@cf::INVOKE_RESULTS> directly).
910 972
911=back 973=back
912 974
913=cut 975=cut
914 976
915############################################################################# 977#############################################################################
916# object support 978# object support
979#
980
981sub _can_merge {
982 my ($ob1, $ob2) = @_;
983
984 local $Storable::canonical = 1;
985 my $fob1 = Storable::freeze $ob1;
986 my $fob2 = Storable::freeze $ob2;
987
988 $fob1 eq $fob2
989}
917 990
918sub reattach { 991sub reattach {
919 # basically do the same as instantiate, without calling instantiate 992 # basically do the same as instantiate, without calling instantiate
920 my ($obj) = @_; 993 my ($obj) = @_;
921 994
1619 $self->init; # pass $1 etc. 1692 $self->init; # pass $1 etc.
1620 return $self; 1693 return $self;
1621 } 1694 }
1622 } 1695 }
1623 1696
1624 Carp::carp "unable to resolve path '$path' (base '$base')."; 1697 Carp::cluck "unable to resolve path '$path' (base '$base').";
1625 () 1698 ()
1626} 1699}
1627 1700
1628sub init { 1701sub init {
1629 my ($self) = @_; 1702 my ($self) = @_;
1907 1980
1908 undef $MAP_PREFETCH{$path}; 1981 undef $MAP_PREFETCH{$path};
1909 $MAP_PREFETCHER ||= cf::async { 1982 $MAP_PREFETCHER ||= cf::async {
1910 while (%MAP_PREFETCH) { 1983 while (%MAP_PREFETCH) {
1911 for my $path (keys %MAP_PREFETCH) { 1984 for my $path (keys %MAP_PREFETCH) {
1912 my $map = find $path 1985 if (my $map = find $path) {
1913 or next;
1914 $map->load; 1986 $map->load;
1987 }
1915 1988
1916 delete $MAP_PREFETCH{$path}; 1989 delete $MAP_PREFETCH{$path};
1917 } 1990 }
1918 } 1991 }
1919 undef $MAP_PREFETCHER; 1992 undef $MAP_PREFETCHER;
2419 2492
2420 utf8::encode $text; 2493 utf8::encode $text;
2421 $self->send_packet (sprintf "drawinfo %d %s", $flags || cf::NDI_BLACK, $text); 2494 $self->send_packet (sprintf "drawinfo %d %s", $flags || cf::NDI_BLACK, $text);
2422} 2495}
2423 2496
2424=item $client->send_msg ($color, $type, $msg, [extra...]) 2497=item $client->send_msg ($channel, $msg, $color, [extra...])
2425 2498
2426Send a drawinfo or msg packet to the client, formatting the msg for the 2499Send a drawinfo or msg packet to the client, formatting the msg for the
2427client if neccessary. C<$type> should be a string identifying the type of 2500client if neccessary. C<$type> should be a string identifying the type of
2428the message, with C<log> being the default. If C<$color> is negative, suppress 2501the message, with C<log> being the default. If C<$color> is negative, suppress
2429the message unless the client supports the msg packet. 2502the message unless the client supports the msg packet.
2430 2503
2431=cut 2504=cut
2432 2505
2433sub cf::client::send_msg { 2506sub cf::client::send_msg {
2434 my ($self, $color, $type, $msg, @extra) = @_; 2507 my ($self, $channel, $msg, $color, @extra) = @_;
2435 2508
2436 $msg = $self->pl->expand_cfpod ($msg); 2509 $msg = $self->pl->expand_cfpod ($msg);
2437 2510
2511 $color &= ~cf::NDI_UNIQUE; # just in case...
2512
2513 if (ref $channel) {
2514 # send meta info to client, if not yet sent
2515 unless (exists $self->{channel}{$channel->{id}}) {
2516 $self->{channel}{$channel->{id}} = $channel;
2517 $self->ext_event (channel_info => %$channel);
2518 }
2519
2520 $channel = $channel->{id};
2521 }
2522
2438 return unless @extra || length $msg; 2523 return unless @extra || length $msg;
2439 2524
2440 if ($self->can_msg) { 2525 if ($self->can_msg) {
2441 $self->send_packet ("msg " . $self->{json_coder}->encode ([$color, $type, $msg, @extra])); 2526 $self->send_packet ("msg " . $self->{json_coder}->encode ([$color, $channel, $msg, @extra]));
2442 } else { 2527 } else {
2443 # replace some tags by gcfclient-compatible ones 2528 # replace some tags by gcfclient-compatible ones
2444 for ($msg) { 2529 for ($msg) {
2445 1 while 2530 1 while
2446 s/<b>([^<]*)<\/b>/[b]${1}[\/b]/ 2531 s/<b>([^<]*)<\/b>/[b]${1}[\/b]/

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines