BroadcasterTrait   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 3
dl 0
loc 74
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A on() 0 16 3
B broadcast() 0 20 7
A buildEventReceivers() 0 8 1
A runReceiverCallback() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jarvis\Skill\EventBroadcaster;
6
7
/**
8
 * @author Eric Chau <[email protected]>
9
 */
10
trait BroadcasterTrait
11
{
12
    private $receivers = [];
13
    private $permanentEvents = [];
14
    private $computedReceivers = [];
15
    private $masterEmitter = false;
16
17
    /**
18
     * {@inheritdoc}
19
     */
20
    public function on(string $name, $receiver, int $priority = BroadcasterInterface::RECEIVER_NORMAL_PRIORITY): void
21
    {
22
        if (!isset($this->receivers[$name])) {
23
            $this->receivers[$name] = [
24
                BroadcasterInterface::RECEIVER_LOW_PRIORITY    => [],
25
                BroadcasterInterface::RECEIVER_NORMAL_PRIORITY => [],
26
                BroadcasterInterface::RECEIVER_HIGH_PRIORITY   => [],
27
            ];
28
        }
29
30
        $this->receivers[$name][$priority][] = $receiver;
31
        $this->computedReceivers[$name] = null;
32
        if (isset($this->permanentEvents[$name])) {
33
            $this->runReceiverCallback($receiver, $this->permanentEvents[$name]);
34
        }
35
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40
    public function broadcast(string $name, EventInterface $event = null): void
41
    {
42
        if (isset($this->permanentEvents[$name])) {
43
            throw new \LogicException('Permanent event cannot be broadcasted multiple times.');
44
        }
45
46
        $event = $event ?? new SimpleEvent();
47
        if ($event instanceof PermanentEventInterface && $event->isPermanent()) {
48
            $this->permanentEvents[$name] = $event;
49
        }
50
51
        if (isset($this->receivers[$name])) {
52
            foreach ($this->buildEventReceivers($name) as $receiver) {
53
                $this->runReceiverCallback($receiver, $event);
54
                if ($event->isPropagationStopped()) {
55
                    break;
56
                }
57
            }
58
        }
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    protected function runReceiverCallback($receiver, EventInterface $event)
65
    {
66
        call_user_func($receiver, ['event' => $event]);
67
    }
68
69
    /**
70
     * Builds and returns well ordered receivers collection that match with provided event name.
71
     *
72
     * @param  string $name The event name we want to get its receivers
73
     * @return array
74
     */
75
    private function buildEventReceivers(string $name): array
76
    {
77
        return $this->computedReceivers[$name] = $this->computedReceivers[$name] ?? array_merge(
78
            $this->receivers[$name][BroadcasterInterface::RECEIVER_HIGH_PRIORITY],
79
            $this->receivers[$name][BroadcasterInterface::RECEIVER_NORMAL_PRIORITY],
80
            $this->receivers[$name][BroadcasterInterface::RECEIVER_LOW_PRIORITY]
81
        );
82
    }
83
}
84