1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Barryvanveen\CCA; |
6
|
|
|
|
7
|
|
|
use Barryvanveen\CCA\Config\NeighborhoodOptions; |
8
|
|
|
use Barryvanveen\CCA\Config\Options; |
9
|
|
|
use Barryvanveen\CCA\Config\Presets; |
10
|
|
|
use Barryvanveen\CCA\Exceptions\InvalidColorException; |
11
|
|
|
use Barryvanveen\CCA\Exceptions\InvalidHueException; |
12
|
|
|
use Barryvanveen\CCA\Exceptions\InvalidNeighborhoodTypeException; |
13
|
|
|
use Phim\Color\RgbColor; |
14
|
|
|
|
15
|
|
|
class Config |
16
|
|
|
{ |
17
|
|
|
protected $config = [ |
18
|
|
|
Options::COLUMNS => 48, |
19
|
|
|
Options::IMAGE_CELL_SIZE => 2, |
20
|
|
|
Options::IMAGE_COLORS => null, |
21
|
|
|
Options::IMAGE_HUE => null, |
22
|
|
|
Options::NEIGHBORHOOD_TYPE => NeighborhoodOptions::NEIGHBORHOOD_TYPE_MOORE, |
23
|
|
|
Options::NEIGHBORHOOD_SIZE => 1, |
24
|
|
|
Options::ROWS => 48, |
25
|
|
|
Options::SEED => null, |
26
|
|
|
Options::STATES => 3, |
27
|
|
|
Options::THRESHOLD => 3, |
28
|
|
|
]; |
29
|
|
|
|
30
|
3 |
|
public function __construct() |
31
|
|
|
{ |
32
|
3 |
|
$this->config[Options::IMAGE_HUE] = $this->makeHue(); |
33
|
|
|
|
34
|
3 |
|
$this->config[Options::SEED] = $this->makeSeed(); |
35
|
3 |
|
} |
36
|
|
|
|
37
|
|
|
protected function makeHue(): int |
38
|
|
|
{ |
39
|
|
|
return rand(0, 360); |
40
|
|
|
} |
41
|
|
|
|
42
|
3 |
|
protected function makeSeed(): int |
43
|
|
|
{ |
44
|
3 |
|
list($usec, $sec) = explode(' ', microtime()); |
45
|
|
|
|
46
|
3 |
|
return intval($sec + $usec * 1000000); |
47
|
|
|
} |
48
|
|
|
|
49
|
3 |
|
public static function createFromPreset(string $preset): self |
50
|
|
|
{ |
51
|
3 |
|
$presetConfig = Presets::getPresetConfig($preset); |
52
|
|
|
|
53
|
3 |
|
$config = new self(); |
54
|
|
|
|
55
|
3 |
|
foreach ($presetConfig as $option => $value) { |
56
|
3 |
|
$config->{$option}($value); |
57
|
|
|
} |
58
|
|
|
|
59
|
3 |
|
return $config; |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Set or get the number of columns in the grid. |
64
|
|
|
* |
65
|
|
|
* @param int number of columns |
66
|
|
|
* |
67
|
|
|
* @return int |
68
|
|
|
*/ |
69
|
3 |
|
public function columns($columns = null): int |
70
|
|
|
{ |
71
|
3 |
|
if (isset($columns)) { |
72
|
3 |
|
$this->config[Options::COLUMNS] = (int) $columns; |
73
|
|
|
} |
74
|
|
|
|
75
|
3 |
|
return $this->config[Options::COLUMNS]; |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* Set or get the size of each cell in the image that is created. |
80
|
|
|
* |
81
|
|
|
* @param int $cellsize |
82
|
|
|
* |
83
|
|
|
* @return int |
84
|
|
|
*/ |
85
|
3 |
|
public function imageCellSize($cellsize = null): int |
86
|
|
|
{ |
87
|
3 |
|
if (isset($cellsize)) { |
88
|
3 |
|
$this->config[Options::IMAGE_CELL_SIZE] = (int) $cellsize; |
89
|
|
|
} |
90
|
|
|
|
91
|
3 |
|
return $this->config[Options::IMAGE_CELL_SIZE]; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Set or get the colors that are used when generating images from states. |
96
|
|
|
* |
97
|
|
|
* @param RgbColor[] $colors |
98
|
|
|
* |
99
|
|
|
* @return RgbColor[]|null |
100
|
|
|
* |
101
|
|
|
* @throws InvalidColorException |
102
|
|
|
*/ |
103
|
|
View Code Duplication |
public function imageColors($colors = null) |
|
|
|
|
104
|
|
|
{ |
105
|
|
|
if (isset($colors) && $this->colorsAreValid($colors)) { |
106
|
|
|
$this->config[Options::IMAGE_COLORS] = $colors; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
return $this->config[Options::IMAGE_COLORS]; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
protected function colorsAreValid($colors): bool |
113
|
|
|
{ |
114
|
|
|
if (!is_array($colors)) { |
115
|
|
|
$colors = [$colors]; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
foreach ($colors as $color) { |
119
|
|
|
if (!$color instanceof RgbColor) { |
120
|
|
|
throw new InvalidColorException(); |
121
|
|
|
} |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
return true; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* Set or get the hue (color) that is used when generating images from states. |
129
|
|
|
* |
130
|
|
|
* @param int $hue |
131
|
|
|
* |
132
|
|
|
* @return int |
133
|
|
|
* |
134
|
|
|
* @throws InvalidHueException |
135
|
|
|
*/ |
136
|
|
View Code Duplication |
public function imageHue($hue = null): int |
|
|
|
|
137
|
|
|
{ |
138
|
|
|
if (isset($hue) && $this->isValidHue($hue)) { |
139
|
|
|
$this->config[Options::IMAGE_HUE] = (int) $hue; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
return $this->config[Options::IMAGE_HUE]; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
protected function isValidHue($hue): bool |
146
|
|
|
{ |
147
|
|
|
if (!is_int($hue)) { |
148
|
|
|
throw new InvalidHueException("Hue is not an integer."); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
if ($hue < 0 || $hue > 360) { |
152
|
|
|
throw new InvalidHueException("Hue should be an integer between 0 and 360."); |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
return true; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* Set or get the size (eg range) of the neighborhood. |
160
|
|
|
* |
161
|
|
|
* @param int $neighborhoodSize size of neighborhood |
162
|
|
|
* |
163
|
|
|
* @return int |
164
|
|
|
*/ |
165
|
3 |
|
public function neighborhoodSize($neighborhoodSize = null): int |
166
|
|
|
{ |
167
|
3 |
|
if (isset($neighborhoodSize)) { |
168
|
3 |
|
$this->config[Options::NEIGHBORHOOD_SIZE] = (int) $neighborhoodSize; |
169
|
|
|
} |
170
|
|
|
|
171
|
3 |
|
return $this->config[Options::NEIGHBORHOOD_SIZE]; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* Set or get the neighborhood function, eg Moore or Neumann |
176
|
|
|
* |
177
|
|
|
* @see NeighborhoodOptions::NEIGHBORHOOD_TYPE_MOORE |
178
|
|
|
* @see NeighborhoodOptions::NEIGHBORHOOD_TYPE_NEUMANN |
179
|
|
|
* |
180
|
|
|
* @param string $neighborhoodType |
181
|
|
|
* |
182
|
|
|
* @return string type of neighborhood |
183
|
|
|
* |
184
|
|
|
* @throws \Barryvanveen\CCA\Exceptions\InvalidNeighborhoodTypeException |
185
|
|
|
*/ |
186
|
6 |
|
public function neighborhoodType($neighborhoodType = null): string |
187
|
|
|
{ |
188
|
6 |
|
if (isset($neighborhoodType)) { |
189
|
6 |
|
if (!in_array($neighborhoodType, NeighborhoodOptions::NEIGHBORHOOD_TYPES)) { |
190
|
3 |
|
throw new InvalidNeighborhoodTypeException(); |
191
|
|
|
} |
192
|
|
|
|
193
|
3 |
|
$this->config[Options::NEIGHBORHOOD_TYPE] = (string) $neighborhoodType; |
194
|
|
|
} |
195
|
|
|
|
196
|
3 |
|
return $this->config[Options::NEIGHBORHOOD_TYPE]; |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
/** |
200
|
|
|
* Set or get the number of rows in the grid. |
201
|
|
|
* |
202
|
|
|
* @param int number of rows |
203
|
|
|
* |
204
|
|
|
* @return int |
205
|
|
|
*/ |
206
|
3 |
View Code Duplication |
public function rows($rows = null): int |
|
|
|
|
207
|
|
|
{ |
208
|
3 |
|
if (isset($rows)) { |
209
|
3 |
|
$this->config[Options::ROWS] = (int) $rows; |
210
|
|
|
} |
211
|
|
|
|
212
|
3 |
|
return $this->config[Options::ROWS]; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* Set or get a seed for the random number generator. Use this for reproducable of runs. |
217
|
|
|
* |
218
|
|
|
* @param int $seed |
219
|
|
|
* |
220
|
|
|
* @return int |
221
|
|
|
*/ |
222
|
3 |
View Code Duplication |
public function seed($seed = null): int |
|
|
|
|
223
|
|
|
{ |
224
|
3 |
|
if (isset($seed)) { |
225
|
3 |
|
$this->config[Options::SEED] = (int) $seed; |
226
|
|
|
} |
227
|
|
|
|
228
|
3 |
|
return $this->config[Options::SEED]; |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* Set or get the number of states that are cycled through. |
233
|
|
|
* |
234
|
|
|
* @param int number of states |
235
|
|
|
* |
236
|
|
|
* @return int |
237
|
|
|
*/ |
238
|
3 |
|
public function states($states = null): int |
239
|
|
|
{ |
240
|
3 |
|
if (isset($states)) { |
241
|
3 |
|
$this->config[Options::STATES] = (int) $states; |
242
|
|
|
} |
243
|
|
|
|
244
|
3 |
|
return $this->config[Options::STATES]; |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
/** |
248
|
|
|
* Set or get the threshold of the cells. |
249
|
|
|
* |
250
|
|
|
* @param int threshold |
251
|
|
|
* |
252
|
|
|
* @return int |
253
|
|
|
*/ |
254
|
3 |
View Code Duplication |
public function threshold($threshold = null): int |
|
|
|
|
255
|
|
|
{ |
256
|
3 |
|
if (isset($threshold)) { |
257
|
3 |
|
$this->config[Options::THRESHOLD] = (int) $threshold; |
258
|
|
|
} |
259
|
|
|
|
260
|
3 |
|
return $this->config[Options::THRESHOLD]; |
261
|
|
|
} |
262
|
|
|
|
263
|
3 |
|
public function toArray(): array |
264
|
|
|
{ |
265
|
3 |
|
return $this->config; |
266
|
|
|
} |
267
|
|
|
} |
268
|
|
|
|
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.