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

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

role_gen ee_check => sub {
  my $comp = shift;
  my %events = map { ($_, 1) } $comp->ee_events;
  sub {
    croak qq{Not recognized event "$_[1]"} unless exists $events{$_[1]};
    $_[0];
  };
};

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

sub ee_remove : Role {
  my ($self, $name, $fn) = @_;
  $self->ee_check($name);

  my $data = $self->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 : Role {
  my ($self, $name) = (shift, shift);
  $_->($self, @_) for my @listeners = $self->ee_listeners($name);
  @listeners;
}

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

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Evo::Ee

=head1 VERSION

version 0.0172

=head1 AUTHOR

alexbyk.com

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2015 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
