<commit_before>#
# Copyright (c) 2011-13, <NAME>
#
# Evented::Object: a simple yet featureful base class event framework.
#
# Evented::Object 0.2+ is based on the libuic UIC::Evented::Object:
# an event system based on the Evented::Object class from foxy-java IRC Bot,
# ... which is based on Evented::Object from Arinity IRC Services,
# ... which is based on Evented::Object from ntirc IRC Client,
# ... which is based on IRC::Evented::Object from libirc IRC Library.
#
# Evented::Object can be found in its latest version at https://github.com/cooper/evented-object.
#
# COMPATIBILITY NOTES:
#   See README.md.
#

package Evented::Object;
 
use warnings;
use strict;
use utf8;
use 5.010;

# these must be set before loading EventFire.
our ($events, $props, %monitors);
BEGIN {
    $events = 'eventedObject.events';
    $props  = 'eventedObject.props';
}

use Scalar::Util qw(weaken blessed);
use Evented::Object::EventFire;

our $VERSION = '4.11';

# create a new evented object.
sub new {
    bless {}, shift;
}

##########################
### MANAGING CALLBACKS ###
##########################

# attach an event callback.
# $eo->register_callback(myEvent => sub {
#     ...
# }, name => 'some.callback', priority => 200, eo_obj => 1);
# note: no_obj fires callback without $fire as first argument.
sub register_callback {
    my ($eo, $event_name, $code, %opts) = @_;
    
    # no name was provided, so we shall construct
    # one using the power of pure hackery.
    # this is one of the most criminal things I've ever done.
    my @caller = caller;
    if (!defined $opts{name}) {
        state $c    = -1; $c++; 
        $opts{name} = "$caller[0]($caller[2],$c)";
    }
    
    # determine the event store.
    my $event_store = _event_store($eo);
        
    # before/after a callback.
    my $priority   = delete $opts{priority} || 0;
    if (my $before = defined $opts{before} or defined $opts{after}) {
        my $add   = $before ? 1 : -1;
        my $res   = $eo->_get_callback_named($event_name, $opts{before} // $opts{after});
        $priority = $res->[0] + $add if defined $res;
    }
    
    # add the callback.
    my $callbacks = $event_store->{$event_name}{$priority} ||= [];
    push @$callbacks, my $cb = {
        %opts,
        code   => $code,
        caller => \@caller
    };
    
    # tell class monitor.
    _monitor_fire($caller[0], register_callback => $eo, $event_name, $cb);
    
    return $cb;
}

# attach several event callbacks.
sub register_callbacks {
    my ($eo, @events) = @_;
    my @return;
    push @return, $eo->register_callback(%$_) foreach @events;
    return @return;
}
 
# fire an event.
# returns $fire.
sub fire_event {
    _fire_event(shift, shift, [caller 1], @_);
}

# delete an event callback or all callbacks of an event.
# returns a true value if any events were deleted, false otherwise.
sub delete_callback {
    my ($eo, $event_name, $name) = @_;
    my $amount      = 0;
    my $event_store = _event_store($eo);
    
    # event does not have any callbacks.
    return unless $event_store->{$event_name};
 
    # iterate through callbacks and delete matches.
    PRIORITY: foreach my $priority (keys %{$event_store->{$event_name}}) {
    
        # if a specific callback name is specified, weed it out.
        if (defined $name) {
            my @a = @{$event_store->{$event_name}{$priority}};
            @a = grep { $_->{name} ne $name } @a;
            
            # none left in this priority.
            if (scalar @a == 0) {
                delete $event_store->{$event_name}{$priority};
                
                # delete this event because all priorities have been removed.
                if (scalar keys %{$event_store->{$event_name}} == 0) {
                    delete $event_store->{$event_name};
                    return 1;
                }
                
                $amount++;
                next PRIORITY;
                
            }
            
            # store the new array.
            $event_store->{$event_name}{$priority} = \@a;
            
        }
        
        # if no callback is specified, delete all events of this type.
        else {
            $amount = scalar keys %{$event_store->{$event_name}};
            delete $event_store->{$event_name};
        }
 
    }

    return $amount;
}

########################
### LISTENER OBJECTS ###
########################

# add an object to listen to events.
sub add_listener {<commit_msg>4.2: added two more monitor events: delete_event and delete_callback.<commit_after>#
# Copyright (c) 2011-13, <NAME>
#
# Evented::Object: a simple yet featureful base class event framework.
#
# Evented::Object 0.2+ is based on the libuic UIC::Evented::Object:
# an event system based on the Evented::Object class from foxy-java IRC Bot,
# ... which is based on Evented::Object from Arinity IRC Services,
# ... which is based on Evented::Object from ntirc IRC Client,
# ... which is based on IRC::Evented::Object from libirc IRC Library.
#
# Evented::Object can be found in its latest version at https://github.com/cooper/evented-object.
#
# COMPATIBILITY NOTES:
#   See README.md.
#

package Evented::Object;
 
use warnings;
use strict;
use utf8;
use 5.010;

# these must be set before loading EventFire.
our ($events, $props, %monitors);
BEGIN {
    $events = 'eventedObject.events';
    $props  = 'eventedObject.props';
}

use Scalar::Util qw(weaken blessed);
use Evented::Object::EventFire;

our $VERSION = '4.2';

# create a new evented object.
sub new {
    bless {}, shift;
}

##########################
### MANAGING CALLBACKS ###
##########################

# attach an event callback.
# $eo->register_callback(myEvent => sub {
#     ...
# }, name => 'some.callback', priority => 200, eo_obj => 1);
# note: no_obj fires callback without $fire as first argument.
sub register_callback {
    my ($eo, $event_name, $code, %opts) = @_;
    
    # no name was provided, so we shall construct
    # one using the power of pure hackery.
    # this is one of the most criminal things I've ever done.
    my @caller = caller;
    if (!defined $opts{name}) {
        state $c    = -1; $c++; 
        $opts{name} = "$caller[0]($caller[2],$c)";
    }
    
    # determine the event store.
    my $event_store = _event_store($eo);
        
    # before/after a callback.
    my $priority   = delete $opts{priority} || 0;
    if (my $before = defined $opts{before} or defined $opts{after}) {
        my $add   = $before ? 1 : -1;
        my $res   = $eo->_get_callback_named($event_name, $opts{before} // $opts{after});
        $priority = $res->[0] + $add if defined $res;
    }
    
    # add the callback.
    my $callbacks = $event_store->{$event_name}{$priority} ||= [];
    push @$callbacks, my $cb = {
        %opts,
        code   => $code,
        caller => \@caller
    };
    
    # tell class monitor.
    _monitor_fire($caller[0], register_callback => $eo, $event_name, $cb);
    
    return $cb;
}

# attach several event callbacks.
sub register_callbacks {
    my ($eo, @events) = @_;
    my @return;
    push @return, $eo->register_callback(%$_) foreach @events;
    return @return;
}
 
# fire an event.
# returns $fire.
sub fire_event {
    _fire_event(shift, shift, [caller 1], @_);
}

# delete an event callback or all callbacks of an event.
# returns a true value if any events were deleted, false otherwise.
sub delete_callback {
    my ($eo, $event_name, $name) = @_;
    my @caller      = caller;
    my $amount      = 0;
    my $event_store = _event_store($eo);
    
    # event does not have any callbacks.
    return unless $event_store->{$event_name};
 
    # iterate through callbacks and delete matches.
    PRIORITY: foreach my $priority (keys %{$event_store->{$event_name}}) {
    
        # if a specific callback name is specified, weed it out.
        if (defined $name) {
            my @a = @{$event_store->{$event_name}{$priority}};
            @a = grep { $_->{name} ne $name } @a;
            
            # none left in this priority.
            if (scalar @a == 0) {
                delete $event_store->{$event_name}{$priority};
                
                # delete this event because all priorities have been removed.
                if (scalar keys %{$event_store->{$event_name}} == 0) {
                    delete $event_store->{$event_name};
                    return 1;
                }
                
                $amount++;
                next PRIORITY;
                
            }
            
            # store the new array.
            $event_store->{$event_name}{$priority} = \@a;
            _monitor_fire($caller[0], delete_callback => $eo, $event_name, $name);
            
        }
        
        # if no callback is specified, delete all events of this type.
        else {
            $amount = scalar keys %{$event_store->{$event_name}};
            delete $event_store->{$event_name};
            _monitor_fire($caller[0], delete_event => $eo, $event_name);
        }
 
    }

    return $amount;
}

########################
### LISTENER OBJECTS ###
########################

# add an object to listen to events.
sub add_listener {
{'fraction_non_alphanumeric': 0.1516076294277929, 'fraction_numerical': 0.007520435967302452, 'mean_word_length': 2.3947465778764334, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 51, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3267583', 'n_tokens_mistral': 2913, 'n_tokens_neox': 2813, 'n_words': 870}