NAME

    Evented::Object - a 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.

 Glossary

    These terms are used throughout the Evented::Object documentation.

    Evented::Object

      This base class, providing methods for managing events.

    Evented object - $eo

      Refers to any object instance of Evented::Object or a package which
      inherits from it.

      See "Evented object methods".

    Callback

      Event responders, known as callbacks, consist of a code reference and
      sometimes additional options describing how and when they should be
      executed.

      They are executed in descending order by priority. Numerically larger
      priorities are called first. This allows you to place a certain
      callback in front of or behind another.

    Fire object - $fire or $event

      An object representing an event fire.

      The fire object provides methods for fetching information related to
      the current event fire. It also provides an interface for modifying
      the behavior of the remaining callbacks.

      Fire objects are specific to the particular event fire, not the
      event. If you fire the same event twice in a row, the event object
      used the first time will not be the same as the second time.
      Therefore, all modifications made by the fire object's methods apply
      only to the callbacks remaining in this particular fire. For example,
      $fire->cancel($callback) will only cancel the supplied callback once.

      See "Fire object methods".

    Collection - $col or $collection

      An object representing a group of callbacks waiting to be fired.

      Sometimes it is useful to prepare an event fire before actually
      calling it. This way, you can provide special options for the fire.
      Collections are returned by the 'prepare' methods.

       $eo->prepare(event_name => @args)->fire(some_fire_option => $value);

      See "Collection methods".

    Listener object

      An evented object that receives event notifications from another
      evented object.

      Additional evented objects can be registered as "listeners," which
      allows them to respond to the events of another evented object.

      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 mooing is cow.moo.

      Fire objects and listeners

      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: the name of the event from the perspective of
	the listener; i.e. cow.moo (NOT moo)

	* $fire->object: the 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, including those belonging to the
      evented object.

    Evented::Object's included core packages are prefixed with
    Evented::Object::. Other packages which are specifically designed for
    use with Evented::Object are prefixed with Evented::.

Evented object methods

    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: the name of the event.

      * callback: a 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: the name of the callback being registered. must be unique to
      this particular event.

      * priority: a numerical priority of the callback.

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

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

      * data: any 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.

      * no_fire_obj: if true, the fire object will not be prepended to the
      argument list.

    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 events 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: an array of hash references to pass to
      ->register_callback().

 $eo->delete_event($event_name)

    Deletes all callbacks registered for the supplied event.

    Returns a true value if any events were deleted, false otherwise.

     $eo->delete_event('myEvent');

    Parameters

      * event_name: the name of the event.

 $eo->delete_callback($event_name)

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

    Returns a true value if any events were deleted, false otherwise.

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

    Parameters

      * event_name: the name of the event.

      * callback_name: the name of the callback being removed.

 $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.

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

    Parameters

      * event_name: the 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.

     $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: the name of the event being fired.

      * arguments: optional, list of arguments to pass to event callbacks.

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

    Makes the passed evented object a listener of this evented object. See
    the "listener objects" section for more information on this feature.

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

    Parameters

      * other_eo: the evented object that will listen.

      * prefix: a string that event names will be prefixed with on the
      listener.

 $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->delete_listener($other_eo)

    Removes a listener of this evented object. See the "listener objects"
    section for more information on this feature.

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

    Parameters

      * other_eo: the evented object that will listen.

      * prefix: a string that event names will be prefixed with on the
      listener.

 $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.

Preparation methods

    Callbacks can be prepared before being fired. This is most useful for
    firing events with special fire options.

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

    Prepares a single event for firing. Returns a collection object
    representing the callbacks for the event.

     # 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.

 $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 ]
     );

Class monitors

 $eo->monitor_events($pkg)

    Registers an evented object as the class monitor for a specific
    package. See the section above for more details on class monitors and
    their purpose.

     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: a 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 the section above for more details on class
    monitors and their purpose.

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

      * pkg: a 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 entire routine. 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
     );

    Parameters

      * events: an 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: the evented object.

      * event_name: the name of the event.

      * args: the arguments for the event fire.

Collection methods

    "Collections" are returned by the 'prepare' methods. They represent a
    group of callbacks that are about to be fired.

 $col->fire(@options)

    Fires the pending callbacks with the specified options, if any. If the
    callbacks have not yet been sorted, they are sorted before the event is
    fired.

     $eo->prepare(some_event => @arguments)->fire('safe');

    Parameters

      * options: optional, a mixture of boolean and key:value options for
      the event fire.

    @options

      * caller: requires value, use an alternate [caller 1] value for the
      event fire. This is typically only used internally.

      * return_check: boolean, if true, the event will yield that it was
      stopped if any of the callbacks return a false value. Note however
      that if one callbacks returns false, the rest will still be called.
      The fire object will only yield stopped status after all callbacks
      have been called and any number of them returned false.

      * safe: boolean, wrap all callback calls in eval for safety. if any
      of them fail, the event will be stopped at that point with the error.

      * fail_continue: boolean, if safe above is enabled, this tells the
      fire to continue even if one of the callbacks fails. This could be
      dangerous if any of the callbacks expected a previous callback to be
      done when it actually failed.

      * data: requires value, a scalar value that can be fetched by
      $fire->data from within the callbacks. Good for data that might be
      useful sometimes but not frequently enough to deserve a spot in the
      argument list. If data is a hash reference, its values can be fetched
      conveniently with $fire->data('key').

 $col->sort

    Sorts the callbacks according to priority, before, and after options.

Fire object methods

    "Fire objects" are passed to all callbacks of an Evented::Object
    (unless the silent parameter was specified.) Fire objects contain
    information about the event itself, the callback, the caller of the
    event, event data, and more.

 $fire->object

    Returns the evented object.

     $fire->object->delete_event('myEvent');

 $fire->caller

    Returns the value of caller(1) from within the ->fire() method. This
    allows you to determine from where the event was fired.

     my $name   = $fire->event_name;
     my @caller = $fire->caller;
     say "Package $caller[0] line $caller[2] called event $name";

 $fire->stop($reason)

    Cancels all remaining callbacks. This stops the rest of the event
    firing. After a callback calls $fire->stop, the name of that callback
    is stored as $fire->stopper.

    If the event has already been stopped, this method returns the reason
    for which the fire was stopped or "unspecified" if no reason was given.

     # ignore messages from trolls
     if ($user eq 'noah') {
         # user is a troll.
         # stop further callbacks.
         return $fire->stop;
     }

      * reason: optional, the reason for stopping the event fire.

 $fire->stopper

    Returns the callback which called $fire->stop.

     if ($fire->stopper) {
         say 'Fire was stopped by '.$fire->stopper;
     }

 $fire->exception

    If the event was fired with the safe option, it is possible that an
    exception occurred in one (or more if fail_continue enabled) callbacks.
    This method returns the last exception that occurred or undef if none
    did.

     if (my $e = $fire->exception) {
        say "Exception! $e";
     }

 $fire->called($callback)

    If no argument is supplied, returns the number of callbacks called so
    far, including the current one. If a callback argument is supplied,
    returns whether that particular callback has been called.

     say $fire->called, 'callbacks have been called so far.';
    
     if ($fire->called('some.callback')) {
         say 'some.callback has been called already.';
     }

    Parameters

      * callback: optional, the callback being checked.

 $fire->pending($callback)

    If no argument is supplied, returns the number of callbacks pending to
    be called, excluding the current one. If a callback argument is
    supplied, returns whether that particular callback is pending for being
    called.

     say $fire->pending, ' callbacks are left.';
    
     if ($fire->pending('some.callback')) {
         say 'some.callback will be called soon (unless it gets canceled)';
     }

    Parameters

      * callback: optional, the callback being checked.

 $fire->cancel($callback)

    Cancels the supplied callback once.

     if ($user eq 'noah') {
         # we don't love noah!
         $fire->cancel('send.hearts');
     }

    Parameters

      * callback: the callback to be cancelled.

 $fire->return_of($callback)

    Returns the return value of the supplied callback.

     if ($fire->return_of('my.callback')) {
         say 'my.callback returned a true value';
     }

    Parameters

      * callback: the desired callback.

 $fire->last

    Returns the most recent previous callback called. This is also useful
    for determining which callback was the last to be called.

     say $fire->last, ' was called before this one.';
    
     my $fire = $eo->fire_event('myEvent');
     say $fire->last, ' was the last callback called.';

 $fire->last_return

    Returns the last callback's return value.

     if ($fire->last_return) {
         say 'the callback before this one returned a true value.';
     }
     else {
         die 'the last callback returned a false value.';
     }

 $fire->event_name

    Returns the name of the event.

     say 'the event being fired is ', $fire->event_name;

 $fire->callback_name

    Returns the name of the current callback.

     say 'the current callback being called is ', $fire->callback_name;

 $fire->callback_priority

    Returns the priority of the current callback.

     say 'the priority of the current callback is ', $fire->callback_priority;

 $fire->callback_data($key)

    Returns the data supplied to the callback when it was registered, if
    any. If the data is a hash reference, an optional key parameter can
    specify a which value to fetch.

     say 'my data is ', $fire->callback_data;
     say 'my name is ', $fire->callback_data('name');

    Parameters

      * key: optional, a key to fetch a value if the data registered was a
      hash.

 $fire->data($key)

    Returns the data supplied to the collection when it was fired, if any.
    If the data is a hash reference, an optional key parameter can specify
    a which value to fetch.

     say 'fire data is ', $fire->data;
     say 'fire time was ', $fire->data('time');

    Parameters

      * key: optional, a key to fetch a value if the data registered was a
      hash.

Aliases

    A number of aliases exist for convenience, but some of the names are
    rather broad. For that reason, they are only recommended for use when
    you are sure 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.

ADVANCED FEATURES

 Registering callbacks to package names

    The methods ->register_callback(), ->delete_event(), ->delete_callback,
    etc. can be called in the form of MyClass->method(). Evented::Object
    will store these callbacks in the package's symbol table.

    Any object of this class will borrow these callbacks from the class.
    They will be incorporated into the callback collection as though they
    were registered directly on the object.

    Note that events cannot be fired on a class, only on evented objects.

    Note that if an evented object is blessed to a subclass of a class with
    callbacks registered to it, the object will NOT inherit the callbacks
    associated with the parent class. Callbacks registered to classes ONLY
    apply to objects directly blessed to the class.

 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.

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 RT
    <https://rt.cpan.org/Public/Dist/Display.html?Name=Evented-Object>.

