-
Notifications
You must be signed in to change notification settings - Fork 7
/
Hooks.pm
108 lines (93 loc) · 2.17 KB
/
Hooks.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# -*- 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: [email protected]
# 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__