# -*- perl -*- # # $Id: Hooks.pm,v 1.7 2005/10/27 00:57:55 eserte Exp $ # Author: Slaven Rezic # # Copyright (C) 2000,2005 Slaven Rezic. All rights reserved. # This package is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # # Mail: eserte@cs.tu-berlin.de # WWW: http://user.cs.tu-berlin.de/~eserte/ # package Hooks; use strict; use vars qw(%pool $VERBOSE $VERSION); $VERSION = sprintf("%d.%02d", q$Revision: 1.7 $ =~ /(\d+)\.(\d+)/); sub get_hooks { my $label = shift; $pool{$label}; } sub new { my($class, $label) = @_; my $self = { Hooks => {}, Seq => 0, Order => [], }; bless $self, $class; if (defined $label) { $pool{$label} = $self; # XXX weakref! $self->{Label} = $label; } $self; } # XXX replace any hooks with same label! sub add { my($self, $code, $label) = @_; my $hook_def = { Code => $code, Label => $label, Seq => $self->{Seq}++, }; if ($VERBOSE) { warn "Add hook $label to $self->{Label}\n"; } $self->{Hooks}{$label} = $hook_def; $self->_create_list; } sub del { my($self, $label) = @_; if ($VERBOSE) { warn "Delete hook $label from $self->{Label}\n"; } delete $self->{Hooks}{$label}; $self->_create_list; } sub _create_list { my $self = shift; my $hooks = $self->{Hooks}; $self->{Order} = [map { $hooks->{$_} } sort { $hooks->{$a}{Seq} <=> $hooks->{$b}{Seq} } keys %$hooks ]; } sub execute { my $self = shift; $self->execute_except([], @_); } sub execute_except { my($self, $except_ref, @args) = @_; my %except = (ref $except_ref eq 'ARRAY' ? map { ($_=>1) } @$except_ref : ($except_ref => 1)); my %ret; foreach my $hook_def (@{ $self->{Order} }) { my $label = $hook_def->{Label}; if ($except{$label}) { warn "Skip hook $label of $self->{Label}\n" if $VERBOSE; next; } if ($VERBOSE) { warn "Execute hook $label of $self->{Label}\n"; } $ret{$label} = $hook_def->{Code}->(@args); } +{ReturnCodes => \%ret}; } sub DESTROY { my $self = shift; if (defined $self->{Label}) { delete $pool{$self->{Label}}; } } 1; __END__