Ambrosia
view release on metacpan or search on metacpan
lib/Ambrosia/Event.pm view on Meta::CPAN
package Ambrosia::Event;
use strict;
use warnings;
use Ambrosia::Meta;
class sealed
{
private => [qw/_handlers/],
};
our $VERSION = 0.010;
sub import
{
no strict 'refs';
no warnings 'redefine';
my $proto = shift;
throw Ambrosia::error::Exception("'$proto' cannot inherit from sealed class '" . __PACKAGE__ . '\'.') if $proto ne __PACKAGE__;
my $INSTANCE_CLASS = caller(0);
foreach my $e ( @_ ) #@events )
{
*{"${INSTANCE_CLASS}::$e"} = sub()
{
#my $pack = ref $_[0];
#$pack =~ s/::/_/sg;
#attachHandler($pack . '_' . $e, $_[1]);
attachHandler($_[0], $e, $_[1]);
$_[0];
};
}
*{"${INSTANCE_CLASS}::publicEvent"} = sub()
{
my $self = shift;
fireEvent($self, @_);
};
}
{
my %__EVENT_HANDLER__ = ();
sub new : Private {};
sub instance
{
return $__EVENT_HANDLER__{$$} ||= __PACKAGE__->SUPER::new();
}
}
sub _init
{
my $self = shift;
$self->SUPER::_init(@_);
$self->_handlers = {};
}
sub attachHandler
{
my $class = shift;
my $type = ref $class || $class || '';
my $name = shift;
my $handler = shift;
my $h = instance();
if ( my $prev = $h->_handlers->{$type}->{$name} )
{
$h->_handlers->{$type}->{$name} = sub { $handler->(@_) || $prev->(@_) };
}
elsif (ref $handler eq 'CODE')
{
$h->_handlers->{$type}->{$name} = $handler;
}
else
{
die 'error';
}
}
sub fireEvent
{
my $class = shift;
my $type = ref $class || $class || '';
my $name = shift;
if ( my $h = instance()->_handlers->{$type}->{$name} )
{
$h->(@_);
}
}
1;
__END__
=head1 NAME
Ambrosia::Event - lets you publish and subscribe to events.
=head1 VERSION
version 0.010
=head1 SYNOPSIS
package Foo;
use Ambrosia::Event qw/on_start on_complete/;
use Ambrosia::Meta;
class sealed {
};
sub run
{
my $self = shift;
$self->publicEvent( 'on_start' );
.........
$self->publicEvent( on_complete => $eny_params );
( run in 1.351 second using v1.01-cache-2.11-cpan-e1769b4cff6 )