]>
jfr.im git - irc/SurrealServices/srsv.git/blob - tags/0.4.3.1-pre2/SrSv/Message.pm
1 # This file is part of SurrealServices.
3 # SurrealServices is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # SurrealServices is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with SurrealServices; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 package SrSv
::Message
;
21 use Exporter
'import';
22 BEGIN { our @EXPORT_OK = qw(add_callback message call_callback unit_finished current_message) }
25 use Storable
qw(fd_retrieve store_fd);
30 require Data
::Dumper
; import Data
::Dumper
();
34 use SrSv
::Process
::Call
qw(safe_call);
35 use SrSv
::Process
::Worker
qw(ima_worker get_socket multi call_in_parent call_all_child do_callback_in_child);
37 our %callbacks_by_trigger_class;
38 our %callbacks_by_after;
39 our %callbacks_by_name;
49 croak
"Callbacks cannot be added at runtime";
52 if(my $after = $callback->{AFTER
}) {
53 push @{$callbacks_by_after{$after}}, $callback;
56 $callback->{NAME
} = $callback->{CALL
} unless $callback->{NAME
};
57 if(my $name = $callback->{NAME
}) {
58 push @{$callbacks_by_name{$name}}, $callback;
61 if(my $trigger = $callback->{TRIGGER_COND
}{CLASS
}) {
62 push @{$callbacks_by_trigger_class{$trigger}}, $callback;
66 print "Added callback: $callback->{NAME}\n";
74 if($message->{SYNC
}) {
75 print "Triggered a sync callback!\n" if DEBUG
();
76 trigger_callbacks
($message);
78 store_fd
($message, get_socket
());
79 fd_retrieve
(get_socket
());
84 trigger_callbacks
($message);
90 my ($callback, $message) = @_;
92 local $current_message = $message;
94 if(my $call = $callback->{CALL
}) {
95 safe_call
($call, [$message, $callback]);
99 sub unit_finished
($$) {
100 my ($callback, $message) = @_;
103 print "--- Finished unit\nCallback: $callback->{NAME}\nMessage: $message->{CLASS}\n";
106 safe_call
($callback->{ON_FINISH
}, [$callback, $message]) if $callback->{ON_FINISH
};
108 $message->{_CB_COUNTDOWN
}--;
109 print "_CB_COUNTDOWN is $message->{_CB_COUNTDOWN}\n---\n" if DEBUG
;
111 $message->{_CB_DONE
}{$callback->{NAME
}} = 1;
113 if(!$message->{SYNC
} and defined($message->{_CB_QUEUE
}) and @{$message->{_CB_QUEUE
}}) {
114 trigger_callbacks
($message);
117 if($message->{_CB_COUNTDOWN
} == 0) {
118 message_finished
($message);
122 sub message_finished
($) {
125 print "Message finished: $message->{CLASS}\n" if DEBUG
;
127 for(qw(_CB_QUEUE _CB_COUNTDOWN _CB_DONE _CB_TODO)) {
128 undef $message->{$_};
131 safe_call
($message->{ON_FINISH
}, [$message]) if $message->{ON_FINISH
};
134 ### Private functions ###
136 sub trigger_callbacks
($) {
141 if(defined($message->{_CB_QUEUE
})) {
142 $callbacks = $message->{_CB_QUEUE
};
144 $callbacks = get_matching_callbacks
($message);
148 $message->{_CB_COUNTDOWN
} = @$callbacks unless defined($message->{_CB_COUNTDOWN
});
152 foreach my $callback (@$callbacks) {
153 my $after = $callback->{AFTER
};
154 if($after and $message->{_CB_TODO
}{$after} and not $message->{_CB_DONE
}{$after}) {
155 push @$do_next, $callback;
157 do_unit
($callback, $message);
161 $message->{_CB_QUEUE
} = $do_next;
163 goto &trigger_callbacks
if($message->{SYNC
} and @$do_next > 0);
168 print "Message with no callbacks: ".Dumper
($message);
171 message_finished
($message);
176 my ($callback, $message) = @_;
178 if(!multi or $callback->{PARENTONLY
} or $message->{SYNC
}) {
179 call_callback
($callback, $message);
180 unit_finished
($callback, $message);
182 do_callback_in_child
($callback, $message);
186 sub get_matching_callbacks
($) {
190 my $class = $message->{CLASS
};
192 foreach my $callback (@{$callbacks_by_trigger_class{$class}}) {
193 if(callback_matches
($message, $callback)) {
194 push @$ret, $callback;
195 $message->{_CB_TODO
}{$callback->{NAME
}} = 1;
202 sub callback_matches
($$) {
203 my ($message, $callback) = @_;
205 foreach my $cond (keys(%{$callback->{TRIGGER_COND
}})) {
206 if(ref($callback->{TRIGGER_COND
}{$cond}) eq 'Regexp') {
207 return 0 if defined($message->{$cond}) && !($message->{$cond} =~ $callback->{TRIGGER_COND
}{$cond});
209 return 0 if defined($message->{$cond}) && !(lc $message->{$cond} eq lc $callback->{TRIGGER_COND
}{$cond});
216 sub current_message
() { return $current_message }