Passed
Push — master ( 47e3e0...5cec02 )
by Fike
03:28
created

Conversion::run()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 0
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace AmaTeam\Image\Projection\Framework;
4
5
use AmaTeam\Image\Projection\API\ConversionInterface;
6
use AmaTeam\Image\Projection\API\Conversion\ListenerInterface;
7
use AmaTeam\Image\Projection\API\Conversion\ProcessorInterface;
8
use AmaTeam\Image\Projection\API\SpecificationInterface;
9
use AmaTeam\Image\Projection\API\Tile\TileInterface;
10
use AmaTeam\Image\Projection\API\Type\GeneratorInterface;
11
use Psr\Log\LoggerAwareInterface;
12
use Psr\Log\LoggerInterface;
13
use Psr\Log\NullLogger;
14
15
/**
16
 * Single-run conversion processing that encapsulates all userspace handlers.
17
 */
18
class Conversion implements ConversionInterface
19
{
20
    /**
21
     * @var SpecificationInterface
22
     */
23
    private $target;
24
    /**
25
     * @var GeneratorInterface
26
     */
27
    private $generator;
28
    /**
29
     * @var ListenerInterface[]
30
     */
31
    private $listeners = [];
32
    /**
33
     * @var ProcessorInterface[][]
34
     */
35
    private $processors = [];
36
    /**
37
     * @var LoggerInterface
38
     */
39
    private $logger;
40
41
    /**
42
     * @param SpecificationInterface $target
43
     * @param GeneratorInterface $generator
44
     * @param LoggerInterface|null $logger
45
     */
46
    public function __construct(
47
        SpecificationInterface $target,
48
        GeneratorInterface $generator,
49
        LoggerInterface $logger = null
50
    ) {
51
        $this->target = $target;
52
        $this->generator = $generator;
53
        $this->logger = $logger ?: new NullLogger();
54
    }
55
56
    /**
57
     * Runs whole pipeline. Tiles are destroyed after last listener has been
58
     * called.
59
     */
60
    public function run()
61
    {
62
        foreach ($this->generator as $tile) {
63
            $context = ['tile' => $tile->getPosition()];
64
            $this->logger->debug('Generated tile {tile}', $context);
65
            $this->applyProcessors($tile, $this->target);
66
            $this->notifyListeners($tile, $this->target);
67
        }
68
    }
69
70
    /**
71
     * @param TileInterface $tile
72
     * @param SpecificationInterface $specification
73
     */
74 View Code Duplication
    private function applyProcessors(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
75
        TileInterface $tile,
76
        SpecificationInterface $specification
77
    ) {
78
        foreach ($this->processors as $processors) {
79
            foreach ($processors as $processor) {
80
                $context = [
81
                    'tile' => $tile->getPosition(),
82
                    'processor' => $processor
83
                ];
84
                $template = 'Applying processor {processor} to tile {tile}';
85
                $this->logger->debug($template, $context);
86
                $processor->process($tile, $specification);
87
            }
88
        }
89
    }
90
91
    /**
92
     * @param TileInterface $tile
93
     * @param SpecificationInterface $specification
94
     */
95 View Code Duplication
    private function notifyListeners(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
96
        TileInterface $tile,
97
        SpecificationInterface $specification
98
    ) {
99
        foreach ($this->listeners as $listener) {
100
            $context = [
101
                'tile' => $tile->getPosition(),
102
                'listener' => $listener
103
            ];
104
            $template = 'Applying listener {listener} to tile {tile}';
105
            $this->logger->debug($template, $context);
106
            $listener->accept($tile, $specification);
107
        }
108
    }
109
110
    /**
111
     * @param ProcessorInterface $processor
112
     * @param int $order Order in which processors are applied (lower order.
113
     * values force processors to be run earlier). Processor with same order
114
     * value will be run in the order they were added.
115
     * priority
116
     *
117
     * @return $this
118
     */
119
    public function addProcessor(ProcessorInterface $processor, $order = 0)
120
    {
121
        if ($processor instanceof LoggerAwareInterface) {
122
            $processor->setLogger($this->logger);
123
        }
124
        if (!$this->processors[$order]) {
125
            $this->processors[$order] = [];
126
        }
127
        $this->processors[$order][] = $processor;
128
        ksort($this->processors);
129
        return $this;
130
    }
131
132
    /**
133
     * @param ListenerInterface $listener
134
     * @return $this
135
     */
136
    public function addListener(ListenerInterface $listener)
137
    {
138
        if ($listener instanceof LoggerAwareInterface) {
139
            $listener->setLogger($this->logger);
140
        }
141
        $this->listeners[] = $listener;
142
        return $this;
143
    }
144
}
145