File Coverage

blib/lib/Bot/Cobalt/Core/Role/Timers.pm
Criterion Covered Total %
statement 18 103 17.4
branch 0 48 0.0
condition 0 16 0.0
subroutine 7 16 43.7
pod 7 7 100.0
total 32 190 16.8


line stmt bran cond sub pod time code
1             package Bot::Cobalt::Core::Role::Timers;
2             $Bot::Cobalt::Core::Role::Timers::VERSION = '0.021003';
3 5     5   2161 use 5.10.1;
  5         14  
4 5     5   17 use strictures 2;
  5         22  
  5         128  
5              
6 5     5   2247 use Bot::Cobalt::Timer;
  5         12  
  5         176  
7              
8 5     5   26 use Scalar::Util qw/blessed/;
  5         7  
  5         245  
9              
10 5     5   22 use List::Objects::WithUtils;
  5         8  
  5         34  
11              
12 5     5   5121 use Moo::Role;
  5         8  
  5         35  
13              
14             requires qw/
15             log
16             debug
17             send_event
18             /;
19              
20              
21             ## FIXME tests are nonexistant
22              
23             has TimerPool => (
24             is => 'rw',
25 2     2   56 builder => sub { hash },
26             );
27              
28              
29             sub timer_gen_unique_id {
30 0     0 1   my ($self) = @_;
31 0           my @p = ( 'a'..'f', 1..9 );
32 0           my $id = join '', map { $p[rand@p] } 1 .. 4;
  0            
33 0           $id .= $p[rand@p] while $self->TimerPool->exists($id);
34 0           $id
35             }
36              
37             sub timer_set {
38 0     0 1   my ($self, $item) = @_;
39            
40 0           my ($caller_pkg, $caller_line) = (caller)[0,2];
41 0           my $d_line = "$caller_pkg line $caller_line";
42            
43 0           my $timer = $item;
44 0 0 0       unless (blessed $item && $item->isa('Bot::Cobalt::Timer') ) {
45             ## hashref-style (we hope)
46 0           $timer = $self->timer_set_hashref( $item, @_[2 .. $#_] );
47             }
48              
49 0 0         unless ($timer->has_id) {
50 0           $timer->id( $self->timer_gen_unique_id );
51             }
52            
53             ## Add to our TimerPool.
54 0           $self->TimerPool->set($timer->id => $timer);
55 0           $self->send_event( new_timer => $timer->id );
56              
57 0 0         $self->log->debug(
58             "timer_set; ".join ' ', $timer->id, $timer->delay, $timer->event
59             ) if $self->debug > 1;
60              
61 0           $timer->id
62             }
63              
64             sub timer_set_hashref {
65 0     0 1   my ($self, $delay, $ev, $id) = @_;
66              
67 0           my ($caller_pkg, $caller_line) = (caller)[0,2];
68 0           my $d_line = "$caller_pkg line $caller_line";
69            
70 0 0         unless (ref $ev eq 'HASH') {
71 0 0         if (ref $ev) {
72 0           $self->log->warn(
73             "timer_set_hashref expected HASH but got $ev; $d_line"
74             );
75             return
76 0           } else {
77             ## Assume we were passed a simple string.
78 0           $ev = { Event => $ev };
79             }
80             }
81            
82 0           my $timer = Bot::Cobalt::Timer->new;
83              
84 0 0         $timer->id($id) if $id;
85              
86             ## Try to guess type, or default to 'event'
87 0           my $type = $ev->{Type};
88 0 0         unless ($type) {
89 0 0 0       if (defined $ev->{Text} && defined $ev->{Context}) {
90 0           $type = 'msg'
91             } else {
92 0           $type = 'event'
93             }
94             }
95            
96 0           my($event_name, @event_args);
97            
98             TYPE: {
99 0 0         if ($type eq "event") {
  0            
100 0 0         unless (defined $ev->{Event}) {
101 0           $self->log->warn(
102             "timer_set_hashref no Event specified; $d_line"
103             );
104             return
105 0           }
106              
107 0           $timer->event( $ev->{Event} );
108 0   0       $timer->args( $ev->{Args}//[] );
109            
110             last TYPE
111 0           }
112            
113 0 0         if (grep { $type eq $_ } qw/msg message privmsg action/) {
  0            
114 0 0 0       unless (defined $ev->{Text} && defined $ev->{Target}) {
115 0           $self->log->warn(
116             "timer_set_hashref; $type needs Text and Target; $d_line"
117             );
118              
119             return
120 0           }
121              
122 0 0         $timer->context( $ev->{Context} ) if defined $ev->{Context};
123 0           $timer->target( $ev->{Target} );
124 0           $timer->text( $ev->{Text} );
125 0           $timer->type( $type );
126              
127             last TYPE
128 0           }
129            
130 0           $self->log->error("Unknown type $type passed to timer_set_hashref");
131             return
132 0           }
133              
134             ## Tag w/ __PACKAGE__ if no alias is specified
135 0   0       $timer->alias( $ev->{Alias} // scalar caller );
136            
137             ## Start ticking.
138 0           $timer->delay( $delay );
139              
140 0           $timer
141             }
142              
143             sub timer_get {
144 0     0 1   my ($self, $id) = @_;
145 0 0 0       return unless $id and $self->TimerPool->exists($id);
146              
147 0 0         $self->log->debug("timer retrieved; $id")
148             if $self->debug > 1;
149              
150 0           $self->TimerPool->get($id)
151             }
152              
153             sub timer_get_alias {
154             ## get all timerIDs for this alias
155 0     0 1   my ($self, $alias) = @_;
156 0 0         return unless $alias;
157              
158 0           my @timers;
159             $self->TimerPool->kv->visit(sub {
160 0     0     my ($id, $entry) = @$_;
161 0 0         push @timers, $id if $entry->alias eq $alias
162 0           });
163              
164 0 0         wantarray ? @timers : \@timers
165             }
166              
167             sub timer_del {
168             ## delete a timer by its ID
169             ## doesn't care if the timerID actually exists or not.
170 0     0 1   my ($self, $id) = @_;
171 0 0         return unless $id;
172              
173 0 0         $self->log->debug("timer del; $id")
174             if $self->debug > 1;
175              
176 0 0         return unless $self->TimerPool->exists($id);
177              
178 0           my $deleted = $self->TimerPool->delete($id);
179 0           $self->send_event( 'deleted_timer', $id, $deleted->all );
180            
181 0           $deleted->all
182             }
183              
184             sub timer_del_alias {
185 0     0 1   my ($self, $alias) = @_;
186 0 0         return unless $alias;
187              
188 0           my @deleted;
189             $self->TimerPool->kv->visit(sub {
190 0     0     my ($id, $entry) = @$_;
191 0 0         if ($entry->alias eq $alias) {
192 0           push @deleted, $id;
193 0           my $removed = $self->TimerPool->delete($id);
194 0           $self->send_event( deleted_timer => $id, $removed );
195             }
196 0           });
197              
198 0 0         wantarray ? @deleted : scalar @deleted
199             }
200              
201              
202             1;
203             __END__