File Coverage

lib/Devel/Trepan/CmdProcessor/Hook.pm
Criterion Covered Total %
statement 51 73 69.8
branch 5 16 31.2
condition n/a
subroutine 10 17 58.8
pod 0 7 0.0
total 66 113 58.4


line stmt bran cond sub pod time code
1             # -*- coding: utf-8 -*-
2             # Copyright (C) 2011-2012 Rocky Bernstein <rocky@cpan.org>
3 13     13   66770 use strict; use warnings;
  13     13   91  
  13         394  
  13         66  
  13         24  
  13         564  
4 13     13   263 use rlib '../../..';
  13         26  
  13         96  
5              
6 13     13   4917 use Class::Struct;
  13         1570  
  13         105  
7 13     13   8393 use Time::HiRes;
  13         19379  
  13         56  
8              
9             struct CmdProcessorHook => {
10             priority => '$',
11             name => '$',
12             fn => '$'
13             };
14              
15              
16             package Devel::Trepan::CmdProcessor::Hook;
17             # attr_accessor :list
18              
19             sub new($;$)
20             {
21 40     40 0 172 my ($class, $list) = @_;
22 40         75 my $self = {};
23 40 50       110 $list = [] unless defined $list;
24 40         91 $self->{list} = $list;
25 40         80 bless $self, $class;
26 40         106 $self;
27             }
28              
29             sub delete_by_name($)
30             {
31 0     0 0 0 my ($self, $delete_name) = @_;
32 0         0 my @new_list = ();
33 0         0 for my $elt (@{$self->{list}}) {
  0         0  
34 0 0       0 push(@new_list, $elt) unless $elt->name eq $delete_name;
35             }
36 0         0 $self->{list} = \@new_list;
37             }
38              
39             sub is_empty($)
40             {
41 0     0 0 0 my $self = shift;
42 0         0 return 0 == scalar(@{$self->{list}});
  0         0  
43             }
44              
45             sub insert($$$$)
46             {
47 2     2 0 719 my ($self, $priority, $name, $hook) = @_;
48 2         3 my $insert_loc;
49 2         4 my @list = $self->{list};
50 2         7 for ($insert_loc=0; $insert_loc < $#list; $insert_loc++) {
51 0         0 my $entry = $self->{list}[$insert_loc];
52 0 0       0 if ($priority > $entry->priority) {
53 0         0 last;
54             }
55             }
56 2         40 my $new_item = CmdProcessorHook->new(name => $name, priority=>$priority, fn => $hook);
57 2         70 splice(@{$self->{list}}, $insert_loc, 0, $new_item);
  2         8  
58             }
59              
60             sub insert_if_new($$$$)
61             {
62 2     2 0 1437 my ($self, $priority, $name, $hook) = @_;
63 2         11 my $found = 0;
64 2         7 for my $item (@{$self->{list}}) {
  2         5  
65 2 100       47 if ($item->name eq $name) {
66 1         10 $found = 1;
67 1         2 last;
68             }
69             }
70 2 100       18 $self->insert($priority, $name, $hook) unless ($found);
71             }
72              
73             # Run each function in `hooks' with args
74             sub run($)
75             {
76 2     2 0 1584 my $self = shift;
77 2         3 for my $hook (@{$self->{list}}) {
  2         6  
78 3         61 $hook->fn->($hook->name, \@_);
79             }
80             }
81              
82             package Devel::Trepan::CmdProcessor;
83              
84             # # Command processor hooks.
85             # attr_reader :autolist_hook
86             # attr_reader :timer_hook
87             # attr_reader :trace_hook
88             # attr_reader :tracebuf_hook
89             # attr_reader :unconditional_prehooks
90             # attr_reader :cmdloop_posthooks
91             # attr_reader :cmdloop_prehooks
92              
93             # # Used to time how long a debugger action takes
94             # attr_accessor :time_last
95              
96             sub hook_initialize($)
97             {
98 13     13 0 50 my ($self) = @_;
99 13         35 my $commands = $self->{commands};
100 13         197 $self->{cmdloop_posthooks} = Devel::Trepan::CmdProcessor::Hook->new;
101 13         48 $self->{cmdloop_prehooks} = Devel::Trepan::CmdProcessor::Hook->new;
102 13         47 $self->{unconditional_prehooks} = Devel::Trepan::CmdProcessor::Hook->new;
103              
104 13         37 my $list_cmd = $commands->{'list'};
105             $self->{autolist_hook} = ['autolist',
106 13 0   0   210 sub{ $list_cmd->run(['list']) if $list_cmd}];
  0         0  
107            
108             $self->{timer_hook} = ['timer',
109             sub{
110 0     0   0 my $now = Time::HiRes::time;
111             $self->{time_last} = $now unless
112 0 0       0 defined $self->{time_last};
113 0         0 my $mess = sprintf("%g seconds", $now - $self->{time_last});
114 0         0 $self->msg($mess);
115 0         0 $self->{time_last} = $now;
116 13         151 }];
117             $self->{timer_posthook} = ['timer',
118             sub{
119 13     0   140 $self->{time_last} = Time::HiRes::time}];
  0         0  
120             $self->{trace_hook} = ['trace',
121             sub{
122             $self->print_location unless
123 13 0   0   161 $self->{terminated} } ];
  0         0  
124             $self->{tracebuf_hook} = ['tracebuffer',
125             sub{
126 0           push(@{$self->{eventbuf}},
127 0     0     ($self->{event}, $self->{frame}));
128 13         180 }];
129             }
130              
131             unless (caller) {
132             # Demo it.
133             my $hooks = Devel::Trepan::CmdProcessor::Hook->new();
134             $hooks->run(5);
135             my $hook1 = sub($$) {
136             my ($name, $a) = @_;
137             my $args = join(', ', @$a);
138             print "${name} called with $args\n";
139             };
140             $hooks = Devel::Trepan::CmdProcessor::Hook->new();
141             $hooks->insert(-1, 'hook1', $hook1);
142             $hooks->insert_if_new(-1, 'hook1', $hook1);
143             my $dash_line = '-' x 30 . "\n";
144             print $dash_line;
145             print join(', ', @{$hooks->{list}}), "\n";
146             $hooks->run(10);
147             print $dash_line;
148             $hooks->insert(-1, 'hook2', $hook1);
149             $hooks->run(20);
150             print $dash_line;
151             $hooks->delete_by_name('hook2');
152             $hooks->run(30);
153             print $dash_line;
154             $hooks->delete_by_name('hook1');
155             $hooks->run(30);
156             print $dash_line;
157             }
158              
159             1;