Skip to content

Commit

Permalink
Return to the concise and simple api
Browse files Browse the repository at this point in the history
  • Loading branch information
WyriHaximus committed Aug 7, 2023
1 parent 383488a commit a3854fe
Show file tree
Hide file tree
Showing 6 changed files with 12 additions and 226 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ $emitter->on('user.created', function (User $user) use ($logger) {

```php
<?php
$emitter->off('user.created', function (User $user) use ($logger) {
$emitter->removeListener('user.created', function (User $user) use ($logger) {
$logger->log(sprintf("User '%s' was created.", $user->getLogin()));
});
```
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
}
],
"require": {
"php": ">=7.3"
"php": ">=7.0"
},
"require-dev": {
"phpunit/phpunit": "^9 || ^6"
Expand Down
24 changes: 0 additions & 24 deletions doc/01-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,27 +89,3 @@ Remove a specific listener for a specific event.
Remove all listeners for a specific event or all listeners all together. This
is useful for long-running processes, where you want to remove listeners in
order to allow them to get garbage collected.


## off($event, callable $listener = null)

Executes removeAllListeners($event = null) if $listener is null, otherwise
execute removeListener($event, callable $listener)

## eventNames()

Allows you to get all names to added event.

Example:

```php
$emitter->on('event1', function () {});
$emitter->on('event2', function () {});
$emitter->once('event3', function () {});

$result = $emitter->eventNames() //$result == ['event1', 'event2', 'event3']
```

## forward(EventEmitterInterface $emitter)

todo
2 changes: 0 additions & 2 deletions src/EventEmitterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@
interface EventEmitterInterface
{
public function on($event, callable $listener);
public function onceBefore($event, callable $listener);
public function once($event, callable $listener);
public function removeListener($event, callable $listener);
public function removeAllListeners($event = null);
public function listeners($event = null);
public function emit($event, array $arguments = []);
public function forward(EventEmitterInterface $emitter);
}
96 changes: 9 additions & 87 deletions src/EventEmitterTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
trait EventEmitterTrait
{
protected $listeners = [];
protected $beforeOnceListeners = [];
protected $onceListeners = [];
protected $children = [];

public function on($event, callable $listener)
{
Expand All @@ -35,21 +33,6 @@ public function on($event, callable $listener)
return $this;
}

public function onceBefore($event, callable $listener)
{
if ($event === null) {
throw new \InvalidArgumentException('event name must not be null');
}

if (!isset($this->beforeOnceListeners[$event])) {
$this->beforeOnceListeners[$event] = [];
}

$this->beforeOnceListeners[$event][] = $listener;

return $this;
}

public function once($event, callable $listener)
{
if ($event === null) {
Expand All @@ -65,23 +48,6 @@ public function once($event, callable $listener)
return $this;
}

public function off($event, callable $listener = null)
{
if ($listener !== null) {
$this->removeListener($event, $listener);
return;
}

$this->removeAllListeners($event);
}

public function eventNames(): array
{
return \array_unique(
\array_merge(\array_keys($this->listeners), \array_keys($this->onceListeners), \array_keys($this->beforeOnceListeners))
);
}

public function removeListener($event, callable $listener)
{
if ($event === null) {
Expand All @@ -107,16 +73,6 @@ public function removeListener($event, callable $listener)
}
}
}

if (isset($this->beforeOnceListeners[$event])) {
$index = \array_search($listener, $this->beforeOnceListeners[$event], true);
if (false !== $index) {
unset($this->beforeOnceListeners[$event][$index]);
if (\count($this->beforeOnceListeners[$event]) === 0) {
unset($this->beforeOnceListeners[$event]);
}
}
}
}

public function removeAllListeners($event = null)
Expand All @@ -132,33 +88,27 @@ public function removeAllListeners($event = null)
} else {
$this->onceListeners = [];
}

if ($event !== null) {
unset($this->beforeOnceListeners[$event]);
} else {
$this->beforeOnceListeners = [];
}
}

public function listeners($event = null): array
{
if ($event === null) {
$events = [];
$eventNames = $this->eventNames();
$eventNames = \array_unique(
\array_merge(\array_keys($this->listeners), \array_keys($this->onceListeners))
);
foreach ($eventNames as $eventName) {
$events[$eventName] = \array_merge(
isset($this->listeners[$eventName]) ? $this->listeners[$eventName] : [],
isset($this->onceListeners[$eventName]) ? $this->onceListeners[$eventName] : [],
isset($this->beforeOnceListeners[$eventName]) ? $this->beforeOnceListeners[$eventName] : []
isset($this->onceListeners[$eventName]) ? $this->onceListeners[$eventName] : []
);
}
return $events;
}

return \array_merge(
isset($this->listeners[$event]) ? $this->listeners[$event] : [],
isset($this->onceListeners[$event]) ? $this->onceListeners[$event] : [],
isset($this->beforeOnceListeners[$event]) ? $this->beforeOnceListeners[$event] : []
isset($this->onceListeners[$event]) ? $this->onceListeners[$event] : []
);
}

Expand All @@ -168,48 +118,20 @@ public function emit($event, array $arguments = [])
throw new \InvalidArgumentException('event name must not be null');
}

$beforeOnceListeners = [];
if (isset($this->beforeOnceListeners[$event])) {
$beforeOnceListeners = \array_values($this->beforeOnceListeners[$event]);
}

$listeners = [];
if (isset($this->listeners[$event])) {
$listeners = \array_values($this->listeners[$event]);
}

$onceListeners = [];
if (isset($this->onceListeners[$event])) {
$onceListeners = \array_values($this->onceListeners[$event]);
}

if(empty($beforeOnceListeners) === false) {
unset($this->beforeOnceListeners[$event]);
foreach ($beforeOnceListeners as $listener) {
$listener(...$arguments);
}
}

if(empty($listeners) === false) {
$listeners = $this->listeners[$event];
foreach ($listeners as $listener) {
$listener(...$arguments);
}
}

if(empty($onceListeners) === false) {

if (isset($this->onceListeners[$event])) {
$onceListeners = $this->onceListeners[$event];
unset($this->onceListeners[$event]);
foreach ($onceListeners as $listener) {
$listener(...$arguments);
}
}

foreach ($this->children as $child) {
$child->emit($event, $arguments);
}
}

public function forward(EventEmitterInterface $emitter)
{
$this->children[] = $emitter;
}
}
112 changes: 1 addition & 111 deletions tests/EventEmitterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class EventEmitterTest extends TestCase
*/
private $emitter;

public function setUp(): void
public function setUp()
{
$this->emitter = new EventEmitter();
}
Expand Down Expand Up @@ -91,32 +91,6 @@ public function testOnceWithArguments()
$this->assertSame(array('a', 'b'), $capturedArgs);
}

public function testOncePre()
{
$listenerCalled = [];

$this->emitter->onceBefore('foo', function () use (&$listenerCalled) {
$this->assertSame([], $listenerCalled);
$listenerCalled[] = 1;
});

$this->emitter->on('foo', function () use (&$listenerCalled) {
$this->assertSame([1], $listenerCalled);
$listenerCalled[] = 2;
});

$this->emitter->once('foo', function () use (&$listenerCalled) {
$this->assertSame([1, 2], $listenerCalled);
$listenerCalled[] = 3;
});

$this->assertSame([], $listenerCalled);

$this->emitter->emit('foo');

$this->assertSame([1, 2, 3], $listenerCalled);
}

public function testEmitWithoutArguments()
{
$listenerCalled = false;
Expand Down Expand Up @@ -471,88 +445,4 @@ public function testOnceNestedCallRegression()
self::assertSame(1, $first);
self::assertSame(1, $second);
}

public function testInheritance()
{
$child = new EventEmitter();
$this->emitter->forward($child);
$child->on('hello', function ($data) {
self::assertSame('hello from parent', $data);
});
$this->emitter->emit('hello', ['hello from parent']);
}

public function testOff()
{
self::assertSame([], $this->emitter->listeners());

$listener = function () {
};
$this->emitter->on('event', $listener);
$this->emitter->on('tneve', $listener);
self::assertSame(
[
'event' => [
$listener,
],
'tneve' => [
$listener,
],
],
$this->emitter->listeners()
);

$this->emitter->off('tneve', $listener);
self::assertSame(
[
'event' => [
$listener,
],
],
$this->emitter->listeners()
);

$this->emitter->off('event');
self::assertSame([], $this->emitter->listeners());
}

public function testNestedOn()
{
$emitter = $this->emitter;

$first = 0;
$second = 0;
$third = 0;

$emitter->on('event', function () use (&$emitter, &$first, &$second, &$third) {
$first++;

$emitter->on('event', function () use (&$second, &$third) {
$second++;
})
->once('event', function () use (&$third) {
$third++;
});
});

$emitter->emit('event');
$this->assertEquals(1, $first);
$this->assertEquals(0, $second);
$this->assertEquals(0, $third);
$emitter->emit('event');
$this->assertEquals(2, $first);
$this->assertEquals(1, $second);
$this->assertEquals(1, $third);
}

public function testEventNames()
{
$emitter = $this->emitter;

$emitter->on('event1', function () {});
$emitter->on('event2', function () {});
$emitter->once('event3', function () {});

$this->assertEquals(['event1', 'event2', 'event3'], $emitter->eventNames());
}
}

0 comments on commit a3854fe

Please sign in to comment.