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';
    }



( run in 0.709 second using v1.01-cache-2.11-cpan-ceb78f64989 )