Completed
Push — master ( f87c77...be4ea7 )
by Marko
02:11
created

Scene::description()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
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;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
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 2
    public function dom()
102
    {
103 2
        return $this->aframeDomObj;
104
    }
105
106
    /**
107
     * Entity
108
     *
109
     * @api
110
     *
111
     * @param string $id            
112
     * @return \AframeVR\Core\Entity
113
     */
114 51
    public function entity(string $id = 'untitled'): Entity
115
    {
116 51
        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 19
    public function save($only_scene = false, string $file = null): string
140
    {
141 19
        $this->prepare();
142 19
        $html = ! $only_scene ? $this->aframeDomObj->render() : $this->aframeDomObj->renderSceneOnly();
143 19
        if (! empty($file) && is_writable(dirname($file))) {
144 1
            file_put_contents($file, $html);
145
        }
146
        
147 19
        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 1
    public function title(string $title)
174
    {
175 1
        $this->dom()->setTitle($title);
176 1
    }
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 1
    public function description(string $description)
189
    {
190 1
        $this->dom()->setDescription($description);
191 1
    }
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
    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
     * Call
227
     *
228
     * @param string $method            
229
     * @param array $args            
230
     * @throws BadShaderCallException
231
     * @return Entity|\AframeVR\Interfaces\ComponentInterface
232
     */
233 28
    public function __call(string $method, array $args)
234
    {
235 28
        $id = $args[0] ?? 0;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
236 28
        $primitive = sprintf('\AframeVR\Extras\Primitives\%s', ucfirst($method));
237
        
238 28
        if (class_exists($primitive)) {
239 26
            return $this->childrens[$id] ?? (is_int($id) ? $this->childrens[array_push($this->childrens, 
240 26
                new $primitive($id)) - 1] : $this->childrens[$id] = new $primitive($id));
241
        } else {
242 2
            return $this->callComponent($method, $args);
243
        }
244
    }
245
246
    /**
247
     * Handle entity components
248
     *
249
     * Since we might need to customize these to have
250
     * custom components loaded as $this->methosd aswell therefore
251
     * we have these placeholder magic methods here
252
     *
253
     * @param string $component_name            
254
     * @param array $args            
255
     */
256 2
    public function callComponent(string $component_name, array $args)
257
    {
258 2
        if (! method_exists($this, $component_name)) {
259 2
            $this->{$component_name} = Closure::bind(
260 2
                function () use ($component_name) {
261 2
                    return $this->component($component_name);
262 2
                }, $this, get_class());
263
        }
264
        
265 2
        return call_user_func($this->{$component_name}, $args);
266
    }
267
268
    /**
269
     * Add everyting to DOM
270
     *
271
     * @return void
272
     */
273 19
    protected function prepare()
274
    {
275 19
        if ($this->prepared)
276 1
            return;
277
            
278
            /* Append all assets */
279 19
        $assets = $this->assets->getAssets();
280 19
        (! $assets) ?: $this->aframeDomObj->appendAssets($assets);
281
        /* Append all primitives */
282 19
        $this->preparePrimitives();
283
        
284
        /* Append all entities */
285 19
        $this->aframeDomObj->appendEntities($this->entities);
286 19
        $this->aframeDomObj->appendSceneComponents($this->components);
287 19
        $this->prepared = true;
288 19
    }
289
}
290