package Evo;
use Evo::Base -strict;
use Evo::Manager;
use Evo::MDN;
use Evo::Guard;

use Exporter 'import';

my @MSN
  = qw(mdn_subscribe mdn_broadcast mdn_unsubscribe mdn_unsubscribe_from_all);
my @DSL  = qw(dsl_stash dsl_check_stash dsl_call dsl_depth);
my @FUNC = qw(asap guard);
our @EXPORT_OK = (@DSL, @FUNC, @MSN);
our %EXPORT_TAGS
  = (all => \@EXPORT_OK, dsl => \@DSL, mdn => \@MSN, func => \@FUNC);

our $VERSION = '0.0158';    # VERSION

sub _manager             { Evo::Manager->singleton }
sub asap : prototype(&@) { _manager->asap(@_) }

sub dsl_depth : prototype()         { _manager->dsl_depth; }
sub dsl_call : prototype($;@)       { _manager->dsl_call(@_); }
sub dsl_stash : prototype(;$$)      { _manager->dsl_stash(@_); }
sub dsl_check_stash : prototype(;$) { _manager->dsl_stash(@_); }

sub _mdn { state $mdn = Evo::MDN->new }
sub mdn_broadcast                           { _mdn->broadcast(@_); }
sub mdn_subscribe                           { _mdn->subscribe(@_); }
sub mdn_unsubscribe                         { _mdn->unsubscribe(@_); }
sub mdn_unsubscribe_from_all : prototype($) { _mdn->unsubscribe_from_all(@_); }

sub guard : prototype(@) { Evo::Guard->new(@_) }

1;

# ABSTRACT: Perl Evo design pattern

__END__

=pod

=encoding UTF-8

=head1 NAME

Evo - Perl Evo design pattern

=head1 VERSION

version 0.0158

=head1 SYNOPSIS

  use Evo::Base -strict;
  use Evo ':all';

  # next tick
  our $state = 'non blocking';

  # always nb
  asap {
    say $state;
    local $state = 'blocking?';
    asap { say $state };
  };


  # dsl
  # prints 1;2;foo
  my @args = (1, 2);
  my $print = sub(@args) { local $, = ';'; say @args, dsl_stash 'foo' };

  dsl_call({foo => 'foo'}, @args, $print);

  # delivery messages from any objects to any objects
  my $sender = Evo::Base->new;

  do {
    my $foo  = Evo::Base->new;
    my $file = IO::File->new;
    mdn_subscribe $foo,  $sender, 1, sub($me, $msg, @) { say "$me got $msg" };
    mdn_subscribe $file, $sender, 0, sub($me, $msg, @) { say "$me got $msg" };

    mdn_broadcast $sender, "hello";
  };

  mdn_broadcast $sender, "alive";

=head1 DESCRIPTION

  Tiny framework for organization non-trivial code into a simple logic.
  It includes benefits from functional and OO styles.

  Write fast, reusable and testable code.
  Familiar with OO? - Use it. Familiar with higher-order functions? - Use it.
  Familiar with non-blocking style? - Use it. Want DSL? - Use it.

  Do it the right way.

=head1 DESCRIPTION

  Attention. Don't use it right now. Wait for the stable release

=head1 METHODS

=head2 mdn_broadcast, mdn_subscribe, mdn_unsubscribe, mdn_unsubscribe_from_all

Calls corresponding L<Evo::MDN> methods passing a singleton as the first
argument

=head2 asap, dsl_depth, dsl_stash dsl_check_stash dsl_call dsl_depth

Calls corresponding L<Evo::Manager> methods passing a singleton as the first
argument

=head2 guard

  my $guard = guard { pass "guard" };
  undef $guard;

Create an L<Evo::Guard> instance passing a first argument as an attribute to L<Evo::Guard/"cb">

=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
