NAME

    Evented::Object - base class which allows you to attach callbacks to
    objects and then fire events on them.

SYNOPSIS

     package Person;
     
     use warnings;
     use strict;
     use 5.010;
     use parent 'Evented::Object';
     
     use Evented::Object;
     
     # Creates a new person object. This is nothing special.
     # Evented::Object does not require any specific constructor to be called.
     sub new {
         my ($class, %opts) = @_;
         bless \%opts, $class;
     }
     
     # Fires birthday event and increments age.
     sub have_birthday {
         my $person = shift;
         $person->fire(birthday => ++$person->{age});
     }

    In some other package...

     package main;
     
     # Create a person named Jake at age 19.
     my $jake = Person->new(name => 'Jake', age => 19);
     
     # Add an event callback that assumes Jake is under 21.
     $jake->on(birthday => sub {
         my ($fire, $new_age) = @_;
         say 'not quite 21 yet...';
     }, name => '21-soon');
     
     # Add an event callback that checks if Jake is 21
     # and cancels the above callback if so.
     $jake->on(birthday => sub {
      my ($fire, $new_age) =  @_;
         if ($new_age == 21) {
              say 'time to get drunk!';
              $fire->cancel('21-soon');
         }
     }, name => 'finally-21', priority => 1);
     
     # Jake has two birthdays.
     
     # Jake's 20th birthday.
     $jake->have_birthday;
     
     # Jake's 21st birthday.
     $jake->have_birthday;
     
     # Because 21-soon has a lower priority than finally-21,
     # finally-21 will cancel 21-soon if Jake is 21.
     
     # The result:
     #
     #   not quite 21 yet...
     #   time to get drunk!

DESCRIPTION

    I doubt your objects have ever been this evented in your entire life.

    Evented::Object supplies an (obviously objective) interface to store
    and manage callbacks for events, fire events upon objects, and more.

    Evented::Object allows you to attach event callbacks to an object
    (i.e., a blessed hash reference) and then fire events on that object.
    Event fires are much like method calls, except that there can be many
    responders.

    Whereas many event systems involve globally unique event names,
    Evented::Object allows you to attach events on specific objects. The
    event callbacks, priority options, and other data are stored within the
    object itself.

MANAGING CALLBACKS

    The Evented::Object package provides several convenient methods for
    managing an event-driven object.

 Evented::Object->new()

    Creates a new Evented::Object.

    Typically, this method is overriden by a child class of
    Evented::Object.

     my $eo = Evented::Object->new();

 $eo->register_callback($event_name => \&callback, %options)

    Attaches an event callback the object.

    When the specified event is fired, each of the callbacks registered
    using this method will be called by descending priority order
    (numerically higher priority numbers are called first.)

     $eo->register_callback(myEvent => sub {
         ...
     }, name => 'some.callback', priority => 200);

    Parameters

      * $event_name - name of the event.

      * \&callback - CODE reference to be called when the event is fired.

      * %options - optional, a hash (NOT a hash reference) of any of the
      below options.

    %options - event handler options

    All of these options are optional, but the use of a callback name is
    highly recommended.

      * name - name of the callback being registered. must be unique to
      this particular event.

      * priority - numerical priority of the callback.

      * before - name of a callback or an array reference of callback names
      to precede.

      * after - name of a callback or an array reference of callback names
      to succeed.

      * data - data that will be stored as $fire->callback_data as the
      callback is fired. If data is a hash reference, its values can be
      fetched conveniently with $fire->callback_data('key').

      * with_eo - if true, the evented object will prepended to the
      argument list (which is not the default behavior). note that this is
      enabled automatically when using the odd-argument version.

      * no_fire_obj - if true, the fire object will not be prepended to the
      argument list (which is the default behavior).

    Note: the order of objects will always be $eo, $fire, @args, regardless
    of omissions. By default, the argument list is $fire, @args.

    You may have any number of before and any number of after options for
    any given callback. For instance, one callback may specify to be before
    'b' and 'c' but after 'a'. Evented::Object will resolve these
    priorities to its best ability.

    In the case that the priorities can not be resolved (for instance, if a
    callback asks to be before 'a' and after 'b' while 'b' has already
    asked to be before 'a'), the behavior of Evented::Object is not
    guaranteed to be consistent. In other words, please do your best to not
    request impossible priorities.

    In any case, before and after options are completely ignored when a
    priority is explicitly specified.

 $eo->register_callback($event_name => \&callback, $cb_name, %options)

    If the list of options is odd, it is assumed that the first element is
    the callback name. In this case, the with_eo option is also
    automatically enabled.

     $eo->register_callback(myEvent => sub {
         ...
     }, 'some.callback, priority => 200);

    See the above method specification for parameters and supported
    options.

 $eo->register_callbacks(@events)

    Registers several event callbacks at once.

    The arguments should be a list of hash references. These references
    take the same options as ->register_callback(). Returns a list of
    return values in the order that the events were specified.

     $eo->register_callbacks(
         { myEvent => \&my_event_1, name => 'cb.1', priority => 200 },
         { myEvent => \&my_event_2, name => 'cb.2', priority => 100 }
     );

    Parameters

      * @events - array of hash references to pass to
      ->register_callback().

 $eo->delete_event($event_name)

    Deletes all callbacks registered for the supplied event.

    Returns number of callbacks deleted, false if none.

     $eo->delete_event('myEvent');

    Parameters

      * $event_name - name of the event.

 $eo->delete_callback($event_name, $callback_name)

    Deletes an event callback from the object with the given callback name.

    Returns true if a callback was deleted.

     $eo->delete_callback(myEvent => 'my.callback');

    Parameters

      * $event_name - name of the event.

      * $callback_name - name of the callback being removed.

 $eo->delete_all_events()

    Deletes all events and all callbacks from the object.

    If you know that an evented object will no longer be used in your
    program, by calling this method you can be sure that no cyclical
    references from within callbacks will cause the object to be leaked.

FIRING EVENTS

 $eo->fire_event($event_name => @arguments)

    Fires the specified event, calling each callback that was registered
    with ->register_callback() in descending order of their priorities.

    Returns the fire object.

     $eo->fire_event('some_event');
    
     $eo->fire_event(some_event => $some_argument, $some_other_argument);

    Parameters

      * $event_name - name of the event being fired.

      * @arguments - optional, list of arguments to pass to event
      callbacks.

 $eo->fire_once($event_name => @arguments)

    Fires the specified event, calling each callback that was registered
    with ->register_callback() in descending order of their priorities.

    Then, all callbacks for the event are deleted. This method is useful
    for situations where an event will never be fired more than once.

    Returns the fire object.

     $eo->fire_once('some_event');
     $eo->fire_event(some_event => $some_argument, $some_other_argument);
     # the second does nothing because the first deleted the callbacks

    Parameters

      * $event_name - name of the event being fired.

      * @arguments - optional, list of arguments to pass to event
      callbacks.

 $eo->fire_events_together(@events)

    The fire_events_together() function can be used as a method on evented
    objects. See the documentation for the function in "PROCEDURAL
    FUNCTIONS".

 $eo->prepare_event(event_name => @arguments)

    Prepares a single event for firing.

    Returns an Evented::Object::Collection representing the pending
    callbacks.

     # an example using the fire option return_check.
     $eo->prepare_event(some_event => @arguments)->fire('return_check');

 $eo->prepare_together(@events)

    The preparatory method equivalent to ->fire_events_together.

    Returns an Evented::Object::Collection representing the pending
    callbacks.

 $eo->prepare(...)

    A smart method that uses the best guess between ->prepare_event and
    ->prepare_together.

     # uses ->prepare_event()
     $eo->prepare(some_event => @arguments);
    
     # uses ->prepare_together()
     $eo->prepare(
        [ some_event => @arguments ],
        [ some_other => @other_arg ]
     );
     

LISTENERS

    An evented object can listen for event notifications from another
    evented object using the method "$eo->add_listener($other_eo,
    $prefix)".

    Consider a scenario where you have a class whose objects represent a
    farm. You have another class which represents a cow. You would like to
    use the same callback for all of the moos that occur on the farm,
    regardless of which cow initiated it.

    Rather than attaching an event callback to every cow, you can instead
    make the farm a listener of the cow. Then, you can attach a single
    callback to your farm. If your cow's event for mooing is moo, your
    farm's event for any mooing is cow.moo.

    When an event is fired on an object, the same fire object is used for
    callbacks belonging to both the evented object and its listening
    objects. Therefore, callback names should be unique not only to the
    listener object but to the object being listened on as well.

    You should also note the values of the fire object:

      * $fire->event_name - name of the event from the perspective of the
      listener; i.e. cow.moo (NOT moo)

      * $fire->object - object being listened to; i.e. $cow (NOT $farm)

    This also means that stopping the event from a listener object will
    cancel all remaining callbacks.

 $eo->add_listener($other_eo, $prefix)

    Makes the passed evented object a listener of this evented object.

    See "LISTENERS".

     $cow->add_listener($farm, 'cow');

    Parameters

      * $other_eo - evented object that will listen.

      * $prefix - string that event names will be prefixed with on the
      listener.

 $eo->delete_listener($other_eo)

    Removes a listener of this evented object.

    See "LISTENERS".

     $cow->delete_listener($farm);

    Parameters

      * $other_eo - evented object that will listen.

CLASS MONITORS

    An evented object can be registered as a "monitor" of a specific
    class/package.

    All event callbacks that are added from that class to any evented
    object of any type will trigger an event on the monitor object.

    An example scenario of when this might be useful is an evented object
    for debugging all events being registered by a certain package. It
    would log all of them, making it easier to find a problem.

 $eo->monitor_events($pkg)

    Registers an evented object as the class monitor for a specific
    package.

    See "CLASS MONITORS".

     my $some_eo  = Evented::Object->new;
     my $other_eo = Evented::Object->new;
    
     $some_eo->on('monitor:register_callback', sub {
         my ($event, $eo, $event_name, $cb) = @_;
         # $eo         == $other_eo
         # $event_name == "blah"
         # $cb         == callback hash from ->register_callback()
         say "Registered $$cb{name} to $eo for $event_name";
     });
    
     $some_eo->monitor_events('Some::Class');
    
     package Some::Class;
     $other_eo->on(blah => sub{}); # will trigger the callback above

      * $pkg - package whose event activity you wish to monitor.

 $eo->stop_monitoring($pkg)

    Removes an evented object from its current position as a monitor for a
    specific package.

    See "CLASS MONITORS".

     $some_eo->stop_monitoring('Some::Class');

      * $pkg - package whose event activity you're monitoring.

PROCEDURAL FUNCTIONS

    The Evented::Object package provides some functions for use. These
    functions typically are associated with more than one evented object or
    none at all.

 fire_events_together(@events)

    Fires multiple events at the same time.

    This allows you to fire multiple similar events on several evented
    objects at the same time. It essentially pretends that the callbacks
    are all for the same event and all on the same object.

    It follows priorities throughout all of the events and all of the
    objects, so it is ideal for firing similar or identical events on
    multiple objects.

    The same fire object is used throughout. This means that callback names
    must unique among all of these objects and events. It also means that
    stopping an event from any callback will cancel all remaining
    callbacks, regardless to which event or which object they belong.

    The function takes a list of array references in the form of: [
    $evented_object, event_name => @arguments ]

     Evented::Object::fire_events_together(
         [ $server,  user_joined_channel => $user, $channel ],
         [ $channel, user_joined         => $user           ],
         [ $user,    joined_channel      => $channel        ]
     );

    ->fire_events_together can also be used as a method on any evented
    object.

     $eo->fire_events_together(
         [ some_event => @arguments ],
         [ some_other => @other_arg ]
     );

    The above example would formerly be achieved as:

     Evented::Object::fire_events_together(
         [ $eo, some_event => @arguments ],
         [ $eo, some_other => @other_arg ]
     );

    However, other evented objects may be specified even when this is used
    as a method. Basically, anywhere that an object is missing will fall
    back to the object on which the method was called.

     $eo->fire_events_together(
         [ $other_eo, some_event => @arguments ],
         [            some_other => @other_arg ] # no object, falls back to $eo
     );
     

    Returns the fire object.

    Parameters

      * @events - array of events in the form of [$eo, event_name =>
      @arguments].

 safe_fire($eo, $event_name, @args)

    Safely fires an event. In other words, if the $eo is not an evented
    object or is not blessed at all, the call will be ignored. This
    eliminates the need to use blessed() and ->isa() on a value for testing
    whether it is an evented object.

     Evented::Object::safe_fire($eo, myEvent => 'my argument');

    Parameters

      * $eo - evented object.

      * $event_name - name of the event.

      * @args - arguments for the event fire.

ALIASES

    A number of aliases exist for convenience, but please only use them if
    you're certain that other subclassing will not interfere.

 $eo->on(...)

    Alias for $eo->register_callback().

 $eo->del(...)

    If one argument provided, alias for $eo->delete_event.

    If two arguments provided, alias for $eo->delete_callback.

 $eo->fire(...)

    Alias for $eo->fire_event().

 $eo->register_event(...)

    Alias for $eo->register_callback().

 $eo->register_events(...)

    Alias for $eo->register_callbacks().

 $fire->eo

    Alias for $fire->object.

AUTHOR

    Mitchell Cooper <https://github.com/cooper> <cooper@cpan.org>

    Copyright © 2011-2017. Released under BSD license.

    Comments, complaints, and recommendations are accepted. Bugs may be
    reported on GitHub <https://github.com/cooper/evented-object/issues>.

