This is a test patch, it should work and is documented.

Dngor, apply it if you want, the slowdown for non hook users is marginal

Artur

Index: POE/Kernel.pm
===================================================================
RCS file: /cvsroot/poe/poe/POE/Kernel.pm,v
retrieving revision 1.136
diff -r1.136 Kernel.pm
11a12,19
> use vars qw($hook_session $hook_source_session $hook_local_state $hook_etc
$hook_file $hook_line $hook_dispatch $hook_return);
> use vars qw(%pre_dispatch_hooks %post_dispatch_hooks %pre_hooks %post_hooks
$hook_id $hooks @hooks);
> 
> ($hook_id, $hooks) = (1,0);
> $pre_dispatch_hooks{""} = {};
> $post_dispatch_hooks{""} = {};
> 
> 
796a805,807
>       $pre_dispatch_hooks{$session} = {};
>       $post_dispatch_hooks{$session} = {};
> 
920a932,934
> 
> 
> 
922,923c936,962
<   my $return =
<     $session->_invoke_state($source_session, $local_state, $etc, $file,
$line);
---
> 
>   my $return;
> 
> 
> 
>   
>   ($hook_session, $hook_source_session,$hook_local_state, $hook_etc,
$hook_file, $hook_line, $hook_dispatch) =
>       (     $session,      $source_session,     $local_state,      $etc,
$file,      $line,          0);
>   
> 
>   for(values %{$pre_dispatch_hooks{""}->{""}},         values
%{$pre_dispatch_hooks{""}->{$local_state}},
>       values %{$pre_dispatch_hooks{"$session"}->{""}}, values
%{$pre_dispatch_hooks{"$session"}->{$local_state}}) {
>       $hook_dispatch = 1 if($hook_return = $_->());
>   }
> 
>   unless($hook_dispatch) {
>       $hook_return = $return = $session->_invoke_state($source_session,
$local_state, $etc, $file, $line);
>   }
> 
>   for(values %{$post_dispatch_hooks{""}->{""}},         values
%{$post_dispatch_hooks{""}->{$local_state}},
>       values %{$post_dispatch_hooks{"$session"}->{""}}, values
%{$post_dispatch_hooks{"$session"}->{$local_state}}) {
>       $hook_dispatch = 1 if($hook_return = $_->());
>   }
> 
>   
>   ($hook_session, $hook_source_session, $hook_local_state, $hook_etc,
$hook_file, $hook_line, $hook_return, $hook_dispatch) =
>       (undef, undef, undef, undef, undef, undef, undef, undef);
1004a1044,1047
> 
>       delete($pre_dispatch_hooks{$session});
>       delete($post_dispatch_hooks{$session});
> 
2892a2936,3009
> 
#===========================================================================
===
> # HOOKS
> 
#===========================================================================
===
> 
> my %hooks = ( dispatch_state => 1);
> 
> sub hook_set {
>     my ($self, $when, $session, $hook, $callback, $event) = @_;
> 
>     if($session) {
>     croak("Session $session is not a registred session")
unless(exists($self->[KR_SESSIONS]->{"$session"}));
>     }
>     croak("Hook $hook is not an avaible hook") unless(exists($hooks{$hook}));
>     if($when) {
>     croak("You cannot register a hook to run '$when', only 'pre' and 'post'")
if($when ne 'post' && $when ne 'pre');
>     } else {
>     $when = 'pre';
>     }
>     carp("We need a callback") unless(ref($callback));
> 
>     if($hook eq 'dispatch_state') {
> 
>     if($when eq 'pre') {
>         $pre_dispatch_hooks{"$session"}->{$event}->{$callback} = $callback;
>     } else {
>         $post_dispatch_hooks{"$session"}->{$event}->{$callback} = $callback;
>     }
>     $hooks[$hook_id] = [$session,$when,$callback,$event];
>     } else {
>     if($when eq 'pre') {
>         $pre_hooks{"$session"}->{$callback} = $callback;
>     } else {
>         $post_hooks{"$session"}->{$callback} = $callback;
>     }
>     $hooks[$hook_id] = [$session,$when,$callback];
>     }
> 
>     
> 
>     $hooks++;
>     return $hook_id++;
> }
> 
> sub hook_remove {
>     my($self, $id) = @_;
> 
>     my $hook = delete($hooks[$id]);
>     carp("No hook with id '$id' exists") unless(ref($hook) eq 'ARRAY');
>     
>     if(@$hook == 3) {
>     if($hook->[1] eq 'pre') {
>         delete($pre_hooks{$hook->[0]}->{$hook->[2]});
>         delete($pre_hooks{$hook->[0]}) unless(@{$pre_hooks{$hook->[0]}});
>     } else {
>         delete($post_hooks{$hook->[0]}->{$hook->[2]});
>         delete($post_hooks{$hook->[0]}) unless(@{$post_hooks{$hook->[0]}});
>     }
>     } else {
>     if($hook->[1] eq 'pre') {
>         delete($pre_dispatch_hooks{$hook->[0]}->{$hook->[3]}->{$hook->[2]});
>         delete($pre_dispatch_hooks{$hook->[0]}->{$hook->[3]})
unless(@{$pre_dispatch_hooks{$hook->[0]}->{$hook->[3]}});
>         delete($pre_dispatch_hooks{$hook->[0]})
unless(@{$pre_dispatch_hooks{$hook->[0]}});
>     } else {
>         delete($post_dispatch_hooks{$hook->[0]}->{$hook->[3]}->{$hook->[2]});
>         delete($post_dispatch_hooks{$hook->[0]}->{$hook->[3]})
unless(@{$post_dispatch_hooks{$hook->[0]}->{$hook->[3]}});
>         delete($post_dispatch_hooks{$hook->[0]})
unless(@{$post_dispatch_hooks{$hook->[0]}});
>     }
>      
>     }
>     $hooks--;
> }
> 
> 
> 
2899a3017
> 
3082a3201,3206
> Kernel hooks:
> 
>   # Kernel hooks lets you set hooks at varius points in the kernel
>   $hookid = $kernel->hook_set($when, $session, $hook, $callback, $event);
>   $kernel->hook_remeve($hookid);
> 
4098a4223,4315
> 
> =head2 Kernel Hooks
> 
> Kernel Hooks provide a way to add in hooks at various points in the
> kernels exeuction. The following two functions control thiss behaviour
> 
> =over 2
> 
> =item my $hook_id = $poe_kernel->hook_set($when, $session $hook, $callback,
$event);
> 
> This sets a hook.
> 
> =over 2
> 
> =item $when
> 
> Should be pre or post depending on when you want the hook executed
> 
> =item $session
> 
> The session you want to watch, empty for all sessions
> 
> =item $hook
> 
> What kind of hook, (hooks listed below)
> 
> =item $callback
> 
> A CODEREF to a subroutine
> 
> =item $event
> 
> The name of the state being called, only usefull for dispatch_state hook
> 
> =back
> 
> =item my $poe_kernel->hook_remove($hook_id);
> 
> This removes the hook with the corresonding id
> 
> =item Hooks
> 
> =over 2
> 
> =item dispatch_state
> 
> This hook is called just before and just after dispatch_state,
> if a pre hook returns true, it is assumed it has taken care of the
> dispatch and POEs normal dispatch is ignored! If you do not want this,
> make sure all dispatches end with return 0;
> 
> dispatch_state exposes quite a lot of variables, they are not exported and
> should be referenced as $POE::Kernel::variable
> 
> =over 2
> 
> =item $hook_session
> 
> This is the session being invoked
> 
> =item $hook_source_session
> 
> This is the source of the event
> 
> =item $hook_local_state
> 
> This is the state being invoked
> 
> =item $hook_etc
> 
> This is an arrayref of arguments
> 
> =item $hook_file
> 
> What file made the event
> 
> =item $hook_line
> 
> And corresponding line!
> 
> =item $hook_dispatch
> 
> This is true if a hook has already dispatched the event
> 
> =item $hook_return
> 
> The return value from the dispatch
> 
> =back
> 
> =back
> 
> 

Reply via email to