package Evo::Ee;
use Evo '-Comp::Role *';
use Carp 'croak';
use List::Util 'first';

requires 'ee_events';

# [name, cb]
has ee_data => sub { [] };

sub ee_check($self, $name) : Role {
  croak qq{Not recognized event "$name"} unless first { $_ eq $name } $self->ee_events;
  $self;
}

sub on($self, $name, $fn) : Role {
  push $self->ee_check($name)->ee_data->@*, [$name, $fn];
  $self;
}

sub ee_remove($self, $name, $fn) : Role {
  my $data = $self->ee_check($name)->ee_data;
  defined(my $index = first { $data->[$_][0] eq $name && $data->[$_][1] == $fn } 0 .. $#$data)
    or return $self;
  splice $data->@*, $index, 1;
  $self;
}

sub emit($self, $name, @args) : Role {
  $_->($self, @args) for my @listeners = $self->ee_listeners($name);
  @listeners;
}

sub ee_listeners($self, $name) : Role {
  map { $_->[1] } grep { $_->[0] eq $name } $self->ee_data->@*;
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Evo::Ee

=head1 VERSION

version 0.0177

=head1 AUTHOR

alexbyk.com

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2016 by alexbyk.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
