File Coverage

blib/lib/Aion/Emitter.pm
Criterion Covered Total %
statement 24 24 100.0
branch 3 4 75.0
condition 1 3 33.3
subroutine 6 6 100.0
pod 1 1 100.0
total 35 38 92.1


line stmt bran cond sub pod time code
1             package Aion::Emitter;
2             # Диспетчер
3              
4 2     2   129007 use common::sense;
  2         4  
  2         21  
5              
6             our $VERSION = "0.1.1";
7              
8 2     2   625 use Aion::Pleroma;
  2         74172  
  2         64  
9              
10 2     2   11 use Aion;
  2         3  
  2         7  
11              
12             my $event_isa = HashRef[ArrayRef[Dict[act => StrMatch[qr/^[\w:]+#\w+$/a], line => Option[Nat], nice => Option[Num], remark => Option[Str]]]];
13              
14 2     2   2071 use Aion::Env::Etc INI => (isa => Str, default => 'etc/annotation/listen.ann', key => 'aion.emitter.ini');
  2         7238  
  2         52  
15 2     2   299 use Aion::Env::Etc EVENT => (isa => $event_isa, default => {}, key => 'aion.emitter.event');
  2         3  
  2         6  
16              
17             # Путь к собранным из аннотаций методам
18             has ini => (is => 'ro', isa => Str, default => INI);
19              
20             # Список слушателей
21             has event => (is => 'ro', isa => $event_isa, default => sub {
22             my ($self) = @_;
23             my %event = %{EVENT()};
24            
25             if(defined $self->ini and -e $self->ini) {
26             open my $f, "<:encoding(UTF-8)", $self->ini or die "Not open ${\$self->ini}";
27             while(<$f>) {
28             do { close $f; die "${\$self->ini}:$. corrupt!" } unless /^([\w:]+)#(\w*),(\d+)=(?:(-?\d+(?:\.\d+)?)\s+)?([a-z][\w:]*(?:#[\w.:-]+)?)(?:\s+(.*?))??\s*$/ia;
29             my ($pkg, $sub, $line, $nice, $evt, $remark) = ($1, $2, $3, $4, $5, $6);
30             $sub //= 'listen';
31             push @{$event{$evt}}, {
32             act => "$pkg#$sub",
33             line => $line,
34             $nice? (nice => $nice): (),
35             $remark ne ''? (remark => $remark): (),
36             };
37             }
38             close $f;
39             }
40              
41             for my $listens (values %event) {
42             @$listens = sort { $a->{nice} <=> $b->{nice} or $a->{act} cmp $b->{act} } @$listens;
43             }
44            
45             \%event
46             });
47              
48             # Плерома
49             has pleroma => (is => 'ro', isa => 'Aion::Pleroma', eon => 1);
50              
51             # Излучить
52             sub emit {
53 2     2 1 144358 my ($self, $event, $key) = @_;
54            
55 2 100       28 my $listeners = $self->event->{defined($key)? "${\ref $event}#$key": ref $event};
  1         2152  
56 2 50       5429 return $self unless $listeners;
57            
58 2         4 for my $listener_bag (@$listeners) {
59 3         64 my ($pkg, $sub) = split /#/, $listener_bag->{act}, 2;
60 3   33     50 my $listener = $self->pleroma->get($pkg) // $self->pleroma->autoware($pkg)->resolve($pkg);
61 3         1198 $listener->$sub($event);
62             }
63            
64             $self
65 2         89 }
66              
67             1;
68              
69             __END__