icicleio/event-emitter

This package is abandoned and no longer maintained. The author suggests using the Observables in icicleio/icicle package instead.

Event Emitter is a library that allows objects to emit events that invoke a set of registered callbacks.

v1.1.1 2015-04-18 17:05 UTC

This package is not auto-updated.

Last update: 2015-12-05 15:46:05 UTC


README

@icicleio on Twitter Build Status Coverage Status Semantic Version Apache 2 License

Join the chat at https://gitter.im/icicleio/Icicle

Event emitters are objects that emit events identified by an integer or string. When an object emits and event, it invokes a set of callbacks registered on the emitted event identifier.

Each event emitter must implement Icicle\EventEmitter\EventEmitterInterface. Classes should implement this interface by extending Icicle\EventEmitter\EventEmitter or using the trait Icicle\EventEmitter\EventEmitterTrait in the class definition.

This implementation differs from other event emitter libraries by ensuring that a particular callback can only be registered once for a particular event identifier. An attempt to register a previously registered callback is a no-op.

Event identifiers are also strictly enforced to aid in debugging. Event emitter objects must initialize event identifiers of events they wish to emit. If an attempt to register a callback is made on a non-existent event, an Icicle\EventEmitter\Exception\InvalidEventException is thrown.

Example
use Icicle\EventEmitter\EventEmitterInterface;
use Icicle\EventEmitter\EventEmitterTrait;

class ExampleEventEmitter implements EventEmitterInterface
{
    use EventEmitterTrait;

    public function __construct()
    {
        $this->createEvent('action'); // Creates event with 'action' identifier.
    }

    public function doAction($arg1, $arg2)
    {
        $this->emit('action', $arg1, $arg2); // Emits an event with 'action' identifier.
    }
}

The example class above implements Icicle\EventEmitter\EventEmitterInterface so it can emit events to a set of listeners. The example below demonstrates how listeners can be added to an instance of this class and the behavior of emitting events. This class will also be used in several other examples below.

$emitter = new ExampleEventEmitter();

// Registers a callback to be called each time the event is emitted.
$emitter->on('action', function ($arg1, $arg2) {
    echo "Argument 1 value: {$arg1}\n";
    echo "Argument 2 value: {$arg2}\n";
});

// Registers a callback to be called only the next time the event is emitted.
$emitter->once('action', function ($arg1, $arg2) {
    $result = $arg1 * $arg2;
    echo "Result: {$result}\n";
});

$emitter->doAction(404, 3.14159); // Calls both functions above.
$emitter->doAction(200, 2.71828); // Calls only the first function.
Requirements
  • PHP 5.4+
Installation

The recommended way to install is with the Composer package manager. (See the Composer installation guide for information on installing and using Composer.)

Run the following command to use this library in your project:

composer require icicleio/event-emitter

You can also manually edit composer.json to add this library as a project requirement.

// composer.json
{
    "require": {
        "icicleio/event-emitter": "~1"
    }
}

Documentation

Function prototypes

Prototypes for object instance methods are described below using the following syntax:

ReturnType $classOrInterfaceName->methodName(ArgumentType $arg1, ArgumentType $arg2)

Prototypes for static methods are described below using the following syntax:

ReturnType ClassName::methodName(ArgumentType $arg1, ArgumentType $arg2)

To document the expected prototype of a callback function used as method arguments or return types, the documentation below uses the following syntax for callable types:

callable<ReturnType (ArgumentType $arg1, ArgumentType $arg2)>

EventEmitterInterface

Icicle\EventEmitter\EventEmitterInterface is an interface that any class can implement for emitting events. The simplest way to implement this interface is to use Icicle\EventEmitter\EventEmitterTrait in the class definition or for the class to extend Icicle\EventEmitter\EventEmitter.

addListener()
$this $eventEmitterInterface->addListener(
    string|int $event,
    callable<void (mixed ...$args)> $callback,
    bool $once = false
)

Adds an event listener defined by $callback to the event identifier $event. If $once is true, the listener will only be called the next time the event is emitted, otherwise the listener will be called each time the event is emitted. If the identifier given by $event does not exist, an Icicle\EventEmitter\Exception\InvalidEventException will be thrown.

on()
$this $eventEmitterInterface->on(string|int $event, callable<void (mixed ...$args)> $callback)

Adds an event listener defined by $callback to the event identifier $event that will be called each time the event is emitted. This method is identical to calling addListener() with $once as false. If the identifier given by $event does not exist, an Icicle\EventEmitter\Exception\InvalidEventException will be thrown.

once()
$this $eventEmitterInterface->once(string|int $event, callable<void (mixed ...$args)> $callback)

Adds an event listener defined by $callback to the event identifier $event that will be only the next time the event is emitted. This method is identical to calling addListener() with $once as true. If the identifier given by $event does not exist, an Icicle\EventEmitter\Exception\InvalidEventException will be thrown.

removeListener()
$this $eventEmitterInterface->removeListener(string|int $event, callable<void (mixed ...$args)> $callback)

Removes the event listener defined by $callback from the event identifier $event. This method will remove the listener regardless of if the listener was to be called each time the event was emitted or only the next time the event was emitted. If the was not a registered on the given event, this function is a no-op. If the identifier given by $event does not exist, an Icicle\EventEmitter\Exception\InvalidEventException will be thrown.

off()
$this $eventEmitterInterface->off(string|int $event, callable<void (mixed ...$args)> $callback)

This method is an alias of removeListener().

removeAllListeners()
$this $eventEmitterInterface->removeAllListeners(string|int|null $event = null)

Removes all listeners from the event identifier or if $event is null, removes all listeners from all events. If the identifier given by $event does not exist, an Icicle\EventEmitter\Exception\InvalidEventException will be thrown.

getListeners()
callable[] $eventEmitterInterface->getListeners(string|int $event)

Returns all listeners on the event identifier as an array of callables. If the identifier given by $event does not exist, an Icicle\EventEmitter\Exception\InvalidEventException will be thrown.

getListenerCount()
int $eventEmitterInterface->getListenerCount(string|int $event)

Gets the number of listeners on the event identifier. If the identifier given by $event does not exist, an Icicle\EventEmitter\Exception\InvalidEventException will be thrown.

emits()
bool $eventEmitterInterface->emits(string|int $event)

Determines if the object emits events with the identifier given by $event.

getEventList()
array $eventEmitterInterface->getEventList()

Returns an array of event identifiers emitted by the object.

EventEmitterTrait

Icicle\EventEmitter\EventEmitterTrait is a simple way for any class to implement Icicle\EventEmitter\EventEmitterInterface. This trait defines protected methods that are not part of Icicle\EventEmitter\EventEmitterInterface that are used to create and emit events.

createEvent()
$this $eventEmitterTrait->create(string|int $identifier)

This method creates an event identifier so events may be emitted and listeners added. Generally this method will be called in the constructor to initialize a set of event identifiers.

emit()
bool $eventEmitterTrait->emit(string|int $event, mixed ...$args)

Emits an event with the event identifier $event, passing the remaining arguments given to this function as the arguments to each event listener. The method returns true if any event listeners were invoked, false if none were. If the identifier given by $event does not exist, an Icicle\EventEmitter\Exception\InvalidEventException will be thrown.

Creating Promises from Events

Promises are a component of Icicle, a library for writing asynchronous code in PHP. Promises act as placeholders for the future value of an asynchronous operation.

The static method Icicle\Promise\Promise::promisify() can be used to create a function returning a promise that is resolved the next time an event emitter emits an event.

use Icicle\Loop\Loop;
use Icicle\Promise\Promise;

// Include ExampleEventEmitter class definition from above.

$emitter = new ExampleEventEmitter();

// Use once() since promises can only be resolved once.
$promisor = Promise::promisify([$emitter, 'once'], 1);

$promise = $promisor('action'); // Promise for 'action' event.

$promise = $promise->then(function (array $args) {
    list($arg1, $arg2) = $args;
    echo "Argument 1 value: {$arg1}\n";
    echo "Argument 2 value: {$arg2}\n";
});

// Simulates an event being emitted while running the loop.
Loop::schedule(function () use ($emitter) {
    $emitter->doAction(404, 3.14159); // Fulfills promise.
});

Loop::run();

See the Promise API documentation for more information on using promises.

Executing Coroutines on Events

Coroutines use generators to create cooperative coroutines. They are a component of Icicle, a library for writing asynchronous code in PHP.

Event emitters can be used to create and execute coroutines each time an event is emitted. The static method Icicle\Coroutine\Coroutine::async() returns a function that can be used as the event listener on an event emitter.

use Icicle\Coroutine\Coroutine;
use Icicle\Loop\Loop;

// Include ExampleEventEmitter class definition from above.

$emitter = new ExampleEventEmitter();

$emitter->on('action', Coroutine::async(function ($arg1, $arg2) {
    $result = (yield $arg1 * $arg2);
    echo "Result: {$result}\n";
}));

// Simulates an event being emitted while running the loop.
Loop::schedule(function () use ($emitter) {
    $emitter->doAction(404, 3.14159); // Creates and runs coroutine.
});

Loop::run();

See the Coroutine API documentation for more information on using coroutines.