Completed
Push — master ( 028450...7dbb7d )
by Marko
03:14
created

Scene::title()   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 97
    public function __construct(string $keyword, Config $config)
87
    {
88 97
        $this->keyword      = $keyword;
89 97
        $this->aframeDomObj = new AframeDOMDocument($config);
90
        /* Initialize assests manager */
91 97
        $this->asset();
92 97
    }
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 97
    public function asset(): Assets
127
    {
128 97
        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 View Code Duplication
    public function component(string $component_name)
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...
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
    /**
227
     * Call
228
     *
229
     * @param string $method
230
     * @param array $args
231
     * @throws BadShaderCallException
232
     * @return Entity|\AframeVR\Interfaces\ComponentInterface
233
     */
234 27
    public function __call(string $method, array $args)
235
    {
236 27
        $id        = $args[0] ?? 'untitled';
237 27
        $primitive = sprintf('\AframeVR\Extras\Primitives\%s',  ucfirst($method));
238
    
239 27
        if (class_exists($primitive)) {
240 25
            return $this->childrens[$id] ?? $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 View Code Duplication
    public function callComponent(string $component_name, array $args)
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...
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