1
|
|
|
<?php |
2
|
|
|
/** @formatter:off |
3
|
|
|
* ****************************************************************** |
4
|
|
|
* Created by Marko Kungla on Jun 20, 2016 - 9:01:22 PM |
5
|
|
|
* Contact [email protected] |
6
|
|
|
* @copyright 2016 Marko Kungla - https://github.com/mkungla |
7
|
|
|
* @license The MIT License (MIT) |
8
|
|
|
* |
9
|
|
|
* @category AframeVR |
10
|
|
|
* @package aframe-php |
11
|
|
|
* |
12
|
|
|
* Lang PHP (php version >= 7) |
13
|
|
|
* Encoding UTF-8 |
14
|
|
|
* File Scene.php |
15
|
|
|
* Code format PSR-2 and 12 |
16
|
|
|
* @link https://github.com/mkungla/aframe-php |
17
|
|
|
* @issues https://github.com/mkungla/aframe-php/issues |
18
|
|
|
* ******************************************************************** |
19
|
|
|
* Contributors: |
20
|
|
|
* @author Marko Kungla <[email protected]> |
21
|
|
|
* ******************************************************************** |
22
|
|
|
* Comments: |
23
|
|
|
* @formatter:on */ |
24
|
|
|
namespace AframeVR\Core; |
25
|
|
|
|
26
|
|
|
use \AframeVR\Extras\Primitives; |
27
|
|
|
use \AframeVR\Core\Entity; |
28
|
|
|
use \AframeVR\Core\DOM\AframeDOMDocument; |
29
|
|
|
use \AframeVR\Core\Assets; |
30
|
|
|
use \Closure; |
31
|
|
|
use \AframeVR\Core\Exceptions\BadComponentCallException; |
32
|
|
|
|
33
|
|
|
final class Scene |
34
|
|
|
{ |
35
|
|
|
/* All scenes can use primitives */ |
36
|
|
|
use Primitives; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* Name with what you can retrieve this scene while working with multiple scenes |
40
|
|
|
* |
41
|
|
|
* @var string $name |
42
|
|
|
*/ |
43
|
|
|
private $keyword; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Is scene prepared for rendering |
47
|
|
|
* |
48
|
|
|
* @var bool |
49
|
|
|
*/ |
50
|
|
|
private $prepared; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Assets |
54
|
|
|
* |
55
|
|
|
* @var \AframeVR\Core\Assets |
56
|
|
|
*/ |
57
|
|
|
protected $assets; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Aframe Document Object Model |
61
|
|
|
* |
62
|
|
|
* @var \AframeVR\Core\DOM\AframeDOMDocument |
63
|
|
|
*/ |
64
|
|
|
protected $aframeDomObj; |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* A-Frame scene entities |
68
|
|
|
* |
69
|
|
|
* @var array $entities |
70
|
|
|
*/ |
71
|
|
|
protected $entities = array(); |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Scene components |
75
|
|
|
* |
76
|
|
|
* @var array $components |
77
|
|
|
*/ |
78
|
|
|
protected $components = array(); |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Scene constructor |
82
|
|
|
* |
83
|
|
|
* @param string $keyword |
84
|
|
|
* @param Config $config |
85
|
|
|
*/ |
86
|
98 |
|
public function __construct(string $keyword, Config $config) |
87
|
|
|
{ |
88
|
98 |
|
$this->keyword = $keyword; |
89
|
98 |
|
$this->aframeDomObj = new AframeDOMDocument($config); |
90
|
|
|
/* Initialize assests manager */ |
91
|
98 |
|
$this->asset(); |
92
|
98 |
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Aframe Document Object Model |
96
|
|
|
* |
97
|
|
|
* @api |
98
|
|
|
* |
99
|
|
|
* @return \AframeVR\Core\DOM\AframeDOMDocument |
100
|
|
|
*/ |
101
|
8 |
|
public function dom() |
102
|
|
|
{ |
103
|
8 |
|
return $this->aframeDomObj; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Entity |
108
|
|
|
* |
109
|
|
|
* @api |
110
|
|
|
* |
111
|
|
|
* @param string $id |
112
|
|
|
* @return \AframeVR\Core\Entity |
113
|
|
|
*/ |
114
|
47 |
|
public function entity(string $id = 'untitled'): Entity |
115
|
|
|
{ |
116
|
47 |
|
return $this->entities[$id] ?? $this->entities[$id] = new Entity($id); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Assets |
121
|
|
|
* |
122
|
|
|
* @api |
123
|
|
|
* |
124
|
|
|
* @return \AframeVR\Core\Assets |
125
|
|
|
*/ |
126
|
98 |
|
public function asset(): Assets |
127
|
|
|
{ |
128
|
98 |
|
return $this->assets ?? $this->assets = new Assets(); |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Render the A-Frame scene and return the HTML |
133
|
|
|
* |
134
|
|
|
* @api |
135
|
|
|
* |
136
|
|
|
* @param bool $only_scene |
137
|
|
|
* @return string |
138
|
|
|
*/ |
139
|
9 |
|
public function save($only_scene = false, string $file = null): string |
140
|
|
|
{ |
141
|
9 |
|
$this->prepare(); |
142
|
9 |
|
$html = ! $only_scene ? $this->aframeDomObj->render() : $this->aframeDomObj->renderSceneOnly(); |
143
|
9 |
|
if (! empty($file) && is_writable(dirname($file))) { |
144
|
1 |
|
file_put_contents($file, $html); |
145
|
|
|
} |
146
|
|
|
|
147
|
9 |
|
return $html; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* Render the A-Frame scene and passthru HTML |
152
|
|
|
* |
153
|
|
|
* @api |
154
|
|
|
* |
155
|
|
|
* @param bool $only_scene |
156
|
|
|
* @return void |
157
|
|
|
*/ |
158
|
1 |
|
public function render($only_scene = false) |
159
|
|
|
{ |
160
|
1 |
|
print $this->save($only_scene); |
161
|
1 |
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* Alias of AframeDOMDocument::setTitle(string) |
165
|
|
|
* |
166
|
|
|
* Set <title> tag |
167
|
|
|
* $this->dom()->setTitle(string); |
168
|
|
|
* |
169
|
|
|
* @api |
170
|
|
|
* |
171
|
|
|
* @param string $title |
172
|
|
|
*/ |
173
|
7 |
|
public function title(string $title) |
174
|
|
|
{ |
175
|
7 |
|
$this->dom()->setTitle($title); |
176
|
7 |
|
} |
177
|
|
|
|
178
|
|
|
/** |
179
|
|
|
* Alias of AframeDOMDocument::setDescription(string) |
180
|
|
|
* |
181
|
|
|
* Set <meta name="description"> tag |
182
|
|
|
* $this->dom()->setDescription(string); |
183
|
|
|
* |
184
|
|
|
* @api |
185
|
|
|
* |
186
|
|
|
* @param string $description |
187
|
|
|
*/ |
188
|
7 |
|
public function description(string $description) |
189
|
|
|
{ |
190
|
7 |
|
$this->dom()->setDescription($description); |
191
|
7 |
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* Get scenes keyword |
195
|
|
|
* |
196
|
|
|
* @return string |
197
|
|
|
*/ |
198
|
1 |
|
public function getKeyword() |
199
|
|
|
{ |
200
|
1 |
|
return $this->keyword; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* Load component for this entity |
205
|
|
|
* |
206
|
|
|
* @param string $component_name |
207
|
|
|
* @throws \AframeVR\Core\Exceptions\BadComponentCallException |
208
|
|
|
* @return object|null |
209
|
|
|
*/ |
210
|
2 |
View Code Duplication |
public function component(string $component_name) |
|
|
|
|
211
|
|
|
{ |
212
|
2 |
|
if (! array_key_exists($component_name, $this->components)) { |
213
|
2 |
|
$component = sprintf('\AframeVR\Core\Components\ascene\%s\%sComponent', ucfirst($component_name), |
214
|
|
|
ucfirst($component_name)); |
215
|
2 |
|
if (class_exists($component)) { |
216
|
1 |
|
$this->components[$component_name] = new $component(); |
217
|
|
|
} else { |
218
|
1 |
|
throw new BadComponentCallException($component_name); |
219
|
|
|
} |
220
|
|
|
} |
221
|
|
|
|
222
|
1 |
|
return $this->components[$component_name] ?? null; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* Handle scene components |
227
|
|
|
* |
228
|
|
|
* Since we might need to customize these to have |
229
|
|
|
* custom components loaded as $this->methosd aswell therefore |
230
|
|
|
* we have these placeholder magic methods here |
231
|
|
|
* |
232
|
|
|
* @param string $component_name |
233
|
|
|
* @param array $args |
234
|
|
|
*/ |
235
|
2 |
View Code Duplication |
public function __call(string $component_name, array $args) |
|
|
|
|
236
|
|
|
{ |
237
|
2 |
|
if (! method_exists($this, $component_name)) { |
238
|
2 |
|
$this->{$component_name} = Closure::bind( |
239
|
2 |
|
function () use ($component_name) { |
240
|
2 |
|
return $this->component($component_name); |
241
|
2 |
|
}, $this, get_class()); |
242
|
|
|
} |
243
|
|
|
|
244
|
2 |
|
return call_user_func($this->{$component_name}, $args); |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
|
248
|
|
|
/** |
249
|
|
|
* Add everyting to DOM |
250
|
|
|
* |
251
|
|
|
* @return void |
252
|
|
|
*/ |
253
|
9 |
|
protected function prepare() |
254
|
|
|
{ |
255
|
9 |
|
if ($this->prepared) |
256
|
1 |
|
return; |
257
|
|
|
|
258
|
|
|
/* Append all assets */ |
259
|
9 |
|
$assets = $this->assets->getAssets(); |
260
|
9 |
|
(! $assets) ?: $this->aframeDomObj->appendAssets($assets); |
261
|
|
|
|
262
|
|
|
/* Append all primitives */ |
263
|
9 |
|
$this->preparePrimitives(); |
264
|
|
|
|
265
|
|
|
/* Append all entities */ |
266
|
9 |
|
$this->aframeDomObj->appendEntities($this->entities); |
267
|
9 |
|
$this->aframeDomObj->appendSceneComponents($this->components); |
268
|
9 |
|
$this->prepared = true; |
269
|
9 |
|
} |
270
|
|
|
} |
271
|
|
|
|
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.